Hi,

On 19.03.2014 00:04, Thomas Liebetraut wrote:
> Anyway, I don't want to open this can of worms, so I'll follow my second
> proposal and add EvAnnotation* classes that correspond to the
> annotations supported by poppler 0.24 without trying to be smart about
> them and try to combine them to simpler "abstract" annotation types
> (like line, polygon and rect/circle annotations are all some sort of
> geometry annotation).

Well, I digressed from this statement in the case of text markup
annotations, having only one class to implement them (but different _new
functions to set the appropriate annotation type).

Other than that, the 6 attached patches implement an EvQuadrilateral
boxed type and a EvAnnotationTextMarkup class that makes use of it. The
last two patches finally implement highlight and strikethrough
annotations in the pdf backend and thus would close
<https://bugzilla.gnome.org/show_bug.cgi?id=583377>.

Should I also attach these patches (even the first three which are only
infrastructure?) to this bug?

The patches require the latest libpoppler-glib master -- more precisely
they require this commit:
<http://cgit.freedesktop.org/poppler/poppler/commit/?id=ac3c8303396a0b8de5e4ad32f480b8da5f3b396e>.


Thomas
# HG changeset patch
# User Thomas Liebetraut <[email protected]>
# Date 1396178635 -7200
#      Sun Mar 30 13:23:55 2014 +0200
# Node ID b8bcc5b4217c48ebe222ef43e53d93be1e617818
# Parent  6de33897d991bca633e43af6a01fcba927350762
Add bounding-rectangle property to EvAnnotation

This allows an EvAnnotation to know its location on the page.

diff -r 6de33897d991 -r b8bcc5b4217c backend/pdf/ev-poppler.cc
--- a/backend/pdf/ev-poppler.cc	Fri Mar 28 19:31:08 2014 +0000
+++ b/backend/pdf/ev-poppler.cc	Sun Mar 30 13:23:55 2014 +0200
@@ -2930,6 +2930,9 @@
 		gchar   *contents;
 		gchar   *name;
 		GdkColor color;
+		gdouble page_height;
+		EvRectangle ev_bound_rect;
+		PopplerRectangle poppler_rect;
 
 		contents = poppler_annot_get_contents (poppler_annot);
 		if (contents) {
@@ -2954,6 +2957,18 @@
 		poppler_annot_color_to_gdk_color (poppler_annot, &color);
 		ev_annotation_set_color (ev_annot, &color);
 
+		poppler_page_get_size (POPPLER_PAGE (page->backend_page),
+				       NULL, &page_height);
+		poppler_annot_get_rectangle(poppler_annot, &poppler_rect);
+		ev_bound_rect.x1 = poppler_rect.x1;
+		ev_bound_rect.x2 = poppler_rect.x2;
+		ev_bound_rect.y1 = page_height - poppler_rect.y2;
+		ev_bound_rect.y2 = page_height - poppler_rect.y1;
+		g_object_set(ev_annot,
+		             "bounding-rectangle", &ev_bound_rect,
+		             NULL);
+
+
 		if (POPPLER_IS_ANNOT_MARKUP (poppler_annot)) {
 			PopplerAnnotMarkup *markup;
 			gchar *label;
@@ -2965,14 +2980,11 @@
 			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),
-						       NULL, &height);
+
 				ev_rect.x1 = poppler_rect.x1;
 				ev_rect.x2 = poppler_rect.x2;
-				ev_rect.y1 = height - poppler_rect.y2;
-				ev_rect.y2 = height - poppler_rect.y1;
+				ev_rect.y1 = page_height - poppler_rect.y2;
+				ev_rect.y2 = page_height - poppler_rect.y1;
 
 				is_open = poppler_annot_markup_get_popup_is_open (markup);
 
@@ -3050,10 +3062,8 @@
 		}
 
 		annot_mapping = g_new (EvMapping, 1);
-		annot_mapping->area.x1 = mapping->area.x1;
-		annot_mapping->area.x2 = mapping->area.x2;
-		annot_mapping->area.y1 = height - mapping->area.y2;
-		annot_mapping->area.y2 = height - mapping->area.y1;
+		ev_annotation_get_bounding_rectangle(ev_annot,
+		                                     &annot_mapping->area);
 		annot_mapping->data = ev_annot;
 
 		g_object_set_data_full (G_OBJECT (ev_annot),
diff -r 6de33897d991 -r b8bcc5b4217c libdocument/ev-annotation.c
--- a/libdocument/ev-annotation.c	Fri Mar 28 19:31:08 2014 +0000
+++ b/libdocument/ev-annotation.c	Sun Mar 30 13:23:55 2014 +0200
@@ -35,6 +35,7 @@
 	gchar           *name;
 	gchar           *modified;
 	GdkRGBA          rgba;
+	EvRectangle      rect;
 };
 
 struct _EvAnnotationClass {
@@ -78,7 +79,8 @@
 	PROP_ANNOT_NAME,
 	PROP_ANNOT_MODIFIED,
 	PROP_ANNOT_COLOR,
-        PROP_ANNOT_RGBA
+        PROP_ANNOT_RGBA,
+        PROP_ANNOT_BOUND_RECT
 };
 
 /* EvAnnotationMarkup */
