]> www.fi.muni.cz Git - evince.git/blob - backend/pdf/ev-poppler.cc
Allow printing multiple pages per sheet. Fixes bug #395573.
[evince.git] / backend / pdf / ev-poppler.cc
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
2 /* pdfdocument.h: Implementation of EvDocument for PDF
3  * Copyright (C) 2004, Red Hat, Inc.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 #include "config.h"
21
22 #ifdef HAVE_POPPLER_FORM_FIELD_BUTTON_GET_BUTTON_TYPE
23 #define HAVE_FORMS
24 #endif
25
26 #include <math.h>
27 #include <string.h>
28 #include <gtk/gtk.h>
29 #include <poppler.h>
30 #include <poppler-document.h>
31 #include <poppler-page.h>
32 #ifdef HAVE_CAIRO_PDF
33 #include <cairo-pdf.h>
34 #endif
35 #ifdef HAVE_CAIRO_PS
36 #include <cairo-ps.h>
37 #endif
38 #include <glib/gi18n.h>
39
40 #include "ev-poppler.h"
41 #include "ev-file-exporter.h"
42 #include "ev-document-find.h"
43 #include "ev-document-misc.h"
44 #include "ev-document-links.h"
45 #include "ev-document-images.h"
46 #include "ev-document-fonts.h"
47 #include "ev-document-security.h"
48 #include "ev-document-thumbnails.h"
49 #include "ev-document-transition.h"
50 #include "ev-document-forms.h"
51 #include "ev-selection.h"
52 #include "ev-attachment.h"
53 #include "ev-image.h"
54
55 #if defined (HAVE_CAIRO_PDF) || defined (HAVE_CAIRO_PS)
56 #define HAVE_CAIRO_PRINT
57 #endif
58
59 typedef struct {
60         PdfDocument *document;
61         char *text;
62         GList **pages;
63         guint idle;
64         int start_page;
65         int search_page;
66 } PdfDocumentSearch;
67
68 typedef struct {
69         EvFileExporterFormat format;
70         PopplerPSFile *ps_file;
71
72         /* Pages per sheet */
73         gint pages_per_sheet;
74         gint pages_printed;
75         gint pages_x;
76         gint pages_y;
77         gdouble page_width;
78         gdouble page_height;
79         
80 #ifdef HAVE_CAIRO_PRINT
81         cairo_t *cr;
82 #endif
83 } PdfPrintContext;
84
85 struct _PdfDocumentClass
86 {
87         GObjectClass parent_class;
88 };
89
90 struct _PdfDocument
91 {
92         GObject parent_instance;
93
94         PopplerDocument *document;
95         gchar *password;
96
97         PopplerFontInfo *font_info;
98         PopplerFontsIter *fonts_iter;
99         int fonts_scanned_pages;
100
101         PdfDocumentSearch *search;
102         PdfPrintContext *print_ctx;
103 };
104
105 static void pdf_document_document_iface_init            (EvDocumentIface           *iface);
106 static void pdf_document_security_iface_init            (EvDocumentSecurityIface   *iface);
107 static void pdf_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface);
108 static void pdf_document_document_links_iface_init      (EvDocumentLinksIface      *iface);
109 static void pdf_document_document_images_iface_init     (EvDocumentImagesIface     *iface);
110 static void pdf_document_document_forms_iface_init      (EvDocumentFormsIface      *iface);
111 static void pdf_document_document_fonts_iface_init      (EvDocumentFontsIface      *iface);
112 static void pdf_document_find_iface_init                (EvDocumentFindIface       *iface);
113 static void pdf_document_file_exporter_iface_init       (EvFileExporterIface       *iface);
114 static void pdf_selection_iface_init                    (EvSelectionIface          *iface);
115 static void pdf_document_page_transition_iface_init     (EvDocumentTransitionIface *iface);
116 static void pdf_document_thumbnails_get_dimensions      (EvDocumentThumbnails      *document_thumbnails,
117                                                          EvRenderContext           *rc,
118                                                          gint                      *width,
119                                                          gint                      *height);
120 static int  pdf_document_get_n_pages                    (EvDocument                *document);
121
122 static EvLinkDest *ev_link_dest_from_dest   (PdfDocument       *pdf_document,
123                                              PopplerDest       *dest);
124 static EvLink     *ev_link_from_action      (PdfDocument       *pdf_document,
125                                              PopplerAction     *action);
126 static void        pdf_document_search_free (PdfDocumentSearch *search);
127 static void        pdf_print_context_free   (PdfPrintContext   *ctx);
128
129 G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
130                          {
131                                  G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT,
132                                                         pdf_document_document_iface_init);
133                                  G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_SECURITY,
134                                                         pdf_document_security_iface_init);
135                                  G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS,
136                                                         pdf_document_document_thumbnails_iface_init);
137                                  G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_LINKS,
138                                                         pdf_document_document_links_iface_init);
139                                  G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_IMAGES,
140                                                         pdf_document_document_images_iface_init);
141 #ifdef HAVE_FORMS
142                                  G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FORMS,
143                                                         pdf_document_document_forms_iface_init);
144 #endif /* HAVE_FORMS */
145                                  G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FONTS,
146                                                         pdf_document_document_fonts_iface_init);
147                                  G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FIND,
148                                                         pdf_document_find_iface_init);
149                                  G_IMPLEMENT_INTERFACE (EV_TYPE_FILE_EXPORTER,
150                                                         pdf_document_file_exporter_iface_init);
151                                  G_IMPLEMENT_INTERFACE (EV_TYPE_SELECTION,
152                                                         pdf_selection_iface_init);
153                                  G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_TRANSITION,
154                                                         pdf_document_page_transition_iface_init);
155                          });
156
157
158 static void
159 set_rc_data (PdfDocument     *pdf_document,
160              EvRenderContext *rc)
161 {
162         if (rc->data == NULL) {
163                 rc->data = poppler_document_get_page (pdf_document->document,
164                                                       rc->page);
165                 rc->destroy = g_object_unref;
166         } else {
167                 g_assert (rc->page == poppler_page_get_index (POPPLER_PAGE (rc->data)));
168         }
169 }
170
171 static void
172 pdf_document_search_free (PdfDocumentSearch   *search)
173 {
174         PdfDocument *pdf_document = search->document;
175         int n_pages;
176         int i;
177
178         if (search->idle != 0)
179                 g_source_remove (search->idle);
180
181         n_pages = pdf_document_get_n_pages (EV_DOCUMENT (pdf_document));
182         for (i = 0; i < n_pages; i++) {
183                 g_list_foreach (search->pages[i], (GFunc) g_free, NULL);
184                 g_list_free (search->pages[i]);
185         }
186         g_free (search->pages);
187         
188         g_free (search->text);
189         g_free (search);
190 }
191
192 static void
193 pdf_document_dispose (GObject *object)
194 {
195         PdfDocument *pdf_document = PDF_DOCUMENT(object);
196
197         if (pdf_document->print_ctx) {
198                 pdf_print_context_free (pdf_document->print_ctx);
199                 pdf_document->print_ctx = NULL;
200         }
201         
202         if (pdf_document->search) {
203                 pdf_document_search_free (pdf_document->search);
204                 pdf_document->search = NULL;
205         }
206
207         if (pdf_document->document) {
208                 g_object_unref (pdf_document->document);
209         }
210
211         if (pdf_document->font_info) { 
212                 poppler_font_info_free (pdf_document->font_info);
213         }
214
215         if (pdf_document->fonts_iter) {
216                 poppler_fonts_iter_free (pdf_document->fonts_iter);
217         }
218
219         G_OBJECT_CLASS (pdf_document_parent_class)->dispose (object);
220 }
221
222 static void
223 pdf_document_class_init (PdfDocumentClass *klass)
224 {
225         GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
226
227         g_object_class->dispose = pdf_document_dispose;
228 }
229
230 static void
231 pdf_document_init (PdfDocument *pdf_document)
232 {
233         pdf_document->password = NULL;
234 }
235
236 static void
237 convert_error (GError  *poppler_error,
238                GError **error)
239 {
240         if (poppler_error == NULL)
241                 return;
242
243         if (poppler_error->domain == POPPLER_ERROR) {
244                 /* convert poppler errors into EvDocument errors */
245                 gint code = EV_DOCUMENT_ERROR_INVALID;
246                 if (poppler_error->code == POPPLER_ERROR_INVALID)
247                         code = EV_DOCUMENT_ERROR_INVALID;
248                 else if (poppler_error->code == POPPLER_ERROR_ENCRYPTED)
249                         code = EV_DOCUMENT_ERROR_ENCRYPTED;
250                         
251
252                 g_set_error (error,
253                              EV_DOCUMENT_ERROR,
254                              code,
255                              poppler_error->message,
256                              NULL);
257         } else {
258                 g_propagate_error (error, poppler_error);
259         }
260 }
261
262
263 /* EvDocument */
264 static gboolean
265 pdf_document_save (EvDocument  *document,
266                    const char  *uri,
267                    GError     **error)
268 {
269         gboolean retval;
270         GError *poppler_error = NULL;
271
272         retval = poppler_document_save (PDF_DOCUMENT (document)->document,
273                                         uri,
274                                         &poppler_error);
275         if (! retval)
276                 convert_error (poppler_error, error);
277
278         return retval;
279 }
280
281 static gboolean
282 pdf_document_load (EvDocument   *document,
283                    const char   *uri,
284                    GError      **error)
285 {
286         GError *poppler_error = NULL;
287         PdfDocument *pdf_document = PDF_DOCUMENT (document);
288
289         pdf_document->document =
290                 poppler_document_new_from_file (uri, pdf_document->password, &poppler_error);
291
292         if (pdf_document->document == NULL) {
293                 convert_error (poppler_error, error);
294                 return FALSE;
295         }
296
297         return TRUE;
298 }
299
300 static int
301 pdf_document_get_n_pages (EvDocument *document)
302 {
303         return poppler_document_get_n_pages (PDF_DOCUMENT (document)->document);
304 }
305
306 static void
307 pdf_document_get_page_size (EvDocument   *document,
308                             int           page,
309                             double       *width,
310                             double       *height)
311 {
312         PdfDocument *pdf_document = PDF_DOCUMENT (document);
313         PopplerPage *poppler_page;
314
315         poppler_page = poppler_document_get_page (pdf_document->document, page);
316         poppler_page_get_size (poppler_page, width, height);
317         g_object_unref (poppler_page);
318 }
319
320 static char *
321 pdf_document_get_page_label (EvDocument *document,
322                              int         page)
323 {
324         PopplerPage *poppler_page;
325         char *label = NULL;
326
327         poppler_page = poppler_document_get_page (PDF_DOCUMENT (document)->document,
328                                                   page);
329
330         g_object_get (G_OBJECT (poppler_page),
331                       "label", &label,
332                       NULL);
333         g_object_unref (poppler_page);
334
335         return label;
336 }
337
338 static gboolean
339 pdf_document_has_attachments (EvDocument *document)
340 {
341         PdfDocument *pdf_document;
342
343         pdf_document = PDF_DOCUMENT (document);
344
345         return poppler_document_has_attachments (pdf_document->document);
346 }
347
348 struct SaveToBufferData {
349         gchar *buffer;
350         gsize len, max;
351 };
352
353 static gboolean
354 attachment_save_to_buffer_callback (const gchar  *buf,
355                                     gsize         count,
356                                     gpointer      user_data,
357                                     GError      **error)
358 {
359         struct SaveToBufferData *sdata = (SaveToBufferData *)user_data;
360         gchar *new_buffer;
361         gsize new_max;
362
363         if (sdata->len + count > sdata->max) {
364                 new_max = MAX (sdata->max * 2, sdata->len + count);
365                 new_buffer = (gchar *)g_realloc (sdata->buffer, new_max);
366
367                 sdata->buffer = new_buffer;
368                 sdata->max = new_max;
369         }
370         
371         memcpy (sdata->buffer + sdata->len, buf, count);
372         sdata->len += count;
373         
374         return TRUE;
375 }
376
377 static gboolean
378 attachment_save_to_buffer (PopplerAttachment  *attachment,
379                            gchar             **buffer,
380                            gsize              *buffer_size,
381                            GError            **error)
382 {
383         static const gint initial_max = 1024;
384         struct SaveToBufferData sdata;
385
386         *buffer = NULL;
387         *buffer_size = 0;
388
389         sdata.buffer = (gchar *) g_malloc (initial_max);
390         sdata.max = initial_max;
391         sdata.len = 0;
392
393         if (! poppler_attachment_save_to_callback (attachment,
394                                                    attachment_save_to_buffer_callback,
395                                                    &sdata,
396                                                    error)) {
397                 g_free (sdata.buffer);
398                 return FALSE;
399         }
400
401         *buffer = sdata.buffer;
402         *buffer_size = sdata.len;
403         
404         return TRUE;
405 }
406
407 static GList *
408 pdf_document_get_attachments (EvDocument *document)
409 {
410         PdfDocument *pdf_document;
411         GList *attachments;
412         GList *list;
413         GList *retval = NULL;
414
415         pdf_document = PDF_DOCUMENT (document);
416
417         if (!pdf_document_has_attachments (document))
418                 return NULL;
419
420         attachments = poppler_document_get_attachments (pdf_document->document);
421         
422         for (list = attachments; list; list = list->next) {
423                 PopplerAttachment *attachment;
424                 EvAttachment *ev_attachment;
425                 gchar *data = NULL;
426                 gsize size;
427                 GError *error = NULL;
428
429                 attachment = (PopplerAttachment *) list->data;
430
431                 if (attachment_save_to_buffer (attachment, &data, &size, &error)) {
432                         ev_attachment = ev_attachment_new (attachment->name,
433                                                            attachment->description,
434                                                            attachment->mtime,
435                                                            attachment->ctime,
436                                                            size, data);
437                         
438                         retval = g_list_prepend (retval, ev_attachment);
439                 } else {
440                         if (error) {
441                                 g_warning ("%s", error->message);
442                                 g_error_free (error);
443
444                                 g_free (data);
445                         }
446                 }
447
448                 g_object_unref (attachment);
449         }
450
451         return g_list_reverse (retval);
452 }
453
454 static cairo_surface_t *
455 pdf_document_render (EvDocument      *document,
456                      EvRenderContext *rc)
457 {
458         PdfDocument *pdf_document;
459         cairo_surface_t *surface;
460         double width_points, height_points;
461         gint width, height;
462
463         pdf_document = PDF_DOCUMENT (document);
464
465         set_rc_data (pdf_document, rc);
466
467         poppler_page_get_size (POPPLER_PAGE (rc->data), &width_points, &height_points);
468
469         if (rc->rotation == 90 || rc->rotation == 270) {
470                 width = (int) ((height_points * rc->scale) + 0.5);
471                 height = (int) ((width_points * rc->scale) + 0.5);
472         } else {
473                 width = (int) ((width_points * rc->scale) + 0.5);
474                 height = (int) ((height_points * rc->scale) + 0.5);
475         }
476
477 #ifdef HAVE_POPPLER_PAGE_RENDER
478         cairo_t *cr;
479         
480         surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
481                                               width, height);
482         memset (cairo_image_surface_get_data (surface), 0xff,
483                 cairo_image_surface_get_height (surface) *
484                 cairo_image_surface_get_stride (surface));
485         
486         cr = cairo_create (surface);
487         switch (rc->rotation) {
488                 case 90:
489                         cairo_translate (cr, width, 0);
490                         break;
491                 case 180:
492                         cairo_translate (cr, width, height);
493                         break;
494                 case 270:
495                         cairo_translate (cr, 0, height);
496                         break;
497                 default:
498                         cairo_translate (cr, 0, 0);
499         }
500         cairo_scale (cr, rc->scale, rc->scale);
501         cairo_rotate (cr, rc->rotation * G_PI / 180.0);
502         poppler_page_render (POPPLER_PAGE (rc->data), cr);
503         cairo_destroy (cr);
504 #else /* HAVE_POPPLER_PAGE_RENDER */
505         GdkPixbuf *pixbuf;
506         
507         pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
508                                  FALSE, 8,
509                                  width, height);
510
511         poppler_page_render_to_pixbuf (POPPLER_PAGE (rc->data),
512                                        0, 0,
513                                        width, height,
514                                        rc->scale,
515                                        rc->rotation,
516                                        pixbuf);
517         surface = ev_document_misc_surface_from_pixbuf (pixbuf);
518         g_object_unref (pixbuf);
519 #endif /* HAVE_POPPLER_PAGE_RENDER */
520
521         return surface;
522 }
523
524 /* EvDocumentSecurity */
525
526 static gboolean
527 pdf_document_has_document_security (EvDocumentSecurity *document_security)
528 {
529         /* FIXME: do we really need to have this? */
530         return FALSE;
531 }
532
533 static void
534 pdf_document_set_password (EvDocumentSecurity *document_security,
535                            const char         *password)
536 {
537         PdfDocument *document = PDF_DOCUMENT (document_security);
538
539         if (document->password)
540                 g_free (document->password);
541
542         document->password = g_strdup (password);
543 }
544
545 static gboolean
546 pdf_document_can_get_text (EvDocument *document)
547 {
548         return TRUE;
549 }
550
551 static EvDocumentInfo *
552 pdf_document_get_info (EvDocument *document)
553 {
554         EvDocumentInfo *info;
555         PopplerPageLayout layout;
556         PopplerPageMode mode;
557         PopplerViewerPreferences view_prefs;
558         PopplerPermissions permissions;
559
560         info = g_new0 (EvDocumentInfo, 1);
561
562         info->fields_mask = EV_DOCUMENT_INFO_TITLE |
563                             EV_DOCUMENT_INFO_FORMAT |
564                             EV_DOCUMENT_INFO_AUTHOR |
565                             EV_DOCUMENT_INFO_SUBJECT |
566                             EV_DOCUMENT_INFO_KEYWORDS |
567                             EV_DOCUMENT_INFO_LAYOUT |
568                             EV_DOCUMENT_INFO_START_MODE |
569                             EV_DOCUMENT_INFO_PERMISSIONS |
570                             EV_DOCUMENT_INFO_UI_HINTS |
571                             EV_DOCUMENT_INFO_CREATOR |
572                             EV_DOCUMENT_INFO_PRODUCER |
573                             EV_DOCUMENT_INFO_CREATION_DATE |
574                             EV_DOCUMENT_INFO_MOD_DATE |
575                             EV_DOCUMENT_INFO_LINEARIZED |
576                             EV_DOCUMENT_INFO_N_PAGES |
577                             EV_DOCUMENT_INFO_SECURITY | 
578                             EV_DOCUMENT_INFO_PAPER_SIZE;
579
580         g_object_get (PDF_DOCUMENT (document)->document,
581                       "title", &(info->title),
582                       "format", &(info->format),
583                       "author", &(info->author),
584                       "subject", &(info->subject),
585                       "keywords", &(info->keywords),
586                       "page-mode", &mode,
587                       "page-layout", &layout,
588                       "viewer-preferences", &view_prefs,
589                       "permissions", &permissions,
590                       "creator", &(info->creator),
591                       "producer", &(info->producer),
592                       "creation-date", &(info->creation_date),
593                       "mod-date", &(info->modified_date),
594                       "linearized", &(info->linearized),
595                       NULL);
596
597         pdf_document_get_page_size(document, 0,
598                                    &(info->paper_width),
599                                    &(info->paper_height));
600
601         // Convert to mm.
602         info->paper_width = info->paper_width / 72.0f * 25.4f;
603         info->paper_height = info->paper_height / 72.0f * 25.4f;
604
605         switch (layout) {
606                 case POPPLER_PAGE_LAYOUT_SINGLE_PAGE:
607                         info->layout = EV_DOCUMENT_LAYOUT_SINGLE_PAGE;
608                         break;
609                 case POPPLER_PAGE_LAYOUT_ONE_COLUMN:
610                         info->layout = EV_DOCUMENT_LAYOUT_ONE_COLUMN;
611                         break;
612                 case POPPLER_PAGE_LAYOUT_TWO_COLUMN_LEFT:
613                         info->layout = EV_DOCUMENT_LAYOUT_TWO_COLUMN_LEFT;
614                         break;
615                 case POPPLER_PAGE_LAYOUT_TWO_COLUMN_RIGHT:
616                         info->layout = EV_DOCUMENT_LAYOUT_TWO_COLUMN_RIGHT;
617                 case POPPLER_PAGE_LAYOUT_TWO_PAGE_LEFT:
618                         info->layout = EV_DOCUMENT_LAYOUT_TWO_PAGE_LEFT;
619                         break;
620                 case POPPLER_PAGE_LAYOUT_TWO_PAGE_RIGHT:
621                         info->layout = EV_DOCUMENT_LAYOUT_TWO_PAGE_RIGHT;
622                         break;
623                 default:
624                         break;
625         }
626
627         switch (mode) {
628                 case POPPLER_PAGE_MODE_NONE:
629                         info->mode = EV_DOCUMENT_MODE_NONE;
630                         break;
631                 case POPPLER_PAGE_MODE_USE_THUMBS:
632                         info->mode = EV_DOCUMENT_MODE_USE_THUMBS;
633                         break;
634                 case POPPLER_PAGE_MODE_USE_OC:
635                         info->mode = EV_DOCUMENT_MODE_USE_OC;
636                         break;
637                 case POPPLER_PAGE_MODE_FULL_SCREEN:
638                         info->mode = EV_DOCUMENT_MODE_FULL_SCREEN;
639                         break;
640                 case POPPLER_PAGE_MODE_USE_ATTACHMENTS:
641                         info->mode = EV_DOCUMENT_MODE_USE_ATTACHMENTS;
642                 default:
643                         break;
644         }
645
646         info->ui_hints = 0;
647         if (view_prefs & POPPLER_VIEWER_PREFERENCES_HIDE_TOOLBAR) {
648                 info->ui_hints |= EV_DOCUMENT_UI_HINT_HIDE_TOOLBAR;
649         }
650         if (view_prefs & POPPLER_VIEWER_PREFERENCES_HIDE_MENUBAR) {
651                 info->ui_hints |= EV_DOCUMENT_UI_HINT_HIDE_MENUBAR;
652         }
653         if (view_prefs & POPPLER_VIEWER_PREFERENCES_HIDE_WINDOWUI) {
654                 info->ui_hints |= EV_DOCUMENT_UI_HINT_HIDE_WINDOWUI;
655         }
656         if (view_prefs & POPPLER_VIEWER_PREFERENCES_FIT_WINDOW) {
657                 info->ui_hints |= EV_DOCUMENT_UI_HINT_FIT_WINDOW;
658         }
659         if (view_prefs & POPPLER_VIEWER_PREFERENCES_CENTER_WINDOW) {
660                 info->ui_hints |= EV_DOCUMENT_UI_HINT_CENTER_WINDOW;
661         }
662         if (view_prefs & POPPLER_VIEWER_PREFERENCES_DISPLAY_DOC_TITLE) {
663                 info->ui_hints |= EV_DOCUMENT_UI_HINT_DISPLAY_DOC_TITLE;
664         }
665         if (view_prefs & POPPLER_VIEWER_PREFERENCES_DIRECTION_RTL) {
666                 info->ui_hints |=  EV_DOCUMENT_UI_HINT_DIRECTION_RTL;
667         }
668
669         info->permissions = 0;
670         if (permissions & POPPLER_PERMISSIONS_OK_TO_PRINT) {
671                 info->permissions |= EV_DOCUMENT_PERMISSIONS_OK_TO_PRINT;
672         }
673         if (permissions & POPPLER_PERMISSIONS_OK_TO_MODIFY) {
674                 info->permissions |= EV_DOCUMENT_PERMISSIONS_OK_TO_MODIFY;
675         }
676         if (permissions & POPPLER_PERMISSIONS_OK_TO_COPY) {
677                 info->permissions |= EV_DOCUMENT_PERMISSIONS_OK_TO_COPY;
678         }
679         if (permissions & POPPLER_PERMISSIONS_OK_TO_ADD_NOTES) {
680                 info->permissions |= EV_DOCUMENT_PERMISSIONS_OK_TO_ADD_NOTES;
681         }
682
683         info->n_pages = ev_document_get_n_pages (document);
684
685         if (ev_document_security_has_document_security (EV_DOCUMENT_SECURITY (document))) {
686                 /* translators: this is the document security state */
687                 info->security = g_strdup (_("Yes"));
688         } else {
689                 /* translators: this is the document security state */
690                 info->security = g_strdup (_("No"));
691         }
692
693         return info;
694 }
695
696 static char *
697 pdf_document_get_text (EvDocument *document, int page, EvRectangle *rect)
698 {
699         PdfDocument *pdf_document = PDF_DOCUMENT (document);
700         PopplerPage *poppler_page;
701         PopplerRectangle r;
702         double height;
703         char *text;
704         
705         poppler_page = poppler_document_get_page (pdf_document->document, page);
706         g_return_val_if_fail (poppler_page != NULL, NULL);
707
708         poppler_page_get_size (poppler_page, NULL, &height);
709         r.x1 = rect->x1;
710         r.y1 = height - rect->y2;
711         r.x2 = rect->x2;
712         r.y2 = height - rect->y1;
713
714         text = poppler_page_get_text (poppler_page, &r);
715
716         g_object_unref (poppler_page);
717
718         return text;
719 }
720
721 static void
722 pdf_document_document_iface_init (EvDocumentIface *iface)
723 {
724         iface->save = pdf_document_save;
725         iface->load = pdf_document_load;
726         iface->get_n_pages = pdf_document_get_n_pages;
727         iface->get_page_size = pdf_document_get_page_size;
728         iface->get_page_label = pdf_document_get_page_label;
729         iface->has_attachments = pdf_document_has_attachments;
730         iface->get_attachments = pdf_document_get_attachments;
731         iface->render = pdf_document_render;
732         iface->get_text = pdf_document_get_text;
733         iface->can_get_text = pdf_document_can_get_text;
734         iface->get_info = pdf_document_get_info;
735 };
736
737 static void
738 pdf_document_security_iface_init (EvDocumentSecurityIface *iface)
739 {
740         iface->has_document_security = pdf_document_has_document_security;
741         iface->set_password = pdf_document_set_password;
742 }
743
744 static gdouble
745 pdf_document_fonts_get_progress (EvDocumentFonts *document_fonts)
746 {
747         PdfDocument *pdf_document = PDF_DOCUMENT (document_fonts);
748         int n_pages;
749
750         n_pages = pdf_document_get_n_pages (EV_DOCUMENT (pdf_document));
751
752         return (double)pdf_document->fonts_scanned_pages / (double)n_pages;
753 }
754
755 static gboolean
756 pdf_document_fonts_scan (EvDocumentFonts *document_fonts,
757                          int              n_pages)
758 {
759         PdfDocument *pdf_document = PDF_DOCUMENT (document_fonts);
760         gboolean result;
761
762         g_return_val_if_fail (PDF_IS_DOCUMENT (document_fonts), FALSE);
763
764         if (pdf_document->font_info == NULL) { 
765                 pdf_document->font_info = poppler_font_info_new (pdf_document->document);
766         }
767
768         if (pdf_document->fonts_iter) {
769                 poppler_fonts_iter_free (pdf_document->fonts_iter);
770         }
771
772         pdf_document->fonts_scanned_pages += n_pages;
773
774         result = poppler_font_info_scan (pdf_document->font_info, n_pages,
775                                          &pdf_document->fonts_iter);
776         if (!result) {
777                 pdf_document->fonts_scanned_pages = 0;
778                 poppler_font_info_free (pdf_document->font_info);
779                 pdf_document->font_info = NULL; 
780         }
781
782         return result;
783 }
784
785 static const char *
786 font_type_to_string (PopplerFontType type)
787 {
788         switch (type) {
789                 case POPPLER_FONT_TYPE_TYPE1:
790                         return _("Type 1");
791                 case POPPLER_FONT_TYPE_TYPE1C:
792                         return _("Type 1C");
793                 case POPPLER_FONT_TYPE_TYPE3:
794                         return _("Type 3");
795                 case POPPLER_FONT_TYPE_TRUETYPE:
796                         return _("TrueType");
797                 case POPPLER_FONT_TYPE_CID_TYPE0:
798                         return _("Type 1 (CID)");
799                 case POPPLER_FONT_TYPE_CID_TYPE0C:
800                         return _("Type 1C (CID)");
801                 case POPPLER_FONT_TYPE_CID_TYPE2:
802                         return _("TrueType (CID)");
803                 default:
804                         return _("Unknown font type");
805         }
806 }
807
808 static void
809 pdf_document_fonts_fill_model (EvDocumentFonts *document_fonts,
810                                GtkTreeModel    *model)
811 {
812         PdfDocument *pdf_document = PDF_DOCUMENT (document_fonts);
813         PopplerFontsIter *iter = pdf_document->fonts_iter;
814
815         g_return_if_fail (PDF_IS_DOCUMENT (document_fonts));
816
817         if (!iter)
818                 return;
819
820         do {
821                 GtkTreeIter list_iter;
822                 const char *name;
823                 const char *type;
824                 const char *embedded;
825                 char *details;
826                 
827                 name = poppler_fonts_iter_get_name (iter);
828
829                 if (name == NULL) {
830                         name = _("No name");
831                 }
832
833                 type = font_type_to_string (
834                         poppler_fonts_iter_get_font_type (iter));
835
836                 if (poppler_fonts_iter_is_embedded (iter)) {
837                         if (poppler_fonts_iter_is_subset (iter))
838                                 embedded = _("Embedded subset");
839                         else
840                                 embedded = _("Embedded");
841                 } else {
842                         embedded = _("Not embedded");
843                 }
844
845                 details = g_markup_printf_escaped ("%s\n%s", type, embedded);
846
847                 gtk_list_store_append (GTK_LIST_STORE (model), &list_iter);
848                 gtk_list_store_set (GTK_LIST_STORE (model), &list_iter,
849                                     EV_DOCUMENT_FONTS_COLUMN_NAME, name,
850                                     EV_DOCUMENT_FONTS_COLUMN_DETAILS, details,
851                                     -1);
852
853                 g_free (details);
854         } while (poppler_fonts_iter_next (iter));
855 }
856
857 static void
858 pdf_document_document_fonts_iface_init (EvDocumentFontsIface *iface)
859 {
860         iface->fill_model = pdf_document_fonts_fill_model;
861         iface->scan = pdf_document_fonts_scan;
862         iface->get_progress = pdf_document_fonts_get_progress;
863 }
864
865 static gboolean
866 pdf_document_links_has_document_links (EvDocumentLinks *document_links)
867 {
868         PdfDocument *pdf_document = PDF_DOCUMENT (document_links);
869         PopplerIndexIter *iter;
870
871         g_return_val_if_fail (PDF_IS_DOCUMENT (document_links), FALSE);
872
873         iter = poppler_index_iter_new (pdf_document->document);
874         if (iter == NULL)
875                 return FALSE;
876         poppler_index_iter_free (iter);
877
878         return TRUE;
879 }
880
881 static EvLinkDest *
882 ev_link_dest_from_dest (PdfDocument *pdf_document,
883                         PopplerDest *dest)
884 {
885         EvLinkDest *ev_dest = NULL;
886         const char *unimplemented_dest = NULL;
887
888         g_assert (dest != NULL);
889
890         switch (dest->type) {
891                 case POPPLER_DEST_XYZ: {
892                         PopplerPage *poppler_page;
893                         double height;
894
895                         poppler_page = poppler_document_get_page (pdf_document->document,
896                                                                   MAX (0, dest->page_num - 1));
897                         poppler_page_get_size (poppler_page, NULL, &height);
898                         ev_dest = ev_link_dest_new_xyz (dest->page_num - 1,
899                                                         dest->left,
900                                                         height - dest->top,
901                                                         dest->zoom);
902                         g_object_unref (poppler_page);
903                 }
904                         break;
905                 case POPPLER_DEST_FIT:
906                         ev_dest = ev_link_dest_new_fit (dest->page_num - 1);
907                         break;
908                 case POPPLER_DEST_FITH: {
909                         PopplerPage *poppler_page;
910                         double height;
911
912                         poppler_page = poppler_document_get_page (pdf_document->document,
913                                                                   MAX (0, dest->page_num - 1));
914                         poppler_page_get_size (poppler_page, NULL, &height);
915                         ev_dest = ev_link_dest_new_fith (dest->page_num - 1,
916                                                          height - dest->top);
917                         g_object_unref (poppler_page);
918                 }
919                         break;
920                 case POPPLER_DEST_FITV:
921                         ev_dest = ev_link_dest_new_fitv (dest->page_num - 1,
922                                                          dest->left);
923                         break;
924                 case POPPLER_DEST_FITR: {
925                         PopplerPage *poppler_page;
926                         double height;
927
928                         poppler_page = poppler_document_get_page (pdf_document->document,
929                                                                   MAX (0, dest->page_num - 1));
930                         poppler_page_get_size (poppler_page, NULL, &height);
931                         ev_dest = ev_link_dest_new_fitr (dest->page_num - 1,
932                                                          dest->left,
933                                                          height - dest->bottom,
934                                                          dest->right,
935                                                          height - dest->top);
936                         g_object_unref (poppler_page);
937                 }
938                         break;
939                 case POPPLER_DEST_FITB:
940                         unimplemented_dest = "POPPLER_DEST_FITB";
941                         break;
942                 case POPPLER_DEST_FITBH:
943                         unimplemented_dest = "POPPLER_DEST_FITBH";
944                         break;
945                 case POPPLER_DEST_FITBV:
946                         unimplemented_dest = "POPPLER_DEST_FITBV";
947                         break;
948                 case POPPLER_DEST_NAMED:
949                         ev_dest = ev_link_dest_new_named (dest->named_dest);
950                         break;
951                 case POPPLER_DEST_UNKNOWN:
952                         unimplemented_dest = "POPPLER_DEST_UNKNOWN";
953                         break;
954         }
955
956         if (unimplemented_dest) {
957                 g_warning ("Unimplemented named action: %s, please post a "
958                            "bug report in Evince bugzilla "
959                            "(http://bugzilla.gnome.org) with a testcase.",
960                            unimplemented_dest);
961         }
962
963         if (!ev_dest)
964                 ev_dest = ev_link_dest_new_page (dest->page_num - 1);
965         
966         return ev_dest;
967 }
968
969 static EvLink *
970 ev_link_from_action (PdfDocument   *pdf_document,
971                      PopplerAction *action)
972 {
973         EvLink       *link = NULL;
974         EvLinkAction *ev_action = NULL;
975         const char   *unimplemented_action = NULL;
976
977         switch (action->type) {
978                 case POPPLER_ACTION_GOTO_DEST: {
979                         EvLinkDest *dest;
980                         
981                         dest = ev_link_dest_from_dest (pdf_document, action->goto_dest.dest);
982                         ev_action = ev_link_action_new_dest (dest);
983                 }
984                         break;
985                 case POPPLER_ACTION_GOTO_REMOTE: {
986                         EvLinkDest *dest;
987                         
988                         dest = ev_link_dest_from_dest (pdf_document, action->goto_remote.dest);
989                         ev_action = ev_link_action_new_remote (dest, 
990                                                                action->goto_remote.file_name);
991                         
992                 }
993                         break;
994                 case POPPLER_ACTION_LAUNCH:
995                         ev_action = ev_link_action_new_launch (action->launch.file_name,
996                                                                action->launch.params);
997                         break;
998                 case POPPLER_ACTION_URI:
999                         ev_action = ev_link_action_new_external_uri (action->uri.uri);
1000                         break;
1001                 case POPPLER_ACTION_NAMED:
1002                         ev_action = ev_link_action_new_named (action->named.named_dest);
1003                         break;
1004                 case POPPLER_ACTION_MOVIE:
1005                         unimplemented_action = "POPPLER_ACTION_MOVIE";
1006                         break;
1007                 case POPPLER_ACTION_UNKNOWN:
1008                         unimplemented_action = "POPPLER_ACTION_UNKNOWN";
1009         }
1010         
1011         if (unimplemented_action) {
1012                 g_warning ("Unimplemented action: %s, please post a bug report with a testcase.",
1013                            unimplemented_action);
1014         }
1015         
1016         link = ev_link_new (action->any.title, ev_action);
1017         
1018         return link;    
1019 }
1020
1021 static void
1022 build_tree (PdfDocument      *pdf_document,
1023             GtkTreeModel     *model,
1024             GtkTreeIter      *parent,
1025             PopplerIndexIter *iter)
1026 {
1027         
1028         do {
1029                 GtkTreeIter tree_iter;
1030                 PopplerIndexIter *child;
1031                 PopplerAction *action;
1032                 EvLink *link = NULL;
1033                 gboolean expand;
1034                 char *title_markup;
1035                 
1036                 action = poppler_index_iter_get_action (iter);
1037                 expand = poppler_index_iter_is_open (iter);
1038
1039                 if (!action)
1040                         continue;
1041
1042                 switch (action->type) {
1043                         case POPPLER_ACTION_GOTO_DEST: {
1044                                 /* For bookmarks, solve named destinations */
1045                                 if (action->goto_dest.dest->type == POPPLER_DEST_NAMED) {
1046                                         PopplerDest *dest;
1047                                         EvLinkDest *ev_dest = NULL;
1048                                         EvLinkAction *ev_action;
1049                                         
1050                                         dest = poppler_document_find_dest (pdf_document->document,
1051                                                                            action->goto_dest.dest->named_dest);
1052                                         if (!dest) {
1053                                                 link = ev_link_from_action (pdf_document, action);
1054                                                 break;
1055                                         }
1056                                         
1057                                         ev_dest = ev_link_dest_from_dest (pdf_document, dest);
1058                                         poppler_dest_free (dest);
1059                                         
1060                                         ev_action = ev_link_action_new_dest (ev_dest);
1061                                         link = ev_link_new (action->any.title, ev_action);
1062                                 } else {
1063                                         link = ev_link_from_action (pdf_document, action);
1064                                 }
1065                         }
1066                                 break;
1067                         default:
1068                                 link = ev_link_from_action (pdf_document, action);
1069                                 break;
1070                 }
1071                 
1072                 if (!link) {
1073                         poppler_action_free (action);
1074                         continue;
1075                 }
1076
1077                 gtk_tree_store_append (GTK_TREE_STORE (model), &tree_iter, parent);
1078                 title_markup = g_markup_escape_text (ev_link_get_title (link), -1);
1079                 
1080                 gtk_tree_store_set (GTK_TREE_STORE (model), &tree_iter,
1081                                     EV_DOCUMENT_LINKS_COLUMN_MARKUP, title_markup,
1082                                     EV_DOCUMENT_LINKS_COLUMN_LINK, link,
1083                                     EV_DOCUMENT_LINKS_COLUMN_EXPAND, expand,
1084                                     -1);
1085                 
1086                 g_free (title_markup);
1087                 g_object_unref (link);
1088                 
1089                 child = poppler_index_iter_get_child (iter);
1090                 if (child)
1091                         build_tree (pdf_document, model, &tree_iter, child);
1092                 poppler_index_iter_free (child);
1093                 poppler_action_free (action);
1094                 
1095         } while (poppler_index_iter_next (iter));
1096 }
1097
1098 static GtkTreeModel *
1099 pdf_document_links_get_links_model (EvDocumentLinks *document_links)
1100 {
1101         PdfDocument *pdf_document = PDF_DOCUMENT (document_links);
1102         GtkTreeModel *model = NULL;
1103         PopplerIndexIter *iter;
1104         
1105         g_return_val_if_fail (PDF_IS_DOCUMENT (document_links), NULL);
1106
1107         iter = poppler_index_iter_new (pdf_document->document);
1108         /* Create the model if we have items*/
1109         if (iter != NULL) {
1110                 model = (GtkTreeModel *) gtk_tree_store_new (EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS,
1111                                                              G_TYPE_STRING,
1112                                                              G_TYPE_OBJECT,
1113                                                              G_TYPE_BOOLEAN,
1114                                                              G_TYPE_STRING);
1115                 build_tree (pdf_document, model, NULL, iter);
1116                 poppler_index_iter_free (iter);
1117         }
1118         
1119         return model;
1120 }
1121
1122 static GList *
1123 pdf_document_links_get_links (EvDocumentLinks *document_links,
1124                               gint             page)
1125 {
1126         PdfDocument *pdf_document;
1127         PopplerPage *poppler_page;
1128         GList *retval = NULL;
1129         GList *mapping_list;
1130         GList *list;
1131         double height;
1132
1133         pdf_document = PDF_DOCUMENT (document_links);
1134         poppler_page = poppler_document_get_page (pdf_document->document,
1135                                                   page);
1136         mapping_list = poppler_page_get_link_mapping (poppler_page);
1137         poppler_page_get_size (poppler_page, NULL, &height);
1138
1139         for (list = mapping_list; list; list = list->next) {
1140                 PopplerLinkMapping *link_mapping;
1141                 EvLinkMapping *ev_link_mapping;
1142
1143                 link_mapping = (PopplerLinkMapping *)list->data;
1144                 ev_link_mapping = g_new (EvLinkMapping, 1);
1145                 ev_link_mapping->link = ev_link_from_action (pdf_document,
1146                                                              link_mapping->action);
1147                 ev_link_mapping->x1 = link_mapping->area.x1;
1148                 ev_link_mapping->x2 = link_mapping->area.x2;
1149                 /* Invert this for X-style coordinates */
1150                 ev_link_mapping->y1 = height - link_mapping->area.y2;
1151                 ev_link_mapping->y2 = height - link_mapping->area.y1;
1152
1153                 retval = g_list_prepend (retval, ev_link_mapping);
1154         }
1155
1156         poppler_page_free_link_mapping (mapping_list);
1157         g_object_unref (poppler_page);
1158
1159         return g_list_reverse (retval);
1160 }
1161
1162 static EvLinkDest *
1163 pdf_document_links_find_link_dest (EvDocumentLinks  *document_links,
1164                                    const gchar      *link_name)
1165 {
1166         PdfDocument *pdf_document;
1167         PopplerDest *dest;
1168         EvLinkDest *ev_dest = NULL;
1169
1170         pdf_document = PDF_DOCUMENT (document_links);
1171         dest = poppler_document_find_dest (pdf_document->document,
1172                                            link_name);
1173         if (dest) {
1174                 ev_dest = ev_link_dest_from_dest (pdf_document, dest);
1175                 poppler_dest_free (dest);
1176         }
1177
1178         return ev_dest;
1179 }
1180
1181 static void
1182 pdf_document_document_links_iface_init (EvDocumentLinksIface *iface)
1183 {
1184         iface->has_document_links = pdf_document_links_has_document_links;
1185         iface->get_links_model = pdf_document_links_get_links_model;
1186         iface->get_links = pdf_document_links_get_links;
1187         iface->find_link_dest = pdf_document_links_find_link_dest;
1188 }
1189
1190 static GList *
1191 pdf_document_images_get_images (EvDocumentImages *document_images,
1192                                 gint              page)
1193 {
1194         GList *retval = NULL;
1195         PdfDocument *pdf_document;
1196         PopplerPage *poppler_page;
1197         GList *mapping_list;
1198         GList *list;
1199
1200         pdf_document = PDF_DOCUMENT (document_images);
1201         poppler_page = poppler_document_get_page (pdf_document->document, page);
1202         mapping_list = poppler_page_get_image_mapping (poppler_page);
1203
1204         for (list = mapping_list; list; list = list->next) {
1205                 PopplerImageMapping *image_mapping;
1206                 EvImageMapping *ev_image_mapping;
1207
1208                 image_mapping = (PopplerImageMapping *)list->data;
1209
1210                 ev_image_mapping = g_new (EvImageMapping, 1);
1211                 
1212                 ev_image_mapping->image = ev_image_new_from_pixbuf (image_mapping->image);
1213                 ev_image_mapping->x1 = image_mapping->area.x1;
1214                 ev_image_mapping->x2 = image_mapping->area.x2;
1215                 ev_image_mapping->y1 = image_mapping->area.y1;
1216                 ev_image_mapping->y2 = image_mapping->area.y2;
1217
1218                 retval = g_list_prepend (retval, ev_image_mapping);
1219         }
1220
1221         poppler_page_free_image_mapping (mapping_list);
1222         g_object_unref (poppler_page);
1223
1224         return retval;
1225 }
1226
1227 static void
1228 pdf_document_document_images_iface_init (EvDocumentImagesIface *iface)
1229 {
1230         iface->get_images = pdf_document_images_get_images;
1231 }
1232
1233 static GdkPixbuf *
1234 make_thumbnail_for_page (PdfDocument     *pdf_document,
1235                          PopplerPage     *poppler_page, 
1236                          EvRenderContext *rc)
1237 {
1238         GdkPixbuf *pixbuf;
1239         int width, height;
1240
1241         pdf_document_thumbnails_get_dimensions (EV_DOCUMENT_THUMBNAILS (pdf_document),
1242                                                 rc, &width, &height);
1243
1244         pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
1245                                  width, height);
1246         gdk_pixbuf_fill (pixbuf, 0xffffffff);
1247
1248         ev_document_fc_mutex_lock ();
1249         poppler_page_render_to_pixbuf (poppler_page, 0, 0,
1250                                        width, height,
1251                                        rc->scale, rc->rotation, pixbuf);
1252         ev_document_fc_mutex_unlock ();
1253
1254         return pixbuf;
1255 }
1256
1257 static GdkPixbuf *
1258 pdf_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document_thumbnails,
1259                                        EvRenderContext      *rc, 
1260                                        gboolean              border)
1261 {
1262         PdfDocument *pdf_document;
1263         PopplerPage *poppler_page;
1264         GdkPixbuf *pixbuf;
1265         GdkPixbuf *border_pixbuf;
1266
1267         pdf_document = PDF_DOCUMENT (document_thumbnails);
1268
1269         poppler_page = poppler_document_get_page (pdf_document->document, rc->page);
1270         g_return_val_if_fail (poppler_page != NULL, NULL);
1271
1272         pixbuf = poppler_page_get_thumbnail (poppler_page);
1273         if (!pixbuf) {
1274                 /* There is no provided thumbnail.  We need to make one. */
1275                 pixbuf = make_thumbnail_for_page (pdf_document, poppler_page, rc);
1276         }
1277
1278         if (border) {           
1279                 border_pixbuf = ev_document_misc_get_thumbnail_frame (-1, -1, pixbuf);
1280                 g_object_unref (pixbuf);
1281                 pixbuf = border_pixbuf;
1282         }               
1283
1284         g_object_unref (poppler_page);
1285         
1286         return pixbuf;
1287 }
1288
1289 static void
1290 pdf_document_thumbnails_get_dimensions (EvDocumentThumbnails *document_thumbnails,
1291                                         EvRenderContext      *rc,
1292                                         gint                 *width,
1293                                         gint                 *height)
1294 {
1295         PdfDocument *pdf_document;
1296         PopplerPage *poppler_page;
1297         gint has_thumb;
1298         
1299         pdf_document = PDF_DOCUMENT (document_thumbnails);
1300         poppler_page = poppler_document_get_page (pdf_document->document, rc->page);
1301
1302         g_return_if_fail (poppler_page != NULL);
1303
1304         has_thumb = poppler_page_get_thumbnail_size (poppler_page, width, height);
1305
1306         if (!has_thumb) {
1307                 double page_width, page_height;
1308
1309                 poppler_page_get_size (poppler_page, &page_width, &page_height);
1310
1311                 *width = (gint) MAX (page_width * rc->scale, 1);
1312                 *height = (gint) MAX (page_height * rc->scale, 1);
1313         }
1314         
1315         if (rc->rotation == 90 || rc->rotation == 270) {
1316                 gint  temp;
1317
1318                 temp = *width;
1319                 *width = *height;
1320                 *height = temp;
1321         }
1322         
1323         g_object_unref (poppler_page);
1324 }
1325
1326 static void
1327 pdf_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface)
1328 {
1329         iface->get_thumbnail = pdf_document_thumbnails_get_thumbnail;
1330         iface->get_dimensions = pdf_document_thumbnails_get_dimensions;
1331 }
1332
1333
1334 static gboolean
1335 pdf_document_search_idle_callback (void *data)
1336 {
1337         PdfDocumentSearch *search = (PdfDocumentSearch*) data;
1338         PdfDocument *pdf_document = search->document;
1339         int n_pages;
1340         GList *matches;
1341         PopplerPage *page;
1342
1343         page = poppler_document_get_page (search->document->document,
1344                                           search->search_page);
1345
1346         ev_document_doc_mutex_lock ();
1347         matches = poppler_page_find_text (page, search->text);
1348         ev_document_doc_mutex_unlock ();
1349
1350         g_object_unref (page);
1351
1352         search->pages[search->search_page] = matches;
1353         ev_document_find_changed (EV_DOCUMENT_FIND (pdf_document),
1354                                   search->search_page);
1355
1356         n_pages = pdf_document_get_n_pages (EV_DOCUMENT (search->document));
1357         search->search_page += 1;
1358         if (search->search_page == n_pages) {
1359                 /* wrap around */
1360                 search->search_page = 0;
1361         }
1362
1363         if (search->search_page != search->start_page) {
1364                 return TRUE;
1365         }
1366
1367         /* We're done. */
1368         search->idle = 0; /* will return FALSE to remove */
1369         return FALSE;
1370 }
1371
1372
1373 static PdfDocumentSearch *
1374 pdf_document_search_new (PdfDocument *pdf_document,
1375                          int          start_page,
1376                          const char  *text)
1377 {
1378         PdfDocumentSearch *search;
1379         int n_pages;
1380         int i;
1381
1382         n_pages = pdf_document_get_n_pages (EV_DOCUMENT (pdf_document));
1383
1384         search = g_new0 (PdfDocumentSearch, 1);
1385
1386         search->text = g_strdup (text);
1387         search->pages = g_new0 (GList *, n_pages);
1388         search->document = pdf_document;
1389
1390         /* We add at low priority so the progress bar repaints */
1391         search->idle = g_idle_add_full (G_PRIORITY_LOW,
1392                                         pdf_document_search_idle_callback,
1393                                         search,
1394                                         NULL);
1395
1396         search->start_page = start_page;
1397         search->search_page = start_page;
1398
1399         return search;
1400 }
1401
1402 static void
1403 pdf_document_find_begin (EvDocumentFind   *document,
1404                          int               page,
1405                          const char       *search_string,
1406                          gboolean          case_sensitive)
1407 {
1408         PdfDocument *pdf_document = PDF_DOCUMENT (document);
1409
1410         /* FIXME handle case_sensitive (right now XPDF
1411          * code is always case insensitive for ASCII
1412          * and case sensitive for all other languaages)
1413          */
1414
1415         if (pdf_document->search &&
1416             strcmp (search_string, pdf_document->search->text) == 0)
1417                 return;
1418
1419         if (pdf_document->search)
1420                 pdf_document_search_free (pdf_document->search);
1421
1422         pdf_document->search = pdf_document_search_new (pdf_document,
1423                                                         page,
1424                                                         search_string);
1425 }
1426
1427 static int
1428 pdf_document_find_get_n_results (EvDocumentFind *document_find, int page)
1429 {
1430         PdfDocumentSearch *search = PDF_DOCUMENT (document_find)->search;
1431
1432         if (search) {
1433                 return g_list_length (search->pages[page]);
1434         } else {
1435                 return 0;
1436         }
1437 }
1438
1439 static gboolean
1440 pdf_document_find_get_result (EvDocumentFind *document_find,
1441                               int             page,
1442                               int             n_result,
1443                               EvRectangle    *rectangle)
1444 {
1445         PdfDocument *pdf_document = PDF_DOCUMENT (document_find);
1446         PdfDocumentSearch *search = pdf_document->search;
1447         PopplerPage *poppler_page;
1448         PopplerRectangle *r;
1449         double height;
1450
1451         if (search == NULL)
1452                 return FALSE;
1453
1454         r = (PopplerRectangle *) g_list_nth_data (search->pages[page],
1455                                                   n_result);
1456         if (r == NULL)
1457                 return FALSE;
1458
1459         poppler_page = poppler_document_get_page (pdf_document->document, page);
1460         poppler_page_get_size (poppler_page, NULL, &height);
1461         rectangle->x1 = r->x1;
1462         rectangle->y1 = height - r->y2;
1463         rectangle->x2 = r->x2;
1464         rectangle->y2 = height - r->y1;
1465         g_object_unref (poppler_page);
1466                 
1467         return TRUE;
1468 }
1469
1470 static int
1471 pdf_document_find_page_has_results (EvDocumentFind *document_find,
1472                                     int             page)
1473 {
1474         PdfDocumentSearch *search = PDF_DOCUMENT (document_find)->search;
1475
1476         return search && search->pages[page] != NULL;
1477 }
1478
1479 static double
1480 pdf_document_find_get_progress (EvDocumentFind *document_find)
1481 {
1482         PdfDocumentSearch *search;
1483         int n_pages, pages_done;
1484
1485         search = PDF_DOCUMENT (document_find)->search;
1486
1487         if (search == NULL) {
1488                 return 0;
1489         }
1490
1491         n_pages = pdf_document_get_n_pages (EV_DOCUMENT (document_find));
1492         if (search->search_page > search->start_page) {
1493                 pages_done = search->search_page - search->start_page + 1;
1494         } else if (search->search_page == search->start_page) {
1495                 pages_done = n_pages;
1496         } else {
1497                 pages_done = n_pages - search->start_page + search->search_page;
1498         }
1499
1500         return pages_done / (double) n_pages;
1501 }
1502
1503 static void
1504 pdf_document_find_cancel (EvDocumentFind *document)
1505 {
1506         PdfDocument *pdf_document = PDF_DOCUMENT (document);
1507
1508         if (pdf_document->search) {
1509                 pdf_document_search_free (pdf_document->search);
1510                 pdf_document->search = NULL;
1511         }
1512 }
1513
1514 static void
1515 pdf_document_find_iface_init (EvDocumentFindIface *iface)
1516 {
1517         iface->begin = pdf_document_find_begin;
1518         iface->get_n_results = pdf_document_find_get_n_results;
1519         iface->get_result = pdf_document_find_get_result;
1520         iface->page_has_results = pdf_document_find_page_has_results;
1521         iface->get_progress = pdf_document_find_get_progress;
1522         iface->cancel = pdf_document_find_cancel;
1523 }
1524
1525 static void
1526 pdf_print_context_free (PdfPrintContext *ctx)
1527 {
1528         if (!ctx)
1529                 return;
1530
1531         if (ctx->ps_file) {
1532                 poppler_ps_file_free (ctx->ps_file);
1533                 ctx->ps_file = NULL;
1534         }
1535 #ifdef HAVE_CAIRO_PRINT
1536         if (ctx->cr) {
1537                 cairo_destroy (ctx->cr);
1538                 ctx->cr = NULL;
1539         }
1540 #endif
1541         g_free (ctx);
1542 }
1543
1544 static void
1545 pdf_document_file_exporter_begin (EvFileExporter        *exporter,
1546                                   EvFileExporterContext *fc)
1547 {
1548         PdfDocument *pdf_document = PDF_DOCUMENT (exporter);
1549         PdfPrintContext *ctx;
1550         gdouble width, height;
1551         gboolean change_orient = FALSE;
1552 #ifdef HAVE_CAIRO_PRINT
1553         cairo_surface_t *surface = NULL;
1554 #endif
1555         
1556         if (pdf_document->print_ctx)
1557                 pdf_print_context_free (pdf_document->print_ctx);
1558         pdf_document->print_ctx = g_new0 (PdfPrintContext, 1);
1559         ctx = pdf_document->print_ctx;
1560         ctx->format = fc->format;
1561         ctx->pages_per_sheet = fc->pages_per_sheet;
1562
1563         switch (fc->pages_per_sheet) {
1564                 default:
1565                 case 1:
1566                         ctx->pages_x = 1;
1567                         ctx->pages_y = 1;
1568                         break;
1569                 case 2:
1570                         change_orient = TRUE;
1571                         ctx->pages_x = 2;
1572                         ctx->pages_y = 1;
1573                         break;
1574                 case 4:
1575                         ctx->pages_x = 2;
1576                         ctx->pages_y = 2;
1577                         break;
1578                 case 6:
1579                         change_orient = TRUE;
1580                         ctx->pages_x = 3;
1581                         ctx->pages_y = 2;
1582                         break;
1583                 case 9:
1584                         ctx->pages_x = 3;
1585                         ctx->pages_y = 3;
1586                         break;
1587                 case 16:
1588                         ctx->pages_x = 4;
1589                         ctx->pages_y = 4;
1590                         break;
1591         }
1592
1593         if (change_orient) {
1594                 width = fc->paper_height;
1595                 height = fc->paper_width;
1596         } else {
1597                 width = fc->paper_width;
1598                 height = fc->paper_height;
1599         }
1600
1601         ctx->page_width = width / ctx->pages_x;
1602         ctx->page_height = height / ctx->pages_y;
1603
1604         ctx->pages_printed = 0;
1605
1606         switch (fc->format) {
1607                 case EV_FILE_FORMAT_PS:
1608 #ifdef HAVE_CAIRO_PS
1609                         surface = cairo_ps_surface_create (fc->filename, width, height);
1610 #else
1611                         ctx->ps_file = poppler_ps_file_new (pdf_document->document,
1612                                                             fc->filename, fc->first_page,
1613                                                             fc->last_page - fc->first_page + 1);
1614                         poppler_ps_file_set_paper_size (ctx->ps_file, fc->paper_width, fc->paper_height);
1615                         poppler_ps_file_set_duplex (ctx->ps_file, fc->duplex);
1616 #endif /* HAVE_CAIRO_PS */
1617                         break;
1618                 case EV_FILE_FORMAT_PDF:
1619 #ifdef HAVE_CAIRO_PDF
1620                         surface = cairo_pdf_surface_create (fc->filename, width, height);
1621 #endif
1622                         break;
1623                 default:
1624                         g_assert_not_reached ();
1625         }
1626
1627 #ifdef HAVE_CAIRO_PRINT
1628         ctx->cr = cairo_create (surface);
1629         cairo_surface_destroy (surface);
1630 #endif
1631 }
1632
1633 static void
1634 pdf_document_file_exporter_do_page (EvFileExporter  *exporter,
1635                                     EvRenderContext *rc)
1636 {
1637         PdfDocument *pdf_document = PDF_DOCUMENT (exporter);
1638         PdfPrintContext *ctx = pdf_document->print_ctx;
1639         PopplerPage *poppler_page;
1640 #ifdef HAVE_CAIRO_PRINT
1641         gdouble page_width, page_height;
1642         gint    x, y;
1643 #endif
1644
1645         g_return_if_fail (pdf_document->print_ctx != NULL);
1646
1647         poppler_page = poppler_document_get_page (pdf_document->document, rc->page);
1648         
1649 #ifdef HAVE_CAIRO_PRINT
1650         x = (ctx->pages_printed % ctx->pages_per_sheet) % ctx->pages_x;
1651         y = (ctx->pages_printed % ctx->pages_per_sheet) / ctx->pages_x;
1652         poppler_page_get_size (poppler_page, &page_width, &page_height);
1653         
1654         cairo_save (ctx->cr);
1655         cairo_translate (ctx->cr,
1656                          x * ctx->page_width,
1657                          y * ctx->page_height);
1658         cairo_scale (ctx->cr,
1659                      ctx->page_width / page_width,
1660                      ctx->page_height / page_height);
1661
1662 #ifdef HAVE_POPPLER_PAGE_RENDER
1663         poppler_page_render (poppler_page, ctx->cr);
1664 #endif
1665         ctx->pages_printed++;
1666                         
1667         if (ctx->pages_printed % ctx->pages_per_sheet == 0) {
1668                 cairo_show_page (ctx->cr);
1669         }
1670         cairo_restore (ctx->cr);
1671 #else /* HAVE_CAIRO_PRINT */
1672         if (ctx->format == EV_FILE_FORMAT_PS)
1673                 poppler_page_render_to_ps (poppler_page, ctx->ps_file);
1674 #endif /* HAVE_CAIRO_PRINT */
1675         
1676         g_object_unref (poppler_page);
1677 }
1678
1679 static void
1680 pdf_document_file_exporter_end (EvFileExporter *exporter)
1681 {
1682         PdfDocument *pdf_document = PDF_DOCUMENT (exporter);
1683
1684         pdf_print_context_free (pdf_document->print_ctx);
1685         pdf_document->print_ctx = NULL;
1686 }
1687
1688 static EvFileExporterCapabilities
1689 pdf_document_file_exporter_get_capabilities (EvFileExporter *exporter)
1690 {
1691         return  (EvFileExporterCapabilities) (
1692                 EV_FILE_EXPORTER_CAN_PAGE_SET |
1693                 EV_FILE_EXPORTER_CAN_COPIES |
1694                 EV_FILE_EXPORTER_CAN_COLLATE |
1695                 EV_FILE_EXPORTER_CAN_REVERSE |
1696                 EV_FILE_EXPORTER_CAN_SCALE |
1697 #ifdef HAVE_CAIRO_PRINT
1698 #ifdef HAVE_POPPLER_PAGE_RENDER
1699 #if GTK_CHECK_VERSION (2, 11, 1)
1700                 EV_FILE_EXPORTER_CAN_NUMBER_UP |
1701 #endif
1702 #endif
1703 #endif
1704                 
1705 #ifdef HAVE_CAIRO_PDF
1706 #ifdef HAVE_POPPLER_PAGE_RENDER
1707                 EV_FILE_EXPORTER_CAN_GENERATE_PDF |
1708 #endif
1709 #endif
1710                 EV_FILE_EXPORTER_CAN_GENERATE_PS);
1711 }
1712
1713 static void
1714 pdf_document_file_exporter_iface_init (EvFileExporterIface *iface)
1715 {
1716         iface->begin = pdf_document_file_exporter_begin;
1717         iface->do_page = pdf_document_file_exporter_do_page;
1718         iface->end = pdf_document_file_exporter_end;
1719         iface->get_capabilities = pdf_document_file_exporter_get_capabilities;
1720 }
1721
1722 static void
1723 pdf_selection_render_selection (EvSelection      *selection,
1724                                 EvRenderContext  *rc,
1725                                 cairo_surface_t **surface,
1726                                 EvRectangle      *points,
1727                                 EvRectangle      *old_points,
1728                                 GdkColor         *text,
1729                                 GdkColor         *base)
1730 {
1731         PdfDocument *pdf_document;
1732         double width_points, height_points;
1733         gint width, height;
1734
1735         pdf_document = PDF_DOCUMENT (selection);
1736         set_rc_data (pdf_document, rc);
1737
1738         poppler_page_get_size (POPPLER_PAGE (rc->data),
1739                                &width_points, &height_points);
1740         width = (int) ((width_points * rc->scale) + 0.5);
1741         height = (int) ((height_points * rc->scale) + 0.5);
1742
1743
1744 #ifdef HAVE_POPPLER_PAGE_RENDER
1745         cairo_t *cr;
1746
1747         if (*surface == NULL) {
1748                 *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
1749                                                        width, height);
1750                 
1751         }
1752
1753         cr = cairo_create (*surface);
1754         cairo_scale (cr, rc->scale, rc->scale);
1755         cairo_surface_set_device_offset (*surface, 0, 0);
1756         memset (cairo_image_surface_get_data (*surface), 0x00,
1757                 cairo_image_surface_get_height (*surface) *
1758                 cairo_image_surface_get_stride (*surface));
1759         poppler_page_render_selection (POPPLER_PAGE (rc->data),
1760                                        cr,
1761                                        (PopplerRectangle *)points,
1762                                        (PopplerRectangle *)old_points,
1763                                        POPPLER_SELECTION_NORMAL, /* SelectionStyle */
1764                                        text,
1765                                        base);
1766         cairo_destroy (cr);
1767 #else /* HAVE_POPPLER_PAGE_RENDER */
1768         GdkPixbuf *pixbuf;
1769         
1770         pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
1771                                  TRUE, 8,
1772                                  width, height);
1773
1774         poppler_page_render_selection_to_pixbuf (POPPLER_PAGE (rc->data),
1775                                                  rc->scale, rc->rotation, pixbuf,
1776                                                  (PopplerRectangle *)points,
1777                                                  (PopplerRectangle *)old_points,
1778                                                  POPPLER_SELECTION_NORMAL, /* SelectionStyle */
1779                                                  text,
1780                                                  base);
1781         if (*surface)
1782                 cairo_surface_destroy (*surface);
1783         *surface = ev_document_misc_surface_from_pixbuf (pixbuf);
1784         g_object_unref (pixbuf);
1785 #endif /* HAVE_POPPLER_PAGE_RENDER */
1786 }
1787
1788
1789 static GdkRegion *
1790 pdf_selection_get_selection_region (EvSelection     *selection,
1791                                     EvRenderContext *rc,
1792                                     EvRectangle     *points)
1793 {
1794         PdfDocument *pdf_document;
1795         GdkRegion *retval;
1796
1797         pdf_document = PDF_DOCUMENT (selection);
1798
1799         set_rc_data (pdf_document, rc);
1800
1801         retval = poppler_page_get_selection_region ((PopplerPage *)rc->data,
1802                                                     rc->scale,
1803                                                     (PopplerRectangle *) points);
1804         return retval;
1805 }
1806
1807 static GdkRegion *
1808 pdf_selection_get_selection_map (EvSelection     *selection,
1809                                  EvRenderContext *rc)
1810 {
1811         PdfDocument *pdf_document;
1812         PopplerPage *poppler_page;
1813         PopplerRectangle points;
1814         GdkRegion *retval;
1815
1816         pdf_document = PDF_DOCUMENT (selection);
1817         poppler_page = poppler_document_get_page (pdf_document->document,
1818                                                   rc->page);
1819
1820         points.x1 = 0.0;
1821         points.y1 = 0.0;
1822         poppler_page_get_size (poppler_page, &(points.x2), &(points.y2));
1823         retval = poppler_page_get_selection_region (poppler_page, 1.0, &points);
1824         g_object_unref (poppler_page);
1825
1826         return retval;
1827 }
1828
1829 static void
1830 pdf_selection_iface_init (EvSelectionIface *iface)
1831 {
1832         iface->render_selection = pdf_selection_render_selection;
1833         iface->get_selection_region = pdf_selection_get_selection_region;
1834         iface->get_selection_map = pdf_selection_get_selection_map;
1835 }
1836
1837 /* Page Transitions */
1838 static gdouble
1839 pdf_document_get_page_duration (EvDocumentTransition *trans,
1840                                 gint                  page)
1841 {
1842         PdfDocument *pdf_document;
1843         PopplerPage *poppler_page;
1844         gdouble      duration = -1;
1845
1846         pdf_document = PDF_DOCUMENT (trans);
1847         poppler_page = poppler_document_get_page (pdf_document->document, page);
1848         if (!poppler_page)
1849                 return -1;
1850
1851         duration = poppler_page_get_duration (poppler_page);
1852         g_object_unref (poppler_page);
1853
1854         return duration;
1855 }
1856
1857 static void
1858 pdf_document_page_transition_iface_init (EvDocumentTransitionIface *iface)
1859 {
1860         iface->get_page_duration = pdf_document_get_page_duration;
1861 }
1862
1863 PdfDocument *
1864 pdf_document_new (void)
1865 {
1866         return PDF_DOCUMENT (g_object_new (PDF_TYPE_DOCUMENT, NULL));
1867 }
1868
1869 /* Forms */
1870 static void
1871 pdf_document_get_crop_box (EvDocument  *document, 
1872                            int          page, 
1873                            EvRectangle *rect)
1874 {
1875         PdfDocument *pdf_document;
1876         PopplerPage *poppler_page;
1877         PopplerRectangle poppler_rect;
1878
1879         pdf_document = PDF_DOCUMENT (document);
1880         poppler_page = poppler_document_get_page (pdf_document->document, page);
1881         poppler_page_get_crop_box (poppler_page, &poppler_rect);
1882         rect->x1 = poppler_rect.x1;
1883         rect->x2 = poppler_rect.x2;
1884         rect->y1 = poppler_rect.y1;
1885         rect->y2 = poppler_rect.y2;
1886 }
1887
1888 #ifdef HAVE_FORMS
1889 static EvFormField *
1890 ev_form_field_from_poppler_field (PopplerFormField *poppler_field)
1891 {
1892         EvFormField *ev_field = NULL;
1893         gint         id;
1894         gdouble      font_size;
1895         gboolean     is_read_only;
1896
1897         id = poppler_form_field_get_id (poppler_field);
1898         font_size = poppler_form_field_get_font_size (poppler_field);
1899         is_read_only = poppler_form_field_is_read_only (poppler_field);
1900
1901         switch (poppler_form_field_get_field_type (poppler_field)) {
1902                 case POPPLER_FORM_FIELD_TEXT: {
1903                         EvFormFieldText    *field_text;
1904                         EvFormFieldTextType ev_text_type = EV_FORM_FIELD_TEXT_NORMAL;
1905
1906                         switch (poppler_form_field_text_get_text_type (poppler_field)) {
1907                                 case POPPLER_FORM_TEXT_NORMAL:
1908                                         ev_text_type = EV_FORM_FIELD_TEXT_NORMAL;
1909                                         break;
1910                                 case POPPLER_FORM_TEXT_MULTILINE:
1911                                         ev_text_type = EV_FORM_FIELD_TEXT_MULTILINE;
1912                                         break;
1913                                 case POPPLER_FORM_TEXT_FILE_SELECT:
1914                                         ev_text_type = EV_FORM_FIELD_TEXT_FILE_SELECT;
1915                                         break;
1916                         }
1917                         
1918                         ev_field = ev_form_field_text_new (id, ev_text_type);
1919                         field_text = EV_FORM_FIELD_TEXT (ev_field);
1920
1921                         field_text->do_spell_check = poppler_form_field_text_do_spell_check (poppler_field);
1922                         field_text->do_scroll = poppler_form_field_text_do_scroll (poppler_field);
1923                         field_text->is_rich_text = poppler_form_field_text_is_rich_text (poppler_field);
1924                         field_text->is_password = poppler_form_field_text_is_password (poppler_field);
1925                         
1926 #ifdef HAVE_POPPLER_FORM_FIELD_TEXT_GET_MAX_LEN
1927                         field_text->max_len = poppler_form_field_text_get_max_len (poppler_field);
1928 #endif
1929                         field_text->text = poppler_form_field_text_get_text (poppler_field);
1930
1931                 }
1932                         break;
1933                 case POPPLER_FORM_FIELD_BUTTON: {
1934                         EvFormFieldButton    *field_button;
1935                         EvFormFieldButtonType ev_button_type = EV_FORM_FIELD_BUTTON_PUSH;
1936
1937                         switch (poppler_form_field_button_get_button_type (poppler_field)) {
1938                                 case POPPLER_FORM_BUTTON_PUSH:
1939                                         ev_button_type = EV_FORM_FIELD_BUTTON_PUSH;
1940                                         break;
1941                                 case POPPLER_FORM_BUTTON_CHECK:
1942                                         ev_button_type = EV_FORM_FIELD_BUTTON_CHECK;
1943                                         break;
1944                                 case POPPLER_FORM_BUTTON_RADIO:
1945                                         ev_button_type = EV_FORM_FIELD_BUTTON_RADIO;
1946                                         break;
1947                         }
1948
1949                         ev_field = ev_form_field_button_new (id, ev_button_type);
1950                         field_button = EV_FORM_FIELD_BUTTON (ev_field);
1951                         
1952                         field_button->state = poppler_form_field_button_get_state (poppler_field);
1953                 }
1954                         break;
1955                 case POPPLER_FORM_FIELD_CHOICE: {
1956                         EvFormFieldChoice    *field_choice;
1957                         EvFormFieldChoiceType ev_choice_type = EV_FORM_FIELD_CHOICE_COMBO;
1958
1959                         switch (poppler_form_field_choice_get_choice_type (poppler_field)) {
1960                                 case POPPLER_FORM_CHOICE_COMBO:
1961                                         ev_choice_type = EV_FORM_FIELD_CHOICE_COMBO;
1962                                         break;
1963                                 case EV_FORM_FIELD_CHOICE_LIST:
1964                                         ev_choice_type = EV_FORM_FIELD_CHOICE_LIST;
1965                                         break;
1966                         }
1967
1968                         ev_field = ev_form_field_choice_new (id, ev_choice_type);
1969                         field_choice = EV_FORM_FIELD_CHOICE (ev_field);
1970
1971                         field_choice->is_editable = poppler_form_field_choice_is_editable (poppler_field);
1972                         field_choice->multi_select = poppler_form_field_choice_can_select_multiple (poppler_field);
1973                         field_choice->do_spell_check = poppler_form_field_choice_do_spell_check (poppler_field);
1974                         field_choice->commit_on_sel_change = poppler_form_field_choice_commit_on_change (poppler_field);
1975
1976                         /* TODO: we need poppler_form_field_choice_get_selected_items in poppler 
1977                         field_choice->selected_items = poppler_form_field_choice_get_selected_items (poppler_field);*/
1978                         if (field_choice->is_editable)
1979                                 field_choice->text = poppler_form_field_choice_get_text (poppler_field);
1980                 }
1981                         break;
1982                 case POPPLER_FORM_FIELD_SIGNATURE:
1983                         /* TODO */
1984                         ev_field = ev_form_field_signature_new (id);
1985                         break;
1986                 case POPPLER_FORM_FIELD_UNKNOWN:
1987                         break;
1988         }
1989
1990         ev_field->font_size = font_size;
1991         ev_field->is_read_only = is_read_only;
1992
1993         return ev_field;
1994 }
1995
1996 static GList *
1997 pdf_document_forms_get_form_fields (EvDocumentForms *document, 
1998                                     gint             page)
1999 {
2000         PdfDocument *pdf_document;
2001         PopplerPage *poppler_page;
2002         GList *retval = NULL;
2003         GList *fields;
2004         GList *list;
2005         double height;
2006         
2007
2008         pdf_document = PDF_DOCUMENT (document);
2009         poppler_page = poppler_document_get_page (pdf_document->document, page);
2010         fields = poppler_page_get_form_field_mapping (poppler_page);
2011         poppler_page_get_size (poppler_page, NULL, &height);
2012
2013         for (list = fields; list; list = list->next) {
2014                 PopplerFormFieldMapping *mapping;
2015                 EvFormFieldMapping *field_mapping;
2016                 
2017                 mapping = (PopplerFormFieldMapping *)list->data;
2018
2019                 field_mapping = g_new0 (EvFormFieldMapping, 1);
2020                 field_mapping->x1 = mapping->area.x1;
2021                 field_mapping->x2 = mapping->area.x2;
2022                 field_mapping->y1 = height - mapping->area.y2;
2023                 field_mapping->y2 = height - mapping->area.y1;
2024                 field_mapping->field = ev_form_field_from_poppler_field (mapping->field);
2025                 field_mapping->field->page = page;
2026                 
2027                 retval = g_list_prepend (retval, field_mapping);
2028         }
2029         poppler_page_free_form_field_mapping (fields);
2030         g_object_unref (poppler_page);
2031
2032         return g_list_reverse (retval);
2033 }
2034
2035 static gchar *
2036 pdf_document_forms_form_field_text_get_text (EvDocumentForms *document,
2037                                              EvFormField     *field)
2038         
2039 {
2040         PdfDocument *pdf_document = PDF_DOCUMENT (document);
2041         PopplerFormField *poppler_field;
2042         gchar *text;
2043
2044         poppler_field = poppler_document_get_form_field (pdf_document->document, field->id);
2045         if (!poppler_field)
2046                 return NULL;
2047         
2048         text = poppler_form_field_text_get_text (poppler_field);
2049         g_object_unref (poppler_field);
2050
2051         return text;
2052 }
2053
2054 static void
2055 pdf_document_forms_form_field_text_set_text (EvDocumentForms *document, 
2056                                              EvFormField     *field,
2057                                              const gchar     *text)
2058 {
2059         PdfDocument *pdf_document = PDF_DOCUMENT (document);
2060         PopplerFormField *poppler_field;
2061
2062         poppler_field = poppler_document_get_form_field (pdf_document->document, field->id);
2063         if (!poppler_field)
2064                 return;
2065         poppler_form_field_text_set_text (poppler_field, text);
2066         g_object_unref (poppler_field);
2067 }
2068
2069 static void
2070 pdf_document_forms_form_field_button_set_state (EvDocumentForms *document, 
2071                                                 EvFormField     *field,
2072                                                 gboolean         state)
2073 {
2074         PdfDocument *pdf_document = PDF_DOCUMENT (document);
2075         PopplerFormField *poppler_field;
2076
2077         poppler_field = poppler_document_get_form_field (pdf_document->document, field->id);
2078         if (!poppler_field)
2079                 return;
2080         
2081         poppler_form_field_button_set_state (poppler_field, state);
2082         g_object_unref (poppler_field);
2083 }
2084
2085 static gboolean
2086 pdf_document_forms_form_field_button_get_state (EvDocumentForms *document, 
2087                                                 EvFormField     *field)
2088 {
2089         PdfDocument *pdf_document = PDF_DOCUMENT (document);
2090         PopplerFormField *poppler_field;
2091         gboolean state;
2092
2093         poppler_field = poppler_document_get_form_field (pdf_document->document, field->id);
2094         if (!poppler_field)
2095                 return FALSE;
2096
2097         state = poppler_form_field_button_get_state (poppler_field);
2098         g_object_unref (poppler_field);
2099
2100         return state;
2101 }
2102
2103 static gchar *
2104 pdf_document_forms_form_field_choice_get_item (EvDocumentForms *document, 
2105                                                EvFormField     *field,
2106                                                gint             index)
2107 {
2108         PdfDocument *pdf_document = PDF_DOCUMENT (document);
2109         PopplerFormField *poppler_field;
2110         gchar *text;
2111
2112         poppler_field = poppler_document_get_form_field (pdf_document->document, field->id);
2113         if (!poppler_field)
2114                 return NULL;
2115
2116         text = poppler_form_field_choice_get_item (poppler_field, index);
2117         g_object_unref (poppler_field);
2118
2119         return text;
2120 }
2121
2122 static int
2123 pdf_document_forms_form_field_choice_get_n_items (EvDocumentForms *document, 
2124                                                   EvFormField     *field)
2125 {
2126         PdfDocument *pdf_document = PDF_DOCUMENT (document);
2127         PopplerFormField *poppler_field;
2128         gint n_items;
2129
2130         poppler_field = poppler_document_get_form_field (pdf_document->document, field->id);
2131         if (!poppler_field)
2132                 return -1;
2133         
2134         n_items = poppler_form_field_choice_get_n_items (poppler_field);
2135         g_object_unref (poppler_field);
2136
2137         return n_items;
2138 }
2139
2140 static gboolean
2141 pdf_document_forms_form_field_choice_is_item_selected (EvDocumentForms *document, 
2142                                                        EvFormField     *field,
2143                                                        gint             index)
2144 {
2145         PdfDocument *pdf_document = PDF_DOCUMENT (document);
2146         PopplerFormField *poppler_field;
2147         gboolean selected;
2148
2149         poppler_field = poppler_document_get_form_field (pdf_document->document, field->id);
2150         if (!poppler_field)
2151                 return FALSE;
2152
2153         selected = poppler_form_field_choice_is_item_selected (poppler_field, index);
2154         g_object_unref (poppler_field);
2155
2156         return selected;
2157 }
2158
2159 static void
2160 pdf_document_forms_form_field_choice_select_item (EvDocumentForms *document, 
2161                                                   EvFormField     *field,
2162                                                   gint             index)
2163 {
2164         PdfDocument *pdf_document = PDF_DOCUMENT (document);
2165         PopplerFormField *poppler_field;
2166
2167         poppler_field = poppler_document_get_form_field (pdf_document->document, field->id);
2168         if (!poppler_field)
2169                 return;
2170
2171         poppler_form_field_choice_select_item (poppler_field, index);
2172         g_object_unref (poppler_field);
2173 }
2174
2175 static void
2176 pdf_document_forms_form_field_choice_toggle_item (EvDocumentForms *document, 
2177                                                   EvFormField     *field,
2178                                                   gint             index)
2179 {
2180         PdfDocument *pdf_document = PDF_DOCUMENT (document);
2181         PopplerFormField *poppler_field;
2182
2183         poppler_field = poppler_document_get_form_field (pdf_document->document, field->id);
2184         if (!poppler_field)
2185                 return;
2186
2187         poppler_form_field_choice_toggle_item (poppler_field, index);
2188         g_object_unref (poppler_field);
2189 }
2190
2191 static void
2192 pdf_document_forms_form_field_choice_unselect_all (EvDocumentForms *document, 
2193                                                    EvFormField     *field)
2194 {
2195         PdfDocument *pdf_document = PDF_DOCUMENT (document);
2196         PopplerFormField *poppler_field;
2197
2198         poppler_field = poppler_document_get_form_field (pdf_document->document, field->id);
2199         if (!poppler_field)
2200                 return;
2201         
2202         poppler_form_field_choice_unselect_all (poppler_field);
2203         g_object_unref (poppler_field);
2204 }
2205
2206 static void
2207 pdf_document_forms_form_field_choice_set_text (EvDocumentForms *document,
2208                                                EvFormField     *field,
2209                                                const gchar     *text)
2210 {
2211         PdfDocument *pdf_document = PDF_DOCUMENT (document);
2212         PopplerFormField *poppler_field;
2213
2214         poppler_field = poppler_document_get_form_field (pdf_document->document, field->id);
2215         if (!poppler_field)
2216                 return;
2217         
2218         poppler_form_field_choice_set_text (poppler_field, text);
2219         g_object_unref (poppler_field);
2220 }
2221
2222 static gchar *
2223 pdf_document_forms_form_field_choice_get_text (EvDocumentForms *document,
2224                                                EvFormField     *field)
2225 {
2226         PdfDocument *pdf_document = PDF_DOCUMENT (document);
2227         PopplerFormField *poppler_field;
2228         gchar *text;
2229
2230         poppler_field = poppler_document_get_form_field (pdf_document->document, field->id);
2231         if (!poppler_field)
2232                 return NULL;
2233
2234         text = poppler_form_field_choice_get_text (poppler_field);
2235         g_object_unref (poppler_field);
2236
2237         return text;
2238 }
2239
2240 static void
2241 pdf_document_document_forms_iface_init (EvDocumentFormsIface *iface)
2242 {
2243         iface->get_form_fields = pdf_document_forms_get_form_fields;
2244         iface->form_field_text_get_text = pdf_document_forms_form_field_text_get_text;
2245         iface->form_field_text_set_text = pdf_document_forms_form_field_text_set_text;
2246         iface->form_field_button_set_state = pdf_document_forms_form_field_button_set_state;
2247         iface->form_field_button_get_state = pdf_document_forms_form_field_button_get_state;
2248         iface->form_field_choice_get_item = pdf_document_forms_form_field_choice_get_item;
2249         iface->form_field_choice_get_n_items = pdf_document_forms_form_field_choice_get_n_items;
2250         iface->form_field_choice_is_item_selected = pdf_document_forms_form_field_choice_is_item_selected;
2251         iface->form_field_choice_select_item = pdf_document_forms_form_field_choice_select_item;
2252         iface->form_field_choice_toggle_item = pdf_document_forms_form_field_choice_toggle_item;
2253         iface->form_field_choice_unselect_all = pdf_document_forms_form_field_choice_unselect_all;
2254         iface->form_field_choice_set_text = pdf_document_forms_form_field_choice_set_text;
2255         iface->form_field_choice_get_text = pdf_document_forms_form_field_choice_get_text;
2256 }
2257 #endif /* HAVE_FORMS */