[evince/BUG_annotations_with_cropbox] annotations: take into account /CropBox



commit 28912381ddcd80ae184be14410641947f5119ef4
Author: Nelson Benítez León <nbenitezl gmail com>
Date:   Tue Oct 15 21:27:36 2019 -0400

    annotations: take into account /CropBox
    
    If PDF page has a /CropBox, take it into
    account when calculating the coordinates
    for new annotations.
    
    Issue #1280

 backend/pdf/ev-poppler.cc | 65 ++++++++++++++++++++++++++++++-----------------
 libdocument/ev-document.c | 24 +++++++++++++++++
 libdocument/ev-document.h |  6 +++++
 libview/ev-view.c         | 36 ++++++++++++++++----------
 4 files changed, 95 insertions(+), 36 deletions(-)
---
diff --git a/backend/pdf/ev-poppler.cc b/backend/pdf/ev-poppler.cc
index 8f2e9804..3cc4a481 100644
--- a/backend/pdf/ev-poppler.cc
+++ b/backend/pdf/ev-poppler.cc
@@ -379,6 +379,29 @@ pdf_document_get_page_size (EvDocument *document,
        poppler_page_get_size (POPPLER_PAGE (page->backend_page), width, height);
 }
 
+static void
+get_page_crop_box (EvPage      *page,
+                  EvRectangle *rect)
+{
+       PopplerPage *poppler_page;
+       PopplerRectangle poppler_rect;
+
+       poppler_page = POPPLER_PAGE (page->backend_page);
+       poppler_page_get_crop_box (poppler_page, &poppler_rect);
+       rect->x1 = poppler_rect.x1;
+       rect->x2 = poppler_rect.x2;
+       rect->y1 = poppler_rect.y1;
+       rect->y2 = poppler_rect.y2;
+}
+
+static void
+pdf_document_get_page_crop_box (EvDocument  *document,
+                               EvPage      *page,
+                               EvRectangle *rect)
+{
+       get_page_crop_box (page, rect);
+}
+
 static char *
 pdf_document_get_page_label (EvDocument *document,
                             EvPage     *page)
@@ -1231,6 +1254,7 @@ pdf_document_class_init (PdfDocumentClass *klass)
        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_crop_box = pdf_document_get_page_crop_box;
        ev_document_class->get_page_label = pdf_document_get_page_label;
        ev_document_class->render = pdf_document_render;
        ev_document_class->get_thumbnail = pdf_document_get_thumbnail;
@@ -2631,26 +2655,6 @@ pdf_document_page_transition_iface_init (EvDocumentTransitionInterface *iface)
 }
 
 /* Forms */
-#if 0
-static void
-pdf_document_get_crop_box (EvDocument  *document,
-                          int          page,
-                          EvRectangle *rect)
-{
-       PdfDocument *pdf_document;
-       PopplerPage *poppler_page;
-       PopplerRectangle poppler_rect;
-
-       pdf_document = PDF_DOCUMENT (document);
-       poppler_page = poppler_document_get_page (pdf_document->document, page);
-       poppler_page_get_crop_box (poppler_page, &poppler_rect);
-       rect->x1 = poppler_rect.x1;
-       rect->x2 = poppler_rect.x2;
-       rect->y1 = poppler_rect.y1;
-       rect->y2 = poppler_rect.y2;
-}
-#endif
-
 static EvFormField *
 ev_form_field_from_poppler_field (PdfDocument      *pdf_document,
                                  PopplerFormField *poppler_field)
@@ -3350,7 +3354,15 @@ annot_area_changed_cb (EvAnnotation *annot,
                       GParamSpec   *spec,
                       EvMapping    *mapping)
 {
-       ev_annotation_get_area (annot, &mapping->area);
+       EvRectangle crop_box, area;
+
+       get_page_crop_box (ev_annotation_get_page (annot), &crop_box);
+       ev_annotation_get_area (annot, &area);
+
+       mapping->area.x1 = area.x1 - crop_box.x1;
+       mapping->area.x2 = area.x2 - crop_box.x1;
+       mapping->area.y1 = area.y1 + crop_box.y1;
+       mapping->area.y2 = area.y2 + crop_box.y1;
 }
 
 static EvMappingList *