@@ -177,6 +179,9 @@
         case PROP_ANNOT_RGBA:
                 ev_annotation_set_rgba (annot, g_value_get_boxed (value));
                 break;
+        case PROP_ANNOT_BOUND_RECT:
+        	ev_annotation_set_bounding_rectangle (annot, g_value_get_boxed (value));
+        	break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 	}
@@ -210,6 +215,9 @@
         case PROP_ANNOT_RGBA:
                 g_value_set_boxed (value, &annot->rgba);
                 break;
+        case PROP_ANNOT_BOUND_RECT:
+        	g_value_set_boxed (value, &annot->rect);
+        	break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 	}
@@ -284,6 +292,22 @@
                                                              GDK_TYPE_RGBA,
                                                              G_PARAM_READWRITE |
                                                              G_PARAM_STATIC_STRINGS));
+
+        /**
+         * EvAnnotation:bounding-rectangle:
+         *
+         * The bounding rectangle of the annotation within the page as a #EvRectangle.
+         *
+         * Since: 3.6
+         */
+        g_object_class_install_property (g_object_class,
+                                         PROP_ANNOT_BOUND_RECT,
+                                         g_param_spec_boxed ("bounding-rectangle",
+                                                             "Bounding rectangle",
+                                                             "The bounding rectangle of the annotation",
+                                                             EV_TYPE_RECTANGLE,
+                                                             G_PARAM_READWRITE |
+                                                             G_PARAM_STATIC_STRINGS));
 }
 
 EvAnnotationType
@@ -631,6 +655,35 @@
         return TRUE;
 }
 
+void
+ev_annotation_get_bounding_rectangle (EvAnnotation *annot,
+				      EvRectangle  *rect)
+{
+	g_return_if_fail (EV_IS_ANNOTATION (annot));
+	g_return_if_fail (rect != NULL);
+
+	*rect = annot->rect;
+}
+
+gboolean
+ev_annotation_set_bounding_rectangle (EvAnnotation      *annot,
+				      const EvRectangle *rect)
+{
+	g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
+	g_return_val_if_fail (rect != NULL, FALSE);
+
+	if (annot->rect.x1 == rect->x1 &&
+	    annot->rect.y1 == rect->y1 &&
+	    annot->rect.x2 == rect->x2 &&
+	    annot->rect.y2 == rect->y2)
+		return FALSE;
+
+        annot->rect = *rect;
+        g_object_notify (G_OBJECT (annot), "bounding_rectangle");
+
+        return TRUE;
+}
+
 /* EvAnnotationMarkup */
 typedef struct {
 	gchar   *label;
diff -r 6de33897d991 -r b8bcc5b4217c libdocument/ev-annotation.h
--- a/libdocument/ev-annotation.h	Fri Mar 28 19:31:08 2014 +0000
+++ b/libdocument/ev-annotation.h	Sun Mar 30 13:23:55 2014 +0200
@@ -125,6 +125,10 @@
                                                               GdkRGBA                *rgba);
 gboolean             ev_annotation_set_rgba                  (EvAnnotation           *annot,
                                                               const GdkRGBA          *rgba);
+void                 ev_annotation_get_bounding_rectangle    (EvAnnotation           *annot,
+                                                              EvRectangle            *rect);
+gboolean             ev_annotation_set_bounding_rectangle    (EvAnnotation           *annot,
+                                                              const EvRectangle      *rect);
 
 /* EvAnnotationMarkup */
 GType                ev_annotation_markup_get_type           (void) G_GNUC_CONST;
diff -r 6de33897d991 -r b8bcc5b4217c libview/ev-view.c
--- a/libview/ev-view.c	Fri Mar 28 19:31:08 2014 +0000
+++ b/libview/ev-view.c	Sun Mar 30 13:23:55 2014 +0200
@@ -3119,6 +3119,7 @@
 	g_object_unref (page);
 
 	ev_annotation_set_color (annot, &color);
