[evince/gpoo/fix-hover-for-highlight-annotations: 2/3] libdocument, pdf: adding method is_xy_in_annotation
- From: Germán Poo-Caamaño <gpoo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince/gpoo/fix-hover-for-highlight-annotations: 2/3] libdocument, pdf: adding method is_xy_in_annotation
- Date: Sun, 9 Feb 2020 12:53:31 +0000 (UTC)
commit 779fe92b34200219354f0bac133014e1d538d1b2
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.
https://bugzilla.gnome.org/show_bug.cgi?id=769133
backend/pdf/ev-poppler.cc | 86 +++++++++++++++++++++++++++++++++++
libdocument/ev-document-annotations.c | 11 +++++
libdocument/ev-document-annotations.h | 8 ++++
3 files changed, 105 insertions(+)
---
diff --git a/backend/pdf/ev-poppler.cc b/backend/pdf/ev-poppler.cc
index a6383a15..c5b35b0d 100644
--- a/backend/pdf/ev-poppler.cc
+++ b/backend/pdf/ev-poppler.cc
@@ -3921,6 +3921,91 @@ pdf_document_annotations_save_annotation (EvDocumentAnnotations *document_annota
ev_document_set_modified (EV_DOCUMENT (document_annotations), 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)
{
@@ -3929,6 +4014,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;
}
/* Media */
diff --git a/libdocument/ev-document-annotations.c b/libdocument/ev-document-annotations.c
index 96ce4f6c..56c3cec8 100644
--- a/libdocument/ev-document-annotations.c
+++ b/libdocument/ev-document-annotations.c
@@ -91,3 +91,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 36ec65ab..b3bb7f43 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;
@@ -102,6 +106,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]