@@ -3571,7 +3583,7 @@ pdf_document_annotations_add_annotation (EvDocumentAnnotations *document_annotat
        gdouble          height;
        PopplerColor     poppler_color;
        GdkColor         color;
-       EvRectangle      rect;
+       EvRectangle      rect, cropbox_rect, cropped_rect;
 
        pdf_document = PDF_DOCUMENT (document_annotations);
        page = ev_annotation_get_page (annot);
@@ -3659,7 +3671,14 @@ pdf_document_annotations_add_annotation (EvDocumentAnnotations *document_annotat
        poppler_page_add_annot (poppler_page, poppler_annot);
 
        annot_mapping = g_new (EvMapping, 1);
-       annot_mapping->area = rect;
+
+       get_page_crop_box (page, &cropbox_rect);
+       cropped_rect.x1 = rect.x1 - cropbox_rect.x1;
+       cropped_rect.x2 = rect.x2 - cropbox_rect.x1;
+       cropped_rect.y1 = rect.y1 + cropbox_rect.y1;
+       cropped_rect.y2 = rect.y2 + cropbox_rect.y1;
+
+       annot_mapping->area = cropped_rect;
        annot_mapping->data = annot;
        g_signal_connect (annot, "notify::area",
                          G_CALLBACK (annot_area_changed_cb),
diff --git a/libdocument/ev-document.c b/libdocument/ev-document.c
index 30a96895..f6606a1d 100644
--- a/libdocument/ev-document.c
+++ b/libdocument/ev-document.c
@@ -811,6 +811,30 @@ ev_document_get_page_size (EvDocument *document,
        }
 }
 
+/**
+ * ev_document_get_page_crop_box:
+ * @document: a #EvDocument
+ * @page: a #EvPage
+ * @rect: (out) : return location for the #EvRectangle representing the crop box,
+ *                will be filled with zeros if @page has no crop box.
+ */
+void
+ev_document_get_page_crop_box (EvDocument  *document,
+                              EvPage      *page,
+                              EvRectangle *rect)
+{
+       EvDocumentClass *klass = EV_DOCUMENT_GET_CLASS (document);
+
+       if (klass->get_page_crop_box)
+               return klass->get_page_crop_box (document, page, rect);
+
+       // set to zero when there's no implementation
+       rect->x1 = 0;
+       rect->y1 = 0;
+       rect->x2 = 0;
+       rect->y2 = 0;
+}
+
 static gchar *
 _ev_document_get_page_label (EvDocument *document,
                             EvPage     *page)
diff --git a/libdocument/ev-document.h b/libdocument/ev-document.h
index a3ed4c16..a709d1f5 100644
--- a/libdocument/ev-document.h
+++ b/libdocument/ev-document.h
@@ -108,6 +108,9 @@ struct _EvDocumentClass
                                                     EvPage              *page,
                                                     double              *width,
                                                     double              *height);
+        void              (* get_page_crop_box)     (EvDocument          *document,
+                                                    EvPage              *page,
+                                                    EvRectangle         *rect);
         gchar           * (* get_page_label)        (EvDocument          *document,
                                                     EvPage              *page);
         cairo_surface_t * (* render)                (EvDocument          *document,
@@ -182,6 +185,9 @@ void             ev_document_get_page_size        (EvDocument      *document,
                                                   gint             page_index,
                                                   double          *width,
                                                   double          *height);
+void             ev_document_get_page_crop_box    (EvDocument  *document,
+                                                  EvPage      *page,
+                                                  EvRectangle *rect);
 gchar           *ev_document_get_page_label       (EvDocument      *document,
                                                   gint             page_index);
 cairo_surface_t *ev_document_render               (EvDocument      *document,
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 2bb5e3c2..da946485 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -3421,7 +3421,7 @@ ev_view_create_annotation_real (EvView *view,
                                EvPoint end)
 {
        EvAnnotation   *annot;
-       EvRectangle     doc_rect, popup_rect;
+       EvRectangle     doc_rect, popup_rect, cropbox_rect;
        EvPage         *page;
        GdkColor        color = { 0, 65535, 65535, 0 };
        GdkRectangle    view_rect;
@@ -3429,19 +3429,21 @@ ev_view_create_annotation_real (EvView *view,
 
        ev_document_doc_mutex_lock ();
        page = ev_document_get_page (view->document, annot_page);
+       ev_document_get_page_crop_box (view->document, page, &cropbox_rect);
+
         switch (view->adding_annot_info.type) {
         case EV_ANNOTATION_TYPE_TEXT:
-                doc_rect.x1 = end.x;
-                doc_rect.y1 = end.y;
+                doc_rect.x1 = end.x + cropbox_rect.x1;
+                doc_rect.y1 = end.y - cropbox_rect.y1;
                 doc_rect.x2 = doc_rect.x1 + ANNOTATION_ICON_SIZE;
                 doc_rect.y2 = doc_rect.y1 + ANNOTATION_ICON_SIZE;
                 annot = ev_annotation_text_new (page);
                 break;
        case EV_ANNOTATION_TYPE_TEXT_MARKUP:
-               doc_rect.x1 = start.x;
-               doc_rect.y1 = start.y;
-               doc_rect.x2 = end.x;
-               doc_rect.y2 = end.y;
+               doc_rect.x1 = start.x + cropbox_rect.x1;
+               doc_rect.y1 = start.y - cropbox_rect.y1;
+               doc_rect.x2 = end.x + cropbox_rect.x1;
+               doc_rect.y2 = end.y - cropbox_rect.y1;
                annot = ev_annotation_text_markup_highlight_new (page);
                break;
        case EV_ANNOTATION_TYPE_ATTACHMENT:
@@ -3480,6 +3482,10 @@ ev_view_create_annotation_real (EvView *view,
        if (!ev_page_cache_get_annot_mapping (view->page_cache, annot_page))
                ev_page_cache_mark_dirty (view->page_cache, annot_page, EV_PAGE_DATA_INCLUDE_ANNOTS);
 
+       doc_rect.x1 -= cropbox_rect.x1;
+       doc_rect.y1 += cropbox_rect.y1;
+       doc_rect.x2 -= cropbox_rect.x1;
+       doc_rect.y2 += cropbox_rect.y1;
        _ev_view_transform_doc_rect_to_view_rect (view, annot_page, &doc_rect, &view_rect);
        view_rect.x -= view->scroll_x;
        view_rect.y -= view->scroll_y;
@@ -5606,11 +5612,13 @@ ev_view_motion_notify_event (GtkWidget      *widget,
                if (view->adding_annot_info.adding_annot) {
                        EvRectangle  rect;
                        EvRectangle  current_area;
+                       EvRectangle  cropbox_rect;
                        EvPoint      start;
                        EvPoint      end;
                        GdkRectangle page_area;
                        GtkBorder    border;
                        guint        annot_page;
+                       EvPage      *page;
 
                        if (!view->adding_annot_info.annot)
                                return TRUE;
@@ -5625,19 +5633,21 @@ ev_view_motion_notify_event (GtkWidget      *widget,
                                                                    &start.x, &start.y);
                        _ev_view_transform_view_point_to_doc_point (view, &view->adding_annot_info.stop, 
&page_area, &border,
                                                                    &end.x, &end.y);
+                       page = ev_document_get_page (view->document, annot_page);
+                       ev_document_get_page_crop_box (view->document, page, &cropbox_rect);
 
                        switch (view->adding_annot_info.type) {
                        case EV_ANNOTATION_TYPE_TEXT:
-                               rect.x1 = end.x;
-                               rect.y1 = end.y;
+                               rect.x1 = end.x + cropbox_rect.x1;
+                               rect.y1 = end.y - cropbox_rect.y1;
                                rect.x2 = rect.x1 + current_area.x2 - current_area.x1;
                                rect.y2 = rect.y1 + current_area.y2 - current_area.y1;
                                break;
                        case EV_ANNOTATION_TYPE_TEXT_MARKUP:
-                               rect.x1 = start.x;
-                               rect.y1 = start.y;
-                               rect.x2 = end.x;
-                               rect.y2 = end.y;
+                               rect.x1 = start.x + cropbox_rect.x1;
+                               rect.y1 = start.y - cropbox_rect.y1;
+                               rect.x2 = end.x + cropbox_rect.x1;
+                               rect.y2 = end.y - cropbox_rect.y1;
                                break;
                        default:
                                g_assert_not_reached ();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]