+	ev_annotation_set_bounding_rectangle(annot, &doc_rect);
 
 	if (EV_IS_ANNOTATION_MARKUP (annot)) {
 		popup_rect.x1 = doc_rect.x2;
# HG changeset patch
# User Thomas Liebetraut <[email protected]>
# Date 1396178635 -7200
#      Sun Mar 30 13:23:55 2014 +0200
# Node ID b57f18696badeb88f1032db9e2dd2b577d606b0d
# Parent  b8bcc5b4217c48ebe222ef43e53d93be1e617818
Add support for interactive areas in annotations.

Some annotation types do not have a rectangular shape
and require non-rectangular boundary checks to determine
if the user clicked on them.

A new method ev_annotation_is_location_in_area() is added
that determines whether a point location is actually
inside the annotation's interactive area.

diff -r b8bcc5b4217c -r b57f18696bad libdocument/ev-annotation.c
--- a/libdocument/ev-annotation.c	Sun Mar 30 13:23:55 2014 +0200
+++ b/libdocument/ev-annotation.c	Sun Mar 30 13:23:55 2014 +0200
@@ -40,6 +40,10 @@
 
 struct _EvAnnotationClass {
 	GObjectClass parent_class;
+
+	gboolean (* is_location_in_area) (EvAnnotation *annot,
+			                  gdouble       x,
+			                  gdouble       y);
 };
 
 struct _EvAnnotationMarkupInterface {
@@ -152,6 +156,26 @@
 	annot->type = EV_ANNOTATION_TYPE_UNKNOWN;
 }
 
+static gboolean
+ev_annotation_impl_is_location_in_area (EvAnnotation *annot,
+				   gdouble       x,
+				   gdouble       y)
+{
+        g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
+
+        /* fall back to bound rectangle */
+	EvRectangle rect;
+	ev_annotation_get_bounding_rectangle (annot, &rect);
+	if ((x >= rect.x1) &&
+	    (x <= rect.x2) &&
+	    (y >= rect.y1) &&
+	    (y <= rect.y2)) {
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
 static void
 ev_annotation_set_property (GObject      *object,
 			    guint         prop_id,
@@ -228,6 +252,8 @@
 {
 	GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
 
+	klass->is_location_in_area = ev_annotation_impl_is_location_in_area;
+
 	g_object_class->finalize = ev_annotation_finalize;
 	g_object_class->set_property = ev_annotation_set_property;
 	g_object_class->get_property = ev_annotation_get_property;
@@ -684,6 +710,19 @@
         return TRUE;
 }
 
+gboolean
+ev_annotation_is_location_in_area (EvAnnotation *annot,
+				   gdouble       x,
+				   gdouble       y)
+{
+	g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
+
+	EvAnnotationClass *klass = EV_ANNOTATION_GET_CLASS (annot);
+
+	return klass->is_location_in_area (annot, x, y);
+}
+
+
 /* EvAnnotationMarkup */
 typedef struct {
 	gchar   *label;
diff -r b8bcc5b4217c -r b57f18696bad libdocument/ev-annotation.h
--- a/libdocument/ev-annotation.h	Sun Mar 30 13:23:55 2014 +0200
+++ b/libdocument/ev-annotation.h	Sun Mar 30 13:23:55 2014 +0200
@@ -129,6 +129,9 @@
                                                               EvRectangle            *rect);
 gboolean             ev_annotation_set_bounding_rectangle    (EvAnnotation           *annot,
                                                               const EvRectangle      *rect);
+gboolean             ev_annotation_is_location_in_area       (EvAnnotation           *annot,
+                                                              gdouble                 x,
+                                                              gdouble                 y);
 
 /* EvAnnotationMarkup */
 GType                ev_annotation_markup_get_type           (void) G_GNUC_CONST;
diff -r b8bcc5b4217c -r b57f18696bad libdocument/ev-mapping-list.c
--- a/libdocument/ev-mapping-list.c	Sun Mar 30 13:23:55 2014 +0200
+++ b/libdocument/ev-mapping-list.c	Sun Mar 30 13:23:55 2014 +0200
@@ -19,6 +19,7 @@
  */
 
 #include "ev-mapping-list.h"
+#include "ev-annotation.h"
 
 /**
  * SECTION: ev-mapping-list
@@ -121,10 +122,15 @@
 	for (list = mapping_list->list; list; list = list->next) {
 		EvMapping *mapping = list->data;
 
-		if ((x >= mapping->area.x1) &&
-		    (y >= mapping->area.y1) &&
-		    (x <= mapping->area.x2) &&
-		    (y <= mapping->area.y2)) {
+		if (EV_IS_ANNOTATION(mapping->data)) {
+			if (ev_annotation_is_location_in_area (
+					EV_ANNOTATION(mapping->data), x, y)) {
+				return mapping;
+			}
+		} else if ((x >= mapping->area.x1) &&
+			   (y >= mapping->area.y1) &&
+			   (x <= mapping->area.x2) &&
+			   (y <= mapping->area.y2)) {
 			return mapping;
 		}
 	}
# HG changeset patch
# User Thomas Liebetraut <[email protected]>
# Date 1396178635 -7200
#      Sun Mar 30 13:23:55 2014 +0200
# Node ID eee239b048d4aca26cf7b59bba4a5cafd4dfb3a4
# Parent  b57f18696badeb88f1032db9e2dd2b577d606b0d
Add EvQuadrilateral type required for text markup annotations.

EvQuadrilateral is a simple boxed type containing 4 EvPoints
that constitute the corners of a quadrilateral.
PDF markup annotations make use of this structure to define
an annotation's active area.

diff -r b57f18696bad -r eee239b048d4 libdocument/ev-annotation.c
--- a/libdocument/ev-annotation.c	Sun Mar 30 13:23:55 2014 +0200
+++ b/libdocument/ev-annotation.c	Sun Mar 30 13:23:55 2014 +0200
@@ -1322,3 +1322,31 @@
 
 	return TRUE;
 }
+
+/* EvQuadrilateral */
+G_DEFINE_BOXED_TYPE (EvQuadrilateral, ev_quadrilateral, ev_quadrilateral_copy, ev_quadrilateral_free)
+
+EvQuadrilateral*
+ev_quadrilateral_new (void)
+{
+	return g_new0 (EvQuadrilateral, 1);
+}
+
+EvQuadrilateral*
+ev_quadrilateral_copy (EvQuadrilateral* quad)
+{
+	EvQuadrilateral *new_quad;
+
+	g_return_val_if_fail (quad != NULL, NULL);
+
+	new_quad = g_new (EvQuadrilateral, 1);
+	*new_quad = *quad;
+
+	return new_quad;
+}
+
+void
+ev_quadrilateral_free (EvQuadrilateral* quad)
+{
+	g_free (quad);
+}
diff -r b57f18696bad -r eee239b048d4 libdocument/ev-annotation.h
--- a/libdocument/ev-annotation.h	Sun Mar 30 13:23:55 2014 +0200
+++ b/libdocument/ev-annotation.h	Sun Mar 30 13:23:55 2014 +0200
@@ -34,6 +34,25 @@
 
 G_BEGIN_DECLS
 
+/* EvQuadrilateral */
+#define EV_TYPE_QUADRILATERAL                   (ev_quadrilateral_get_type ())
+
+typedef struct _EvQuadrilateral EvQuadrilateral;
+
+struct _EvQuadrilateral
+{
+	EvPoint p1;
+	EvPoint p2;
+	EvPoint p3;
+	EvPoint p4;
+};
+
+GType            ev_quadrilateral_get_type (void) G_GNUC_CONST;
+EvQuadrilateral *ev_quadrilateral_new      (void);
+EvQuadrilateral *ev_quadrilateral_copy     (EvQuadrilateral *quad);
+void             ev_quadrilateral_free     (EvQuadrilateral *quad);
+
+
 /* EvAnnotation */
 #define EV_TYPE_ANNOTATION                      (ev_annotation_get_type())
 #define EV_ANNOTATION(object)                   (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_ANNOTATION, EvAnnotation))
# HG changeset patch
# User Thomas Liebetraut <[email protected]>
# Date 1396195767 -7200
#      Sun Mar 30 18:09:27 2014 +0200
# Node ID 48de07d940ed928d89b67b4d47bc53b8adb65622
# Parent  eee239b048d4aca26cf7b59bba4a5cafd4dfb3a4
Add EvAnnotationTextMarkup class.

This base class should be used for all text markup
annotations like text highlighting, underlining, etc.

diff -r eee239b048d4 -r 48de07d940ed libdocument/ev-annotation.c
--- a/libdocument/ev-annotation.c	Sun Mar 30 13:23:55 2014 +0200
+++ b/libdocument/ev-annotation.c	Sun Mar 30 18:09:27 2014 +0200
@@ -71,9 +71,20 @@
 	EvAnnotationClass parent_class;
 };
 
-static void ev_annotation_markup_default_init          (EvAnnotationMarkupInterface *iface);
-static void ev_annotation_text_markup_iface_init       (EvAnnotationMarkupInterface *iface);
-static void ev_annotation_attachment_markup_iface_init (EvAnnotationMarkupInterface *iface);
+struct _EvAnnotationTextMarkup {
+	EvAnnotation parent;
+
+	GArray *quadrilaterals;
+};
+
+struct _EvAnnotationTextMarkupClass {
+	EvAnnotationClass parent_class;
+};
+
+static void ev_annotation_markup_default_init           (EvAnnotationMarkupInterface *iface);
+static void ev_annotation_text_markup_iface_init        (EvAnnotationMarkupInterface *iface);
+static void ev_annotation_attachment_markup_iface_init  (EvAnnotationMarkupInterface *iface);
+static void ev_annotation_text_markup_markup_iface_init (EvAnnotationMarkupInterface *iface);
 
 /* EvAnnotation */
 enum {
@@ -108,6 +119,11 @@
 	PROP_ATTACHMENT_ATTACHMENT = PROP_MARKUP_POPUP_IS_OPEN + 1
 };
 
+/* EvAnnotationTextMarkup */
+enum {
+	PROP_TEXT_MARKUP_QUADRILATERALS = PROP_MARKUP_POPUP_IS_OPEN + 1
+};
+
 G_DEFINE_ABSTRACT_TYPE (EvAnnotation, ev_annotation, G_TYPE_OBJECT)
 G_DEFINE_INTERFACE (EvAnnotationMarkup, ev_annotation_markup, EV_TYPE_ANNOTATION)
 G_DEFINE_TYPE_WITH_CODE (EvAnnotationText, ev_annotation_text, EV_TYPE_ANNOTATION,
@@ -121,6 +137,12 @@
 					ev_annotation_attachment_markup_iface_init);
 	 });
 
+G_DEFINE_TYPE_WITH_CODE (EvAnnotationTextMarkup, ev_annotation_text_markup, EV_TYPE_ANNOTATION,
+	 {
+		 G_IMPLEMENT_INTERFACE (EV_TYPE_ANNOTATION_MARKUP,
+					ev_annotation_text_markup_markup_iface_init);
+	 });
+
 /* EvAnnotation */
 static void
 ev_annotation_finalize (GObject *object)
@@ -1350,3 +1372,182 @@
 {
 	g_free (quad);
 }
+
+/* EvAnnotationTextMarkup */
+static void
+ev_annotation_text_markup_finalize (GObject *object)
+{
+	EvAnnotationTextMarkup *annot = EV_ANNOTATION_TEXT_MARKUP (object);
+
+	if (annot->quadrilaterals) {
+		g_object_unref(annot->quadrilaterals);
+		annot->quadrilaterals = NULL;
+	}
+}
+
+static void
+ev_annotation_text_markup_init (EvAnnotationTextMarkup *annot)
+{
+	annot->quadrilaterals = g_array_new(FALSE, TRUE, sizeof(EvQuadrilateral));
+}
+
+static gboolean
+ev_annotation_text_markup_impl_is_location_in_area (EvAnnotation *annot,
+						    gdouble       x,
+						    gdouble       y)
+{
+	EvAnnotationTextMarkup *tm_annot = EV_ANNOTATION_TEXT_MARKUP (annot);
+	EvAnnotationClass *p_class;
+	gboolean in_bounding_rect = FALSE;
+	GArray *quadrilaterals = NULL;
+
+	p_class = EV_ANNOTATION_CLASS (ev_annotation_text_markup_parent_class);
+	in_bounding_rect = p_class->is_location_in_area (annot, x, y);
+	if (!in_bounding_rect) {
+		return FALSE;
+	}
+
+	quadrilaterals = tm_annot->quadrilaterals;
+	if (quadrilaterals->len == 0) {
+		return TRUE;
+	} else {
+		int i;
+		for (i = 0; i < quadrilaterals->len; ++i) {
+			EvQuadrilateral quad = g_array_index(quadrilaterals,
+							     EvQuadrilateral,
+							     i);
+			/*
+			 * This only works for convex quadrilaterals!
+			 *
+			 * The coordinates within a quadrilateral are
+			 * defined counter-clockwise.
+			 * If the point x,y is on the left of each edge of
+			 * the quadrilateral, the point is inside the
+			 * quadrilateral.
+			 *
+			 * To test if the point P is left of a line from
+			 * A to B, first translate A and B by -P (to make
+			 * P the new point of origin).
+			 * Then consider the angle alpha between A and B:
+			 * if sin(alpha) >= 0 then the point/origin is
+			 * left of the line AB.
+			 *
+			 * 0 <= sin(alpha) = -cos(alpha + pi/2) ~ -dotP(A',B'')
+			 * where A'=A-P, B'=B-P and B''=B' rotated by pi/2.
+			 *
+			 * Note that for these calculations evince's
+			 * coordinate system is flipped vertically
+			 * (y-axis downwards)!
+			 */
+			if (((quad.p2.x - x) * (quad.p1.y - y) - (quad.p1.x - x) * (quad.p2.y - y) >= 0) &&
+			    ((quad.p3.x - x) * (quad.p2.y - y) - (quad.p2.x - x) * (quad.p3.y - y) >= 0) &&
+			    ((quad.p4.x - x) * (quad.p3.y - y) - (quad.p3.x - x) * (quad.p4.y - y) >= 0) &&
+			    ((quad.p1.x - x) * (quad.p4.y - y) - (quad.p4.x - x) * (quad.p1.y - y) >= 0)) {
+				return TRUE;
+			}
+		}
+	}
+	return FALSE;
+}
+
+static void
+ev_annotation_text_markup_set_property (GObject      *object,
+				        guint         prop_id,
+				        const GValue *value,
+				        GParamSpec   *pspec)
+{
+	EvAnnotationTextMarkup *annot = EV_ANNOTATION_TEXT_MARKUP (object);
+
+	if (prop_id < PROP_TEXT_MARKUP_QUADRILATERALS) {
+		ev_annotation_markup_set_property (object, prop_id, value, pspec);
+		return;
+	}
+
+	switch (prop_id) {
+	case PROP_TEXT_MARKUP_QUADRILATERALS:
+		ev_annotation_text_markup_set_quadrilaterals (annot,
+		                                              g_value_get_boxed (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	}
+}
+
+static void
+ev_annotation_text_markup_get_property (GObject    *object,
+				        guint       prop_id,
+				        GValue     *value,
+				        GParamSpec *pspec)
+{
+	EvAnnotationTextMarkup *annot = EV_ANNOTATION_TEXT_MARKUP (object);
+
+	if (prop_id < PROP_TEXT_MARKUP_QUADRILATERALS) {
+		ev_annotation_markup_get_property (object, prop_id, value, pspec);
+		return;
+	}
+
+	switch (prop_id) {
+	case PROP_TEXT_MARKUP_QUADRILATERALS:
+		g_value_take_boxed(value, ev_annotation_text_markup_get_quadrilaterals(annot));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	}
+}
+
+static void
+ev_annotation_text_markup_class_init (EvAnnotationTextMarkupClass *klass)
+{
+	GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
+	EvAnnotationClass *ev_annotation_class = EV_ANNOTATION_CLASS (klass);
+
+	ev_annotation_markup_class_install_properties (g_object_class);
+
+	g_object_class->finalize = ev_annotation_text_markup_finalize;
+	g_object_class->set_property = ev_annotation_text_markup_set_property;
+	g_object_class->get_property = ev_annotation_text_markup_get_property;
+
+	ev_annotation_class->is_location_in_area = ev_annotation_text_markup_impl_is_location_in_area;
+
+	g_object_class_install_property (g_object_class,
+					 PROP_TEXT_MARKUP_QUADRILATERALS,
+					 g_param_spec_boxed ("quadrilaterals",
+							     "Quadrilaterlas",
+							     "The quadrilaterals of the annotation",
+							     G_TYPE_ARRAY,
+							     G_PARAM_READWRITE |
+                                                             G_PARAM_STATIC_STRINGS));
+}
+
+static void
+ev_annotation_text_markup_markup_iface_init (EvAnnotationMarkupInterface *iface)
+{
+}
+
+GArray*
+ev_annotation_text_markup_get_quadrilaterals (EvAnnotationTextMarkup* annot)
+{
+	GArray *result = g_array_sized_new (FALSE, FALSE,
+					    sizeof(EvQuadrilateral),
+					    annot->quadrilaterals->len);
+	g_array_append_vals (result, annot->quadrilaterals->data,
+			     annot->quadrilaterals->len);
+
+	return result;
+}
+
+gboolean
+ev_annotation_text_markup_set_quadrilaterals (EvAnnotationTextMarkup *annot,
+                                              GArray *arr)
+{
+	g_return_val_if_fail(arr != NULL, FALSE);
+	g_return_val_if_fail(arr->len > 0, FALSE);
+
+	if (annot->quadrilaterals->len)
+		g_array_remove_range (annot->quadrilaterals, 0, annot->quadrilaterals->len);
+
+	g_array_append_vals (annot->quadrilaterals, arr->data, arr->len);
+
+	return TRUE;
+}
+
diff -r eee239b048d4 -r 48de07d940ed libdocument/ev-annotation.h
--- a/libdocument/ev-annotation.h	Sun Mar 30 13:23:55 2014 +0200
+++ b/libdocument/ev-annotation.h	Sun Mar 30 18:09:27 2014 +0200
@@ -85,6 +85,15 @@
 #define EV_IS_ANNOTATION_ATTACHMENT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_ANNOTATION_ATTACHMENT))
 #define EV_ANNOTATION_ATTACHMENT_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_ANNOTATION_ATTACHMENT, EvAnnotationAttachmentClass))
 
+/* EvAnnotationTextMarkup */
+#define EV_TYPE_ANNOTATION_TEXT_MARKUP              (ev_annotation_text_markup_get_type())
+#define EV_ANNOTATION_TEXT_MARKUP(object)           (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_ANNOTATION_TEXT_MARKUP, EvAnnotationTextMarkup))
+#define EV_ANNOTATION_TEXT_MARKUP_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_ANNOTATION_TEXT_MARKUP, EvAnnotationTextMarkupClass))
+#define EV_IS_ANNOTATION_TEXT_MARKUP(object)        (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_ANNOTATION_TEXT_MARKUP))
+#define EV_IS_ANNOTATION_TEXT_MARKUP_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_ANNOTATION_TEXT_MARKUP))
+#define EV_ANNOTATION_TEXT_MARKUP_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_ANNOTATION_TEXT_MARKUP, EvAnnotationTextMarkupClass))
+
+
 typedef struct _EvAnnotation                EvAnnotation;
 typedef struct _EvAnnotationClass           EvAnnotationClass;
 
@@ -97,6 +106,9 @@
 typedef struct _EvAnnotationAttachment      EvAnnotationAttachment;
 typedef struct _EvAnnotationAttachmentClass EvAnnotationAttachmentClass;
 
+typedef struct _EvAnnotationTextMarkup      EvAnnotationTextMarkup;
+typedef struct _EvAnnotationTextMarkupClass EvAnnotationTextMarkupClass;
+
 typedef enum {
 	EV_ANNOTATION_TYPE_UNKNOWN,
 	EV_ANNOTATION_TYPE_TEXT,
@@ -188,6 +200,12 @@
 EvAttachment        *ev_annotation_attachment_get_attachment (EvAnnotationAttachment *annot);
 gboolean             ev_annotation_attachment_set_attachment (EvAnnotationAttachment *annot,
 							      EvAttachment           *attachment);
+/* EvAnnotationTextMarkup */
+GType                ev_annotation_text_markup_get_type           (void) G_GNUC_CONST;
+GArray              *ev_annotation_text_markup_get_quadrilaterals (EvAnnotationTextMarkup *annot);
+gboolean             ev_annotation_text_markup_set_quadrilaterals (EvAnnotationTextMarkup *annot,
+                                                                   GArray *arr);
+
 
 G_END_DECLS
 
# HG changeset patch
# User Thomas Liebetraut <[email protected]>
# Date 1396196080 -7200
#      Sun Mar 30 18:14:40 2014 +0200
# Node ID 15b1715682fd6d48ea723619431834214e67701d
# Parent  48de07d940ed928d89b67b4d47bc53b8adb65622
Add support for POPPLER_ANNOT_HIGHLIGHT

https://bugzilla.gnome.org/show_bug.cgi?id=583377

diff -r 48de07d940ed -r 15b1715682fd backend/pdf/ev-poppler.cc
--- a/backend/pdf/ev-poppler.cc	Sun Mar 30 18:09:27 2014 +0200
+++ b/backend/pdf/ev-poppler.cc	Sun Mar 30 18:14:40 2014 +0200
@@ -2872,6 +2872,10 @@
 				g_object_unref (poppler_attachment);
 		}
 			break;
+		case POPPLER_ANNOT_HIGHLIGHT: {
+			ev_annot = ev_annotation_text_markup_highlight_new (page);
+		}
+			break;
 	        case POPPLER_ANNOT_LINK:
 	        case POPPLER_ANNOT_WIDGET:
 			/* Ignore link and widgets annots since they are already handled */
@@ -2879,7 +2883,6 @@
 		case POPPLER_ANNOT_3D:
 		case POPPLER_ANNOT_CARET:
 		case POPPLER_ANNOT_FREE_TEXT:
-		case POPPLER_ANNOT_HIGHLIGHT:
 		case POPPLER_ANNOT_LINE:
 		case POPPLER_ANNOT_SCREEN:
 		case POPPLER_ANNOT_SOUND:
@@ -2968,6 +2971,58 @@
 		             "bounding-rectangle", &ev_bound_rect,
 		             NULL);
 
+		if (POPPLER_IS_ANNOT_TEXT_MARKUP (poppler_annot)) {
+			PopplerAnnotTextMarkup *poppler_text_markup;
+			EvAnnotationTextMarkup *ev_annot_text_markup;
+			GArray *poppler_quads = NULL;
+			GArray *ev_quads = NULL;
+			gdouble page_height;
+
+			poppler_text_markup = POPPLER_ANNOT_TEXT_MARKUP (poppler_annot);
+
+			poppler_quads = poppler_annot_text_markup_get_quadrilaterals(poppler_text_markup);
+			if (poppler_quads && poppler_quads->len) {
+				ev_quads = g_array_sized_new (FALSE, FALSE,
+				                              sizeof(EvQuadrilateral),
+				                              poppler_quads->len);
+
+				poppler_page_get_size (POPPLER_PAGE (page->backend_page),
+						       NULL, &page_height);
+
+				guint i;
+				for (i = 0; i < poppler_quads->len; ++i) {
+					EvQuadrilateral ev_quad;
+					PopplerQuadrilateral quad = g_array_index(poppler_quads,
+					                                            PopplerQuadrilateral,
+					                                            i);
+					/*
+					 * Reorder poppler quads to be
+					 * counter-clockwise and starting
+					 * at the bottom left corner.
+					 */
+					ev_quad.p1.x =               quad.p3.x;
+					ev_quad.p1.y = page_height - quad.p3.y;
+
+					ev_quad.p2.x =               quad.p4.x;
+					ev_quad.p2.y = page_height - quad.p4.y;
+
+					ev_quad.p3.x =               quad.p2.x;
+					ev_quad.p3.y = page_height - quad.p2.y;
+
+					ev_quad.p4.x =               quad.p1.x;
+					ev_quad.p4.y = page_height - quad.p1.y;
+
+					g_array_append_val(ev_quads,
+							   ev_quad);
+				}
+			}
+
+			ev_annot_text_markup = EV_ANNOTATION_TEXT_MARKUP (ev_annot);
+
+			g_object_set(ev_annot_text_markup, "quadrilaterals", ev_quads, NULL);
+			g_array_unref(poppler_quads);
+			g_array_unref(ev_quads);
+		}
 
 		if (POPPLER_IS_ANNOT_MARKUP (poppler_annot)) {
 			PopplerAnnotMarkup *markup;
diff -r 48de07d940ed -r 15b1715682fd libdocument/ev-annotation.c
--- a/libdocument/ev-annotation.c	Sun Mar 30 18:09:27 2014 +0200
+++ b/libdocument/ev-annotation.c	Sun Mar 30 18:14:40 2014 +0200
@@ -1551,3 +1551,15 @@
 	return TRUE;
 }
 
+EvAnnotation *
+ev_annotation_text_markup_highlight_new (EvPage  *page)
+{
+	EvAnnotation *annot = EV_ANNOTATION(g_object_new (EV_TYPE_ANNOTATION_TEXT_MARKUP,
+	                                                  "page", page,
+	                                                  NULL));
+	if (annot) {
+		annot->type = EV_ANNOTATION_TYPE_HIGHLIGHT;
+	}
+	return annot;
+}
+
diff -r 48de07d940ed -r 15b1715682fd libdocument/ev-annotation.h
--- a/libdocument/ev-annotation.h	Sun Mar 30 18:09:27 2014 +0200
+++ b/libdocument/ev-annotation.h	Sun Mar 30 18:14:40 2014 +0200
@@ -112,7 +112,8 @@
 typedef enum {
 	EV_ANNOTATION_TYPE_UNKNOWN,
 	EV_ANNOTATION_TYPE_TEXT,
-	EV_ANNOTATION_TYPE_ATTACHMENT
+	EV_ANNOTATION_TYPE_ATTACHMENT,
+	EV_ANNOTATION_TYPE_HIGHLIGHT
 } EvAnnotationType;
 
 typedef enum {
@@ -205,6 +206,7 @@
 GArray              *ev_annotation_text_markup_get_quadrilaterals (EvAnnotationTextMarkup *annot);
 gboolean             ev_annotation_text_markup_set_quadrilaterals (EvAnnotationTextMarkup *annot,
                                                                    GArray *arr);
+EvAnnotation        *ev_annotation_text_markup_highlight_new      (EvPage                 *page);
 
 
 G_END_DECLS
# HG changeset patch
# User Thomas Liebetraut <[email protected]>
# Date 1396197130 -7200
#      Sun Mar 30 18:32:10 2014 +0200
# Node ID e1e87caa7cdc9874015d635e28eed02975830a35
# Parent  15b1715682fd6d48ea723619431834214e67701d
Add support for POPPLER_ANNOT_STRIKE_OUT

https://bugzilla.gnome.org/show_bug.cgi?id=583377

diff -r 15b1715682fd -r e1e87caa7cdc backend/pdf/ev-poppler.cc
--- a/backend/pdf/ev-poppler.cc	Sun Mar 30 18:14:40 2014 +0200
+++ b/backend/pdf/ev-poppler.cc	Sun Mar 30 18:32:10 2014 +0200
@@ -2876,6 +2876,10 @@
 			ev_annot = ev_annotation_text_markup_highlight_new (page);
 		}
 			break;
+		case POPPLER_ANNOT_STRIKE_OUT: {
+			ev_annot = ev_annotation_text_markup_strikeout_new (page);
+		}
+			break;
 	        case POPPLER_ANNOT_LINK:
 	        case POPPLER_ANNOT_WIDGET:
 			/* Ignore link and widgets annots since they are already handled */
@@ -2889,7 +2893,6 @@
 		case POPPLER_ANNOT_SQUARE:
 		case POPPLER_ANNOT_SQUIGGLY:
 		case POPPLER_ANNOT_STAMP:
-		case POPPLER_ANNOT_STRIKE_OUT:
 		case POPPLER_ANNOT_UNDERLINE: {
 			/* FIXME: These annotations are unimplemented, but they were already
 			 * reported in Evince Bugzilla with test case.  We add a special
diff -r 15b1715682fd -r e1e87caa7cdc libdocument/ev-annotation.c
--- a/libdocument/ev-annotation.c	Sun Mar 30 18:14:40 2014 +0200
+++ b/libdocument/ev-annotation.c	Sun Mar 30 18:32:10 2014 +0200
@@ -1563,3 +1563,14 @@
 	return annot;
 }
 
+EvAnnotation *
+ev_annotation_text_markup_strikeout_new (EvPage  *page)
+{
+	EvAnnotation *annot = EV_ANNOTATION(g_object_new (EV_TYPE_ANNOTATION_TEXT_MARKUP,
+	                                                  "page", page,
+	                                                  NULL));
+	if (annot) {
+		annot->type = EV_ANNOTATION_TYPE_STRIKEOUT;
+	}
+	return annot;
+}
diff -r 15b1715682fd -r e1e87caa7cdc libdocument/ev-annotation.h
--- a/libdocument/ev-annotation.h	Sun Mar 30 18:14:40 2014 +0200
+++ b/libdocument/ev-annotation.h	Sun Mar 30 18:32:10 2014 +0200
@@ -113,7 +113,8 @@
 	EV_ANNOTATION_TYPE_UNKNOWN,
 	EV_ANNOTATION_TYPE_TEXT,
 	EV_ANNOTATION_TYPE_ATTACHMENT,
-	EV_ANNOTATION_TYPE_HIGHLIGHT
+	EV_ANNOTATION_TYPE_HIGHLIGHT,
+	EV_ANNOTATION_TYPE_STRIKEOUT
 } EvAnnotationType;
 
 typedef enum {
@@ -207,6 +208,7 @@
 gboolean             ev_annotation_text_markup_set_quadrilaterals (EvAnnotationTextMarkup *annot,
                                                                    GArray *arr);
 EvAnnotation        *ev_annotation_text_markup_highlight_new      (EvPage                 *page);
+EvAnnotation        *ev_annotation_text_markup_strikeout_new      (EvPage                 *page);
 
 
 G_END_DECLS

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
evince-list mailing list
[email protected]
https://mail.gnome.org/mailman/listinfo/evince-list

Reply via email to