[evince/wip/highlight: 53/59] libdocument, pdf: adding method is_xy_in_annotation



commit eb428d20d9ec5d999d21c71bc05972894421d487
Author: Giselle Reis <gisellemnr src gnome org>
Date:   Mon Aug 18 20:54:47 2014 +0200

    libdocument, pdf: adding method is_xy_in_annotation
    
    Added the method is_xy_in_annotation to the
    interface of document-annotations. It intends to
    check if a point (x,y) is inside the annotation's
    quadrilaterals (and not its bounding box, which
    can be checked using the EvMapping).
    Also implements the function in the pdf back-end.

 backend/pdf/ev-poppler.cc             |   86 +++++++++++++++++++++++++++++++++
 libdocument/ev-document-annotations.c |   11 ++++
 libdocument/ev-document-annotations.h |    8 +++
 3 files changed, 105 insertions(+), 0 deletions(-)
---
diff --git a/backend/pdf/ev-poppler.cc b/backend/pdf/ev-poppler.cc
index d795b8e..e34808f 100644
--- a/backend/pdf/ev-poppler.cc
+++ b/backend/pdf/ev-poppler.cc
@@ -3358,6 +3358,91 @@ pdf_document_annotations_save_annotation (EvDocumentAnnotations *document_annota
        PDF_DOCUMENT (document_annotations)->annots_modified = TRUE;
 }
 
