X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=backend%2Fpdf%2Fev-poppler.cc;h=add48f7448ab85d6a75b28e1d55b11e87a1fd166;hb=d52ff81f97f4bd3794e1517443096846baee068b;hp=0333d715564810d5209bc9856e0c2386fc8b6733;hpb=3d3328b2597e9b85afcb552ffc6abdeca1e3e3a7;p=evince.git diff --git a/backend/pdf/ev-poppler.cc b/backend/pdf/ev-poppler.cc index 0333d715..add48f74 100644 --- a/backend/pdf/ev-poppler.cc +++ b/backend/pdf/ev-poppler.cc @@ -1,5 +1,7 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ -/* pdfdocument.h: Implementation of EvDocument for PDF +/* this file is part of evince, a gnome document viewer + * + * Copyright (C) 2009, Juanjo Marín * Copyright (C) 2004, Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify @@ -14,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" @@ -63,6 +65,13 @@ #define HAVE_CAIRO_PRINT #endif +/* fields from the XMP Rights Management Schema, XMP Specification Sept 2005, pag. 45 */ +#define LICENSE_MARKED "/x:xmpmeta/rdf:RDF/rdf:Description/xmpRights:Marked" +#define LICENSE_TEXT "/x:xmpmeta/rdf:RDF/rdf:Description/dc:rights/rdf:Alt/rdf:li[lang('%s')]" +#define LICENSE_WEB_STATEMENT "/x:xmpmeta/rdf:RDF/rdf:Description/xmpRights:WebStatement" +/* license field from Creative Commons schema, http://creativecommons.org/ns */ +#define LICENSE_URI "/x:xmpmeta/rdf:RDF/rdf:Description/cc:license/@rdf:resource" + typedef struct { PdfDocument *document; char *text; @@ -92,12 +101,12 @@ typedef struct { struct _PdfDocumentClass { - GObjectClass parent_class; + EvDocumentClass parent_class; }; struct _PdfDocument { - GObject parent_instance; + EvDocument parent_instance; PopplerDocument *document; gchar *password; @@ -113,35 +122,38 @@ struct _PdfDocument GList *layers; }; -static void pdf_document_document_iface_init (EvDocumentIface *iface); -static void pdf_document_security_iface_init (EvDocumentSecurityIface *iface); -static void pdf_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface); -static void pdf_document_document_links_iface_init (EvDocumentLinksIface *iface); -static void pdf_document_document_images_iface_init (EvDocumentImagesIface *iface); -static void pdf_document_document_forms_iface_init (EvDocumentFormsIface *iface); -static void pdf_document_document_fonts_iface_init (EvDocumentFontsIface *iface); -static void pdf_document_document_layers_iface_init (EvDocumentLayersIface *iface); +static void pdf_document_security_iface_init (EvDocumentSecurityInterface *iface); +static void pdf_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *iface); +static void pdf_document_document_links_iface_init (EvDocumentLinksInterface *iface); +static void pdf_document_document_images_iface_init (EvDocumentImagesInterface *iface); +static void pdf_document_document_forms_iface_init (EvDocumentFormsInterface *iface); +static void pdf_document_document_fonts_iface_init (EvDocumentFontsInterface *iface); +static void pdf_document_document_layers_iface_init (EvDocumentLayersInterface *iface); #ifdef HAVE_POPPLER_PAGE_RENDER -static void pdf_document_document_print_iface_init (EvDocumentPrintIface *iface); +static void pdf_document_document_print_iface_init (EvDocumentPrintInterface *iface); #endif -static void pdf_document_document_annotations_iface_init (EvDocumentAnnotationsIface *iface); -static void pdf_document_document_attachments_iface_init (EvDocumentAttachmentsIface *iface); -static void pdf_document_find_iface_init (EvDocumentFindIface *iface); -static void pdf_document_file_exporter_iface_init (EvFileExporterIface *iface); -static void pdf_selection_iface_init (EvSelectionIface *iface); -static void pdf_document_page_transition_iface_init (EvDocumentTransitionIface *iface); -static void pdf_document_thumbnails_get_dimensions (EvDocumentThumbnails *document_thumbnails, - EvRenderContext *rc, - gint *width, - gint *height); -static int pdf_document_get_n_pages (EvDocument *document); - -static EvLinkDest *ev_link_dest_from_dest (PdfDocument *pdf_document, - PopplerDest *dest); -static EvLink *ev_link_from_action (PdfDocument *pdf_document, - PopplerAction *action); -static void pdf_document_search_free (PdfDocumentSearch *search); -static void pdf_print_context_free (PdfPrintContext *ctx); +static void pdf_document_document_annotations_iface_init (EvDocumentAnnotationsInterface *iface); +static void pdf_document_document_attachments_iface_init (EvDocumentAttachmentsInterface *iface); +static void pdf_document_find_iface_init (EvDocumentFindInterface *iface); +static void pdf_document_file_exporter_iface_init (EvFileExporterInterface *iface); +static void pdf_selection_iface_init (EvSelectionInterface *iface); +static void pdf_document_page_transition_iface_init (EvDocumentTransitionInterface *iface); +static void pdf_document_thumbnails_get_dimensions (EvDocumentThumbnails *document_thumbnails, + EvRenderContext *rc, + gint *width, + gint *height); +static int pdf_document_get_n_pages (EvDocument *document); + +static EvLinkDest *ev_link_dest_from_dest (PdfDocument *pdf_document, + PopplerDest *dest); +static EvLink *ev_link_from_action (PdfDocument *pdf_document, + PopplerAction *action); +static void pdf_document_search_free (PdfDocumentSearch *search); +static void pdf_print_context_free (PdfPrintContext *ctx); +static gboolean attachment_save_to_buffer (PopplerAttachment *attachment, + gchar **buffer, + gsize *buffer_size, + GError **error); EV_BACKEND_REGISTER_WITH_CODE (PdfDocument, pdf_document, { @@ -233,14 +245,6 @@ pdf_document_dispose (GObject *object) G_OBJECT_CLASS (pdf_document_parent_class)->dispose (object); } -static void -pdf_document_class_init (PdfDocumentClass *klass) -{ - GObjectClass *g_object_class = G_OBJECT_CLASS (klass); - - g_object_class->dispose = pdf_document_dispose; -} - static void pdf_document_init (PdfDocument *pdf_document) { @@ -448,51 +452,18 @@ pdf_document_render (EvDocument *document, width, height, rc); } -/* EvDocumentSecurity */ - -static gboolean -pdf_document_has_document_security (EvDocumentSecurity *document_security) -{ - /* FIXME: do we really need to have this? */ - return FALSE; -} - -static void -pdf_document_set_password (EvDocumentSecurity *document_security, - const char *password) -{ - PdfDocument *document = PDF_DOCUMENT (document_security); - - if (document->password) - g_free (document->password); - - document->password = g_strdup (password); -} - - /* reference: http://www.pdfa.org/lib/exe/fetch.php?id=pdfa%3Aen%3Atechdoc&cache=cache&media=pdfa:techdoc:tn0001_pdfa-1_and_namespaces_2008-03-18.pdf */ static char * -pdf_document_get_format_from_metadata (const char *metadata) +pdf_document_get_format_from_metadata (xmlDocPtr doc, + xmlXPathContextPtr xpathCtx) { - xmlDocPtr doc; - xmlXPathContextPtr xpathCtx; xmlXPathObjectPtr xpathObj; xmlChar *part = NULL; xmlChar *conf = NULL; char *result = NULL; int i; - doc = xmlParseMemory (metadata, strlen (metadata)); - if (doc == NULL) - return NULL; /* invalid xml metadata */ - - xpathCtx = xmlXPathNewContext (doc); - if (xpathCtx == NULL) { - xmlFreeDoc (doc); - return NULL; /* invalid xpath context */ - } - /* add pdf/a namespaces */ xmlXPathRegisterNs (xpathCtx, BAD_CAST "x", BAD_CAST "adobe:ns:meta/"); xmlXPathRegisterNs (xpathCtx, BAD_CAST "rdf", BAD_CAST "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); @@ -550,12 +521,159 @@ pdf_document_get_format_from_metadata (const char *metadata) /* Cleanup */ xmlFree (part); xmlFree (conf); - xmlXPathFreeContext (xpathCtx); - xmlFreeDoc (doc); return result; } +static EvDocumentLicense * +pdf_document_get_license_from_metadata (xmlDocPtr doc, + xmlXPathContextPtr xpathCtx) +{ + xmlXPathObjectPtr xpathObj; + xmlChar *marked = NULL; + const char *language_string; + char *aux; + gchar **tags; + gchar *tag, *tag_aux; + int i, j; + EvDocumentLicense *license; + + /* register namespaces */ + xmlXPathRegisterNs (xpathCtx, BAD_CAST "x", BAD_CAST "adobe:ns:meta/"); + xmlXPathRegisterNs (xpathCtx, BAD_CAST "rdf", BAD_CAST "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); + xmlXPathRegisterNs (xpathCtx, BAD_CAST "dc", BAD_CAST "http://purl.org/dc/elements/1.1/"); + /* XMP Rights Management Schema */ + xmlXPathRegisterNs (xpathCtx, BAD_CAST "xmpRights", BAD_CAST "http://ns.adobe.com/xap/1.0/rights/"); + /* Creative Commons Schema */ + xmlXPathRegisterNs (xpathCtx, BAD_CAST "cc", BAD_CAST "http://creativecommons.org/ns#"); + + /* checking if the document has been marked as defined on the XMP Rights + * Management Schema */ + xpathObj = xmlXPathEvalExpression (BAD_CAST LICENSE_MARKED, xpathCtx); + if (xpathObj != NULL) { + if (xpathObj->nodesetval != NULL && + xpathObj->nodesetval->nodeNr != 0) + marked = xmlNodeGetContent (xpathObj->nodesetval->nodeTab[0]); + xmlXPathFreeObject (xpathObj); + } + + /* a) Not marked => No XMP Rights information */ + if (!marked) { + xmlFree (marked); + return NULL; + } + + license = ev_document_license_new (); + + /* b) Marked False => Public Domain, no copyrighted material and no + * license needed */ + if (g_strrstr ((char *) marked, "False") != NULL) { + license->text = g_strdup (_("This work is in the Public Domain")); + /* c) Marked True => Copyrighted material */ + } else { + /* Checking usage terms as defined by the XMP Rights Management + * Schema. This field is recomended to be checked by Creative + * Commons */ + /* 1) checking for a suitable localized string */ + language_string = pango_language_to_string (gtk_get_default_language ()); + tags = g_strsplit (language_string, "-", -1); + i = g_strv_length (tags); + while (i-- && !license->text) { + tag = g_strdup (tags[0]); + for (j = 1; j <= i; j++) { + tag_aux = g_strdup_printf ("%s-%s", tag, tags[j]); + g_free (tag); + tag = tag_aux; + } + aux = g_strdup_printf (LICENSE_TEXT, tag); + xpathObj = xmlXPathEvalExpression (BAD_CAST aux, xpathCtx); + if (xpathObj != NULL) { + if (xpathObj->nodesetval != NULL && + xpathObj->nodesetval->nodeNr != 0) + license->text = (gchar *)xmlNodeGetContent (xpathObj->nodesetval->nodeTab[0]); + xmlXPathFreeObject (xpathObj); + } + g_free (tag); + g_free (aux); + } + g_strfreev(tags); + + /* 2) if not, use the default string */ + if (!license->text) { + aux = g_strdup_printf (LICENSE_TEXT, "x-default"); + xpathObj = xmlXPathEvalExpression (BAD_CAST aux, xpathCtx); + if (xpathObj != NULL) { + if (xpathObj->nodesetval != NULL && + xpathObj->nodesetval->nodeNr != 0) + license->text = (gchar *)xmlNodeGetContent (xpathObj->nodesetval->nodeTab[0]); + xmlXPathFreeObject (xpathObj); + } + g_free (aux); + } + + /* Checking the license URI as defined by the Creative Commons + * Schema. This field is recomended to be checked by Creative + * Commons */ + xpathObj = xmlXPathEvalExpression (BAD_CAST LICENSE_URI, xpathCtx); + if (xpathObj != NULL) { + if (xpathObj->nodesetval != NULL && + xpathObj->nodesetval->nodeNr != 0) + license->uri = (gchar *)xmlNodeGetContent (xpathObj->nodesetval->nodeTab[0]); + xmlXPathFreeObject (xpathObj); + } + + /* Checking the web statement as defined by the XMP Rights + * Management Schema. Checking it out is a sort of above-and-beyond + * the basic recommendations by Creative Commons. It can be + * considered as a "reinforcement" approach to add certainty. */ + xpathObj = xmlXPathEvalExpression (BAD_CAST LICENSE_WEB_STATEMENT, xpathCtx); + if (xpathObj != NULL) { + if (xpathObj->nodesetval != NULL && + xpathObj->nodesetval->nodeNr != 0) + license->web_statement = (gchar *)xmlNodeGetContent (xpathObj->nodesetval->nodeTab[0]); + xmlXPathFreeObject (xpathObj); + } + } + xmlFree (marked); + + if (!license->text && !license->uri && !license->web_statement) { + ev_document_license_free (license); + return NULL; + } + + return license; +} + +static void +pdf_document_parse_metadata (const gchar *metadata, + EvDocumentInfo *info) +{ + xmlDocPtr doc; + xmlXPathContextPtr xpathCtx; + gchar *fmt; + + doc = xmlParseMemory (metadata, strlen (metadata)); + if (doc == NULL) + return; /* invalid xml metadata */ + + xpathCtx = xmlXPathNewContext (doc); + if (xpathCtx == NULL) { + xmlFreeDoc (doc); + return; /* invalid xpath context */ + } + + fmt = pdf_document_get_format_from_metadata (doc, xpathCtx); + if (fmt != NULL) { + g_free (info->format); + info->format = fmt; + } + + info->license = pdf_document_get_license_from_metadata (doc, xpathCtx); + + xmlXPathFreeContext (xpathCtx); + xmlFreeDoc (doc); +} + static EvDocumentInfo * pdf_document_get_info (EvDocument *document) @@ -567,7 +685,6 @@ pdf_document_get_info (EvDocument *document) PopplerPermissions permissions; EvPage *page; char *metadata; - char *fmt; info = g_new0 (EvDocumentInfo, 1); @@ -587,7 +704,8 @@ pdf_document_get_info (EvDocument *document) EV_DOCUMENT_INFO_LINEARIZED | EV_DOCUMENT_INFO_N_PAGES | EV_DOCUMENT_INFO_SECURITY | - EV_DOCUMENT_INFO_PAPER_SIZE; + EV_DOCUMENT_INFO_PAPER_SIZE | + EV_DOCUMENT_INFO_LICENSE; g_object_get (PDF_DOCUMENT (document)->document, "title", &(info->title), @@ -608,24 +726,16 @@ pdf_document_get_info (EvDocument *document) NULL); if (metadata != NULL) { - fmt = pdf_document_get_format_from_metadata(metadata); - if (fmt != NULL) { - g_free (info->format); - info->format = fmt; - } + pdf_document_parse_metadata (metadata, info); g_free (metadata); } info->n_pages = ev_document_get_n_pages (document); if (info->n_pages > 0) { - page = ev_document_get_page (document, 0); - ev_document_get_page_size (document, page, + ev_document_get_page_size (document, 0, &(info->paper_width), &(info->paper_height)); - g_object_unref (page); - - // Convert to mm. info->paper_width = info->paper_width / 72.0f * 25.4f; info->paper_height = info->paper_height / 72.0f * 25.4f; @@ -720,21 +830,70 @@ pdf_document_get_info (EvDocument *document) return info; } +static gboolean +pdf_document_get_backend_info (EvDocument *document, EvDocumentBackendInfo *info) +{ + PopplerBackend backend; + + backend = poppler_get_backend (); + switch (backend) { + case POPPLER_BACKEND_CAIRO: + info->name = "poppler/cairo"; + break; + case POPPLER_BACKEND_SPLASH: + info->name = "poppler/splash"; + break; + default: + info->name = "poppler/unknown"; + break; + } + + info->version = poppler_get_version (); + + return TRUE; +} + static void -pdf_document_document_iface_init (EvDocumentIface *iface) -{ - iface->save = pdf_document_save; - iface->load = pdf_document_load; - iface->get_n_pages = pdf_document_get_n_pages; - iface->get_page = pdf_document_get_page; - iface->get_page_size = pdf_document_get_page_size; - iface->get_page_label = pdf_document_get_page_label; - iface->render = pdf_document_render; - iface->get_info = pdf_document_get_info; -}; +pdf_document_class_init (PdfDocumentClass *klass) +{ + GObjectClass *g_object_class = G_OBJECT_CLASS (klass); + EvDocumentClass *ev_document_class = EV_DOCUMENT_CLASS (klass); + + g_object_class->dispose = pdf_document_dispose; + + ev_document_class->save = pdf_document_save; + ev_document_class->load = pdf_document_load; + ev_document_class->get_n_pages = pdf_document_get_n_pages; + ev_document_class->get_page = pdf_document_get_page; + ev_document_class->get_page_size = pdf_document_get_page_size; + ev_document_class->get_page_label = pdf_document_get_page_label; + ev_document_class->render = pdf_document_render; + ev_document_class->get_info = pdf_document_get_info; + ev_document_class->get_backend_info = pdf_document_get_backend_info; +} + +/* EvDocumentSecurity */ +static gboolean +pdf_document_has_document_security (EvDocumentSecurity *document_security) +{ + /* FIXME: do we really need to have this? */ + return FALSE; +} + +static void +pdf_document_set_password (EvDocumentSecurity *document_security, + const char *password) +{ + PdfDocument *document = PDF_DOCUMENT (document_security); + + if (document->password) + g_free (document->password); + + document->password = g_strdup (password); +} static void -pdf_document_security_iface_init (EvDocumentSecurityIface *iface) +pdf_document_security_iface_init (EvDocumentSecurityInterface *iface) { iface->has_document_security = pdf_document_has_document_security; iface->set_password = pdf_document_set_password; @@ -854,7 +1013,7 @@ pdf_document_fonts_fill_model (EvDocumentFonts *document_fonts, } static void -pdf_document_document_fonts_iface_init (EvDocumentFontsIface *iface) +pdf_document_document_fonts_iface_init (EvDocumentFontsInterface *iface) { iface->fill_model = pdf_document_fonts_fill_model; iface->scan = pdf_document_fonts_scan; @@ -1125,7 +1284,7 @@ pdf_document_links_get_links_model (EvDocumentLinks *document_links) static GList * pdf_document_links_get_links (EvDocumentLinks *document_links, - gint page) + EvPage *page) { PdfDocument *pdf_document; PopplerPage *poppler_page; @@ -1135,8 +1294,7 @@ pdf_document_links_get_links (EvDocumentLinks *document_links, double height; pdf_document = PDF_DOCUMENT (document_links); - poppler_page = poppler_document_get_page (pdf_document->document, - page); + poppler_page = POPPLER_PAGE (page->backend_page); mapping_list = poppler_page_get_link_mapping (poppler_page); poppler_page_get_size (poppler_page, NULL, &height); @@ -1158,7 +1316,6 @@ pdf_document_links_get_links (EvDocumentLinks *document_links, } poppler_page_free_link_mapping (mapping_list); - g_object_unref (poppler_page); return g_list_reverse (retval); } @@ -1183,7 +1340,7 @@ pdf_document_links_find_link_dest (EvDocumentLinks *document_links, } static void -pdf_document_document_links_iface_init (EvDocumentLinksIface *iface) +pdf_document_document_links_iface_init (EvDocumentLinksInterface *iface) { iface->has_document_links = pdf_document_links_has_document_links; iface->get_links_model = pdf_document_links_get_links_model; @@ -1193,7 +1350,7 @@ pdf_document_document_links_iface_init (EvDocumentLinksIface *iface) static GList * pdf_document_images_get_image_mapping (EvDocumentImages *document_images, - gint page) + EvPage *page) { GList *retval = NULL; PdfDocument *pdf_document; @@ -1202,7 +1359,7 @@ pdf_document_images_get_image_mapping (EvDocumentImages *document_images, GList *list; pdf_document = PDF_DOCUMENT (document_images); - poppler_page = poppler_document_get_page (pdf_document->document, page); + poppler_page = POPPLER_PAGE (page->backend_page); mapping_list = poppler_page_get_image_mapping (poppler_page); for (list = mapping_list; list; list = list->next) { @@ -1213,7 +1370,7 @@ pdf_document_images_get_image_mapping (EvDocumentImages *document_images, ev_image_mapping = g_new (EvMapping, 1); - ev_image_mapping->data = ev_image_new (page, image_mapping->image_id); + ev_image_mapping->data = ev_image_new (page->index, image_mapping->image_id); ev_image_mapping->area.x1 = image_mapping->area.x1; ev_image_mapping->area.y1 = image_mapping->area.y1; ev_image_mapping->area.x2 = image_mapping->area.x2; @@ -1223,7 +1380,6 @@ pdf_document_images_get_image_mapping (EvDocumentImages *document_images, } poppler_page_free_image_mapping (mapping_list); - g_object_unref (poppler_page); return g_list_reverse (retval); } @@ -1254,7 +1410,7 @@ pdf_document_images_get_image (EvDocumentImages *document_images, } static void -pdf_document_document_images_iface_init (EvDocumentImagesIface *iface) +pdf_document_document_images_iface_init (EvDocumentImagesInterface *iface) { iface->get_image_mapping = pdf_document_images_get_image_mapping; iface->get_image = pdf_document_images_get_image; @@ -1375,7 +1531,7 @@ pdf_document_thumbnails_get_dimensions (EvDocumentThumbnails *document_thumbnail } static void -pdf_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface) +pdf_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *iface) { iface->get_thumbnail = pdf_document_thumbnails_get_thumbnail; iface->get_dimensions = pdf_document_thumbnails_get_dimensions; @@ -1415,7 +1571,7 @@ pdf_document_find_find_text (EvDocumentFind *document_find, } static void -pdf_document_find_iface_init (EvDocumentFindIface *iface) +pdf_document_find_iface_init (EvDocumentFindInterface *iface) { iface->find_text = pdf_document_find_find_text; } @@ -1699,7 +1855,7 @@ pdf_document_file_exporter_get_capabilities (EvFileExporter *exporter) } static void -pdf_document_file_exporter_iface_init (EvFileExporterIface *iface) +pdf_document_file_exporter_iface_init (EvFileExporterInterface *iface) { iface->begin = pdf_document_file_exporter_begin; iface->begin_page = pdf_document_file_exporter_begin_page; @@ -1722,7 +1878,7 @@ pdf_document_print_print_page (EvDocumentPrint *document, } static void -pdf_document_document_print_iface_init (EvDocumentPrintIface *iface) +pdf_document_document_print_iface_init (EvDocumentPrintInterface *iface) { iface->print_page = pdf_document_print_print_page; } @@ -1804,7 +1960,7 @@ pdf_selection_render_selection (EvSelection *selection, static gchar * pdf_selection_get_selected_text (EvSelection *selection, - EvRenderContext *rc, + EvPage *page, EvSelectionStyle style, EvRectangle *points) { @@ -1813,7 +1969,7 @@ pdf_selection_get_selected_text (EvSelection *selection, double height; char *retval; - poppler_page = POPPLER_PAGE (rc->page->backend_page); + poppler_page = POPPLER_PAGE (page->backend_page); poppler_page_get_size (poppler_page, NULL, &height); r.x1 = points->x1; @@ -1877,15 +2033,15 @@ pdf_selection_get_selection_region (EvSelection *selection, } static GdkRegion * -pdf_selection_get_selection_map (EvSelection *selection, - EvRenderContext *rc) +pdf_selection_get_selection_map (EvSelection *selection, + EvPage *page) { PopplerPage *poppler_page; PopplerRectangle points; GList *region; GdkRegion *retval; - poppler_page = POPPLER_PAGE (rc->page->backend_page); + poppler_page = POPPLER_PAGE (page->backend_page); points.x1 = 0.0; points.y1 = 0.0; @@ -1901,7 +2057,7 @@ pdf_selection_get_selection_map (EvSelection *selection, } static void -pdf_selection_iface_init (EvSelectionIface *iface) +pdf_selection_iface_init (EvSelectionInterface *iface) { iface->render_selection = pdf_selection_render_selection; iface->get_selected_text = pdf_selection_get_selected_text; @@ -1968,7 +2124,7 @@ pdf_document_get_effect (EvDocumentTransition *trans, } static void -pdf_document_page_transition_iface_init (EvDocumentTransitionIface *iface) +pdf_document_page_transition_iface_init (EvDocumentTransitionInterface *iface) { iface->get_page_duration = pdf_document_get_page_duration; iface->get_effect = pdf_document_get_effect; @@ -2334,7 +2490,7 @@ pdf_document_forms_form_field_choice_get_text (EvDocumentForms *document, } static void -pdf_document_document_forms_iface_init (EvDocumentFormsIface *iface) +pdf_document_document_forms_iface_init (EvDocumentFormsInterface *iface) { iface->get_form_fields = pdf_document_forms_get_form_fields; iface->form_field_text_get_text = pdf_document_forms_form_field_text_get_text; @@ -2376,7 +2532,7 @@ ev_annot_from_poppler_annot (PopplerAnnot *poppler_annot, const gchar *unimplemented_annot = NULL; switch (poppler_annot_get_annot_type (poppler_annot)) { - case POPPLER_ANNOT_TEXT: + case POPPLER_ANNOT_TEXT: { PopplerAnnotText *poppler_text; EvAnnotationText *ev_annot_text; @@ -2386,8 +2542,41 @@ ev_annot_from_poppler_annot (PopplerAnnot *poppler_annot, ev_annot_text = EV_ANNOTATION_TEXT (ev_annot); ev_annot_text->is_open = poppler_annot_text_get_is_open (poppler_text); + } + break; +#ifdef HAVE_POPPLER_ANNOT_FILE_ATTACHMENT_GET_ATTACHMENT + case POPPLER_ANNOT_FILE_ATTACHMENT: { + PopplerAnnotFileAttachment *poppler_annot_attachment; + EvAnnotationAttachment *ev_annot_attachment; + PopplerAttachment *poppler_attachment; + gchar *data = NULL; + gsize size; + GError *error = NULL; + + poppler_annot_attachment = POPPLER_ANNOT_FILE_ATTACHMENT (poppler_annot); + poppler_attachment = poppler_annot_file_attachment_get_attachment (poppler_annot_attachment); + + if (poppler_attachment && + attachment_save_to_buffer (poppler_attachment, &data, &size, &error)) { + EvAttachment *ev_attachment; + + ev_attachment = ev_attachment_new (poppler_attachment->name, + poppler_attachment->description, + poppler_attachment->mtime, + poppler_attachment->ctime, + size, data); + ev_annot = ev_annotation_attachment_new (page, ev_attachment); + g_object_unref (ev_attachment); + } else if (error) { + g_warning ("%s", error->message); + g_error_free (error); + } + if (poppler_attachment) + g_object_unref (poppler_attachment); + } break; +#endif /* HAVE_POPPLER_ANNOT_FILE_ATTACHMENT_GET_ATTACHMENT */ case POPPLER_ANNOT_LINK: case POPPLER_ANNOT_WIDGET: /* Ignore link and widgets annots since they are already handled */ @@ -2535,7 +2724,7 @@ pdf_document_annotations_annotation_set_contents (EvDocumentAnnotations *documen } static void -pdf_document_document_annotations_iface_init (EvDocumentAnnotationsIface *iface) +pdf_document_document_annotations_iface_init (EvDocumentAnnotationsInterface *iface) { iface->get_annotations = pdf_document_annotations_get_annotations; iface->annotation_set_contents = pdf_document_annotations_annotation_set_contents; @@ -2652,7 +2841,7 @@ pdf_document_attachments_has_attachments (EvDocumentAttachments *document) } static void -pdf_document_document_attachments_iface_init (EvDocumentAttachmentsIface *iface) +pdf_document_document_attachments_iface_init (EvDocumentAttachmentsInterface *iface) { iface->has_attachments = pdf_document_attachments_has_attachments; iface->get_attachments = pdf_document_attachments_get_attachments; @@ -2782,7 +2971,7 @@ pdf_document_layers_layer_is_visible (EvDocumentLayers *document, } static void -pdf_document_document_layers_iface_init (EvDocumentLayersIface *iface) +pdf_document_document_layers_iface_init (EvDocumentLayersInterface *iface) { iface->has_layers = pdf_document_layers_has_layers; iface->get_layers = pdf_document_layers_get_layers;