]> www.fi.muni.cz Git - evince.git/blobdiff - backend/pdf/ev-poppler.cc
build: Include string.h for strcmp()
[evince.git] / backend / pdf / ev-poppler.cc
index 2d838ea2ff1abe94fc4b252d86c8fdc7fdd20866..93064456aede70e507db2309163f1793144e8cba 100644 (file)
@@ -48,6 +48,7 @@
 #include "ev-document-layers.h"
 #include "ev-document-print.h"
 #include "ev-document-annotations.h"
 #include "ev-document-layers.h"
 #include "ev-document-print.h"
 #include "ev-document-annotations.h"
+#include "ev-document-attachments.h"
 #include "ev-selection.h"
 #include "ev-transition-effect.h"
 #include "ev-attachment.h"
 #include "ev-selection.h"
 #include "ev-transition-effect.h"
 #include "ev-attachment.h"
@@ -91,12 +92,12 @@ typedef struct {
 
 struct _PdfDocumentClass
 {
 
 struct _PdfDocumentClass
 {
-       GObjectClass parent_class;
+       EvDocumentClass parent_class;
 };
 
 struct _PdfDocument
 {
 };
 
 struct _PdfDocument
 {
-       GObject parent_instance;
+       EvDocument parent_instance;
 
        PopplerDocument *document;
        gchar *password;
 
        PopplerDocument *document;
        gchar *password;
@@ -112,7 +113,6 @@ struct _PdfDocument
        GList *layers;
 };
 
        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_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);
@@ -124,6 +124,7 @@ static void pdf_document_document_layers_iface_init      (EvDocumentLayersIface
 static void pdf_document_document_print_iface_init       (EvDocumentPrintIface       *iface);
 #endif
 static void pdf_document_document_annotations_iface_init (EvDocumentAnnotationsIface *iface);
 static void pdf_document_document_print_iface_init       (EvDocumentPrintIface       *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_find_iface_init                 (EvDocumentFindIface        *iface);
 static void pdf_document_file_exporter_iface_init        (EvFileExporterIface        *iface);
 static void pdf_selection_iface_init                     (EvSelectionIface           *iface);
@@ -163,6 +164,8 @@ EV_BACKEND_REGISTER_WITH_CODE (PdfDocument, pdf_document,
 #endif
                                 EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_ANNOTATIONS,
                                                                 pdf_document_document_annotations_iface_init);
 #endif
                                 EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_ANNOTATIONS,
                                                                 pdf_document_document_annotations_iface_init);
+                                EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_ATTACHMENTS,
+                                                                pdf_document_document_attachments_iface_init);
                                 EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FIND,
                                                                 pdf_document_find_iface_init);
                                 EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_FILE_EXPORTER,
                                 EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FIND,
                                                                 pdf_document_find_iface_init);
                                 EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_FILE_EXPORTER,