+static gboolean
+pdf_document_annotations_is_xy_in_annotation (EvDocumentAnnotations *document_annots,
+                                             EvAnnotation          *annot,
+                                             gdouble                x,
+                                             gdouble                y)
+{
+       PopplerAnnot *poppler_annot;
+       EvPage       *page;
+       PopplerPage  *poppler_page;
+       gdouble       height;
+       gdouble       poppler_y;
+
+       page = ev_annotation_get_page (annot);
+       poppler_page = POPPLER_PAGE (page->backend_page);
+       poppler_page_get_size (poppler_page, NULL, &height);
+       poppler_y = height - y;
+       poppler_annot = POPPLER_ANNOT (g_object_get_data (G_OBJECT (annot), "poppler-annot"));
+
+       if (EV_IS_ANNOTATION_TEXT_MARKUP (annot)) {
+               GArray *quads;
+               guint   i;
+
+               quads = poppler_annot_text_markup_get_quadrilaterals (POPPLER_ANNOT_TEXT_MARKUP 
(poppler_annot));
+
+               for (i = 0; i < quads->len; i++) {
+                       PopplerQuadrilateral *q;
+                       gdouble               area_triangles;
+                       gdouble               area_quad;
+                       gdouble               x1, y1, x2, y2, x3, y3, x4, y4;
+
+                       x1 = x;
+                       y1 = poppler_y;
+                       area_triangles = 0;
+                       q = &g_array_index (quads, PopplerQuadrilateral, i);
+
+                       x2 = q->p1.x;
+                       y2 = q->p1.y;
+                       x3 = q->p2.x;
+                       y3 = q->p2.y;
+                       area_triangles += ABS (x1*(y2 - y3) + x2*(y3 - y1) + x3*(y1 - y2)) / 2;
+
+                       x2 = q->p2.x;
+                       y2 = q->p2.y;
+                       x3 = q->p4.x;
+                       y3 = q->p4.y;
+                       area_triangles += ABS (x1*(y2 - y3) + x2*(y3 - y1) + x3*(y1 - y2)) / 2;
+
+                       x2 = q->p4.x;
+                       y2 = q->p4.y;
+                       x3 = q->p3.x;
+                       y3 = q->p3.y;
+                       area_triangles += ABS (x1*(y2 - y3) + x2*(y3 - y1) + x3*(y1 - y2)) / 2;
+
+                       x2 = q->p3.x;
+                       y2 = q->p3.y;
+                       x3 = q->p1.x;
+                       y3 = q->p1.y;
+                       area_triangles += ABS (x1*(y2 - y3) + x2*(y3 - y1) + x3*(y1 - y2)) / 2;
+
+                       x1 = q->p1.x;
+                       y1 = q->p1.y;
+                       x2 = q->p2.x;
+                       y2 = q->p2.y;
+                       x3 = q->p4.x;
+                       y3 = q->p4.y;
+                       x4 = q->p3.x;
+                       y4 = q->p3.y;
+                       area_quad = ABS ((x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y4 - y3*x4) + (x4*y1 - 
y4*x1)) / 2;
+
+                       if (ABS (area_triangles - area_quad) < 0.0001)
+                               return TRUE;
+               }
+               g_array_unref (quads);
+
+               return FALSE;
+       } else {
+               /* Check only the rectangle, which should be true */
+               PopplerRectangle rect;
+
+               poppler_annot_get_rectangle (poppler_annot, &rect);
+
+               return rect.x1 <= x && rect.x2 >= x && rect.y1 <= poppler_y && rect.y2 >= poppler_y;
+       }
+}
+
 static void
 pdf_document_document_annotations_iface_init (EvDocumentAnnotationsInterface *iface)
 {
@@ -3366,6 +3451,7 @@ pdf_document_document_annotations_iface_init (EvDocumentAnnotationsInterface *if
        iface->add_annotation = pdf_document_annotations_add_annotation;
        iface->save_annotation = pdf_document_annotations_save_annotation;
        iface->remove_annotation = pdf_document_annotations_remove_annotation;
+       iface->is_xy_in_annotation = pdf_document_annotations_is_xy_in_annotation;
 }
 
 /* Attachments */
diff --git a/libdocument/ev-document-annotations.c b/libdocument/ev-document-annotations.c
index cdf1ea8..10891af 100644
--- a/libdocument/ev-document-annotations.c
+++ b/libdocument/ev-document-annotations.c
@@ -92,3 +92,14 @@ ev_document_annotations_can_remove_annotation (EvDocumentAnnotations *document_a
 
        return iface->remove_annotation != NULL;
 }
+
+gboolean
+ev_document_annotations_is_xy_in_annotation (EvDocumentAnnotations *document_annots,
+                                            EvAnnotation          *annot,
+                                            gdouble                x,
+                                            gdouble                y)
+{
+       EvDocumentAnnotationsInterface *iface = EV_DOCUMENT_ANNOTATIONS_GET_IFACE (document_annots);
+
+       return iface->is_xy_in_annotation (document_annots, annot, x, y);
+}
diff --git a/libdocument/ev-document-annotations.h b/libdocument/ev-document-annotations.h
index de41c4d..73a24c6 100644
--- a/libdocument/ev-document-annotations.h
+++ b/libdocument/ev-document-annotations.h
@@ -85,6 +85,10 @@ struct _EvDocumentAnnotationsInterface
                                                 EvAnnotationsSaveMask  mask);
        void           (* remove_annotation)    (EvDocumentAnnotations *document_annots,
                                                 EvAnnotation          *annot);
+       gboolean       (* is_xy_in_annotation)  (EvDocumentAnnotations *document_annots,
+                                                EvAnnotation          *annot,
+                                                gdouble                x,
+                                                gdouble                y);
 };
 
 GType          ev_document_annotations_get_type             (void) G_GNUC_CONST;
@@ -103,6 +107,10 @@ void           ev_document_annotations_save_annotation      (EvDocumentAnnotatio
                                                             EvAnnotationsSaveMask  mask);
 gboolean       ev_document_annotations_can_add_annotation    (EvDocumentAnnotations *document_annots);
 gboolean       ev_document_annotations_can_remove_annotation (EvDocumentAnnotations *document_annots);
+gboolean       ev_document_annotations_is_xy_in_annotation   (EvDocumentAnnotations *document_annots,
+                                                             EvAnnotation          *annot,
+                                                             gdouble                x,
+                                                             gdouble                y);
 
 G_END_DECLS
 


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