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
signature.asc
Description: OpenPGP digital signature
_______________________________________________ evince-list mailing list [email protected] https://mail.gnome.org/mailman/listinfo/evince-list