@@ -229,14 +232,6 @@ pdf_document_dispose (GObject *object)
        G_OBJECT_CLASS (pdf_document_parent_class)->dispose (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)
 {
 static void
 pdf_document_init (PdfDocument *pdf_document)
 {
@@ -361,122 +356,6 @@ pdf_document_get_page_label (EvDocument *document,
        return label;
 }
 
        return label;
 }
 
-static gboolean
-pdf_document_has_attachments (EvDocument *document)
-{
-       PdfDocument *pdf_document;
-
-       pdf_document = PDF_DOCUMENT (document);
-
-       return poppler_document_has_attachments (pdf_document->document);
-}
-
-struct SaveToBufferData {
-       gchar *buffer;
-       gsize len, max;
-};
-
-static gboolean
-attachment_save_to_buffer_callback (const gchar  *buf,
-                                   gsize         count,
-                                   gpointer      user_data,
-                                   GError      **error)
-{
-       struct SaveToBufferData *sdata = (SaveToBufferData *)user_data;
-       gchar *new_buffer;
-       gsize new_max;
-
-       if (sdata->len + count > sdata->max) {
-               new_max = MAX (sdata->max * 2, sdata->len + count);
-               new_buffer = (gchar *)g_realloc (sdata->buffer, new_max);
-
-               sdata->buffer = new_buffer;
-               sdata->max = new_max;
-       }
-       
-       memcpy (sdata->buffer + sdata->len, buf, count);
-       sdata->len += count;
-       
-       return TRUE;
-}
-
-static gboolean
-attachment_save_to_buffer (PopplerAttachment  *attachment,
-                          gchar             **buffer,
-                          gsize              *buffer_size,
-                          GError            **error)
-{
-       static const gint initial_max = 1024;
-       struct SaveToBufferData sdata;
-
-       *buffer = NULL;
-       *buffer_size = 0;
-
-       sdata.buffer = (gchar *) g_malloc (initial_max);
-       sdata.max = initial_max;
-       sdata.len = 0;
-
-       if (! poppler_attachment_save_to_callback (attachment,
-                                                  attachment_save_to_buffer_callback,
-                                                  &sdata,
-                                                  error)) {
-               g_free (sdata.buffer);
-               return FALSE;
-       }
-
-       *buffer = sdata.buffer;
-       *buffer_size = sdata.len;
-       
-       return TRUE;
-}
-
-static GList *
-pdf_document_get_attachments (EvDocument *document)
-{
-       PdfDocument *pdf_document;
-       GList *attachments;
-       GList *list;
-       GList *retval = NULL;
-
-       pdf_document = PDF_DOCUMENT (document);
-
-       if (!pdf_document_has_attachments (document))
-               return NULL;
-
-       attachments = poppler_document_get_attachments (pdf_document->document);
-       
-       for (list = attachments; list; list = list->next) {
-               PopplerAttachment *attachment;
-               EvAttachment *ev_attachment;
-               gchar *data = NULL;
-               gsize size;
-               GError *error = NULL;
-
-               attachment = (PopplerAttachment *) list->data;
-
-               if (attachment_save_to_buffer (attachment, &data, &size, &error)) {
-                       ev_attachment = ev_attachment_new (attachment->name,
-                                                          attachment->description,
-                                                          attachment->mtime,
-                                                          attachment->ctime,
-                                                          size, data);
-                       
-                       retval = g_list_prepend (retval, ev_attachment);
-               } else {
-                       if (error) {
-                               g_warning ("%s", error->message);
-                               g_error_free (error);
-
-                               g_free (data);
-                       }
-               }
-
-               g_object_unref (attachment);
-       }
-
-       return g_list_reverse (retval);
-}
-
 static cairo_surface_t *
 pdf_page_render (PopplerPage     *page,
                 gint             width,
 static cairo_surface_t *
 pdf_page_render (PopplerPage     *page,
                 gint             width,
@@ -487,14 +366,11 @@ pdf_page_render (PopplerPage     *page,
 
 #ifdef HAVE_POPPLER_PAGE_RENDER
        cairo_t *cr;
 
 #ifdef HAVE_POPPLER_PAGE_RENDER
        cairo_t *cr;
-       
-       surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+
+       surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                              width, height);
                                              width, height);
-       memset (cairo_image_surface_get_data (surface), 0xff,
-               cairo_image_surface_get_height (surface) *
-               cairo_image_surface_get_stride (surface));
-       
        cr = cairo_create (surface);
        cr = cairo_create (surface);
+
        switch (rc->rotation) {
                case 90:
                        cairo_translate (cr, width, 0);
        switch (rc->rotation) {
                case 90:
                        cairo_translate (cr, width, 0);
@@ -511,6 +387,11 @@ pdf_page_render (PopplerPage     *page,
        cairo_scale (cr, rc->scale, rc->scale);
        cairo_rotate (cr, rc->rotation * G_PI / 180.0);
        poppler_page_render (page, cr);
        cairo_scale (cr, rc->scale, rc->scale);
        cairo_rotate (cr, rc->rotation * G_PI / 180.0);
        poppler_page_render (page, cr);
+
+       cairo_set_operator (cr, CAIRO_OPERATOR_DEST_OVER);
+       cairo_set_source_rgb (cr, 1., 1., 1.);
+       cairo_paint (cr);
+
        cairo_destroy (cr);
 #else /* HAVE_POPPLER_PAGE_RENDER */
        GdkPixbuf *pixbuf;
        cairo_destroy (cr);
 #else /* HAVE_POPPLER_PAGE_RENDER */
        GdkPixbuf *pixbuf;
@@ -558,28 +439,6 @@ pdf_document_render (EvDocument      *document,
                                width, height, rc);
 }
 
                                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 *
 /* 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 *
@@ -729,13 +588,9 @@ pdf_document_get_info (EvDocument *document)
        info->n_pages = ev_document_get_n_pages (document);
 
        if (info->n_pages > 0) {
        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));
                                           &(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;
                // Convert to mm.
                info->paper_width = info->paper_width / 72.0f * 25.4f;
                info->paper_height = info->paper_height / 72.0f * 25.4f;
@@ -831,19 +686,42 @@ pdf_document_get_info (EvDocument *document)
 }
 
 static void
 }
 
 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->has_attachments = pdf_document_has_attachments;
-       iface->get_attachments = pdf_document_get_attachments;
-       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;
+}
+
+/* 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)
 
 static void
 pdf_document_security_iface_init (EvDocumentSecurityIface *iface)
@@ -2530,13 +2408,13 @@ ev_annot_from_poppler_annot (PopplerAnnot *poppler_annot,
                        PopplerAnnotMarkup *markup;
                        gchar *label;
                        gdouble opacity;
                        PopplerAnnotMarkup *markup;
                        gchar *label;
                        gdouble opacity;
-                       gboolean is_open;
                        PopplerRectangle poppler_rect;
 
                        markup = POPPLER_ANNOT_MARKUP (poppler_annot);
 
                        if (poppler_annot_markup_get_popup_rectangle (markup, &poppler_rect)) {
                                EvRectangle ev_rect;
                        PopplerRectangle poppler_rect;
 
                        markup = POPPLER_ANNOT_MARKUP (poppler_annot);
 
                        if (poppler_annot_markup_get_popup_rectangle (markup, &poppler_rect)) {
                                EvRectangle ev_rect;
+                               gboolean is_open;
                                gdouble height;
 
                                poppler_page_get_size (POPPLER_PAGE (page->backend_page),
                                gdouble height;
 
                                poppler_page_get_size (POPPLER_PAGE (page->backend_page),
@@ -2546,17 +2424,28 @@ ev_annot_from_poppler_annot (PopplerAnnot *poppler_annot,
                                ev_rect.y1 = height - poppler_rect.y2;
                                ev_rect.y2 = height - poppler_rect.y1;
 
                                ev_rect.y1 = height - poppler_rect.y2;
                                ev_rect.y2 = height - poppler_rect.y1;
 
-                               g_object_set (ev_annot, "rectangle", &ev_rect, NULL);
+                               is_open = poppler_annot_markup_get_popup_is_open (markup);
+
+                               g_object_set (ev_annot,
+                                             "rectangle", &ev_rect,
+                                             "is_open", is_open,
+                                             "has_popup", TRUE,
+                                             NULL);
+                       } else {
+                               /* FIXME: Use poppler_annot_markup_has_popup() when
+                                * new poppler is released.
+                                */
+                               g_object_set (ev_annot,
+                                             "has_popup", FALSE,
+                                             NULL);
                        }
 
                        label = poppler_annot_markup_get_label (markup);
                        opacity = poppler_annot_markup_get_opacity (markup);
                        }
 
                        label = poppler_annot_markup_get_label (markup);
                        opacity = poppler_annot_markup_get_opacity (markup);
-                       is_open = poppler_annot_markup_get_popup_is_open (markup);
 
                        g_object_set (ev_annot,
                                      "label", label,
                                      "opacity", opacity,
 
                        g_object_set (ev_annot,
                                      "label", label,
                                      "opacity", opacity,
-                                     "is_open", is_open,
                                      NULL);
 
                        g_free (label);
                                      NULL);
 
                        g_free (label);
@@ -2642,6 +2531,123 @@ pdf_document_document_annotations_iface_init (EvDocumentAnnotationsIface *iface)
        iface->annotation_set_contents = pdf_document_annotations_annotation_set_contents;
 }
 
        iface->annotation_set_contents = pdf_document_annotations_annotation_set_contents;
 }
 
+/* Attachments */
+struct SaveToBufferData {
+       gchar *buffer;
+       gsize len, max;
+};
+
+static gboolean
+attachment_save_to_buffer_callback (const gchar  *buf,
+                                   gsize         count,
+                                   gpointer      user_data,
+                                   GError      **error)
+{
+       struct SaveToBufferData *sdata = (SaveToBufferData *)user_data;
+       gchar *new_buffer;
+       gsize new_max;
+
+       if (sdata->len + count > sdata->max) {
+               new_max = MAX (sdata->max * 2, sdata->len + count);
+               new_buffer = (gchar *)g_realloc (sdata->buffer, new_max);
+
+               sdata->buffer = new_buffer;
+               sdata->max = new_max;
+       }
+
+       memcpy (sdata->buffer + sdata->len, buf, count);
+       sdata->len += count;
+
+       return TRUE;
+}
+
+static gboolean
+attachment_save_to_buffer (PopplerAttachment  *attachment,
+                          gchar             **buffer,
+                          gsize              *buffer_size,
+                          GError            **error)
+{
+       static const gint initial_max = 1024;
+       struct SaveToBufferData sdata;
+
+       *buffer = NULL;
+       *buffer_size = 0;
+
+       sdata.buffer = (gchar *) g_malloc (initial_max);
+       sdata.max = initial_max;
+       sdata.len = 0;
+
+       if (! poppler_attachment_save_to_callback (attachment,
+                                                  attachment_save_to_buffer_callback,
+                                                  &sdata,
+                                                  error)) {
+               g_free (sdata.buffer);
+               return FALSE;
+       }
+
+       *buffer = sdata.buffer;
+       *buffer_size = sdata.len;
+
+       return TRUE;
+}
+
+static GList *
+pdf_document_attachments_get_attachments (EvDocumentAttachments *document)
+{
+       PdfDocument *pdf_document = PDF_DOCUMENT (document);
+       GList *attachments;
+       GList *list;
+       GList *retval = NULL;
+
+       attachments = poppler_document_get_attachments (pdf_document->document);
+
+       for (list = attachments; list; list = list->next) {
+               PopplerAttachment *attachment;
+               EvAttachment *ev_attachment;
+               gchar *data = NULL;
+               gsize size;
+               GError *error = NULL;
+
+               attachment = (PopplerAttachment *) list->data;
+
+               if (attachment_save_to_buffer (attachment, &data, &size, &error)) {
+                       ev_attachment = ev_attachment_new (attachment->name,
+                                                          attachment->description,
+                                                          attachment->mtime,
+                                                          attachment->ctime,
+                                                          size, data);
+
+                       retval = g_list_prepend (retval, ev_attachment);
+               } else {
+                       if (error) {
+                               g_warning ("%s", error->message);
+                               g_error_free (error);
+
+                               g_free (data);
+                       }
+               }
+
+               g_object_unref (attachment);
+       }
+
+       return g_list_reverse (retval);
+}
+
+static gboolean
+pdf_document_attachments_has_attachments (EvDocumentAttachments *document)
+{
+       PdfDocument *pdf_document = PDF_DOCUMENT (document);
+
+       return poppler_document_has_attachments (pdf_document->document);
+}
+
+static void
+pdf_document_document_attachments_iface_init (EvDocumentAttachmentsIface *iface)
+{
+       iface->has_attachments = pdf_document_attachments_has_attachments;
+       iface->get_attachments = pdf_document_attachments_get_attachments;
+}
+
 /* Layers */
 static gboolean
 pdf_document_layers_has_layers (EvDocumentLayers *document)
 /* Layers */
 static gboolean
 pdf_document_layers_has_layers (EvDocumentLayers *document)