Hi Thomas, On Mon, 2014-03-03 at 15:45 +0100, Thomas Liebetraut wrote:
tl;dr: I want to work on proper annotations in evince and do this "ask first" thingy. [...] Currently, evince annotations only allow one (as in "exactly one") rectangular area to be interactive. The problem with things like highlight annotations is that if they span multiple lines, their area is not rectangular anymore. If it were, highlighting the last word in a line and the first word of the next line would result it the two complete lines to be clickable, not just those to words. For hyperlink annotations that span multiple lines, poppler creates a separate link area for each piece of the link (I don't know whether this stems from the PDF standard itself or can be considered a quirk in poppler), so this is not a problem here. The current code structure uses EvMapping to map from interactive area to dynamic elements (like annotations) and this EvMapping is created from PopplerAnnotMapping which defines a bounding rectangle that completely contains the annotation.
A rectangle defines the location of an annotation, no matter its type (text markup, link, etc.) See page 606 of PDF specification 1.7. http://www.adobe.com/devnet/pdf/pdf_reference.html
poppler recently added some missing pieces for properly supporting this kind of annotation that use a list of quadrilaterals to define their interactive area (<https://bugs.freedesktop.org/show_bug.cgi?id=51487>).
Quadrilaterals are like rectangles, but instead of having 2 coordinates, they have 4 (so, you can represent a rectangle in any angle). Think in a text inclined 75 degrees. The rectangle will define the whole area that covers the annotation, and the quadrilaterals will have only the "inclined rectangles" of the text to be highlighted. In the example you gave previously, you will 1 rectangle that covers 2 lines, but 2 quadrilaterals, one per line. If you highlight a paragraph of 5 lines, you might have 3 quadrilaterals: 1 for part of the first line, 1 for the block with the whole lines highlighted, and 1 for the part of the last line. Check the pane "Annotation Properties" in poppler-glib-demo to see them in action.
Long story short, I want to work on annotation support in evince and see two possible solutions: Instead of using PopplerAnnotMapping to define the annotation's area I create one EvMapping for each quadrilateral I find for the annotation and reference the exact same EvAnnotation object in each of these annotations.
I am not sure I am follow. Quadrilaterals only exists for Text Markup annotations, but there are many more annotation types that do are not represented by quadrilaterals at all.
This leaves all the libview parts untouched and still working (I hope) but may have undesirable side-effects: AFAIUI the bounding box is intended merely for focussing and displaying purposes and is the area that should be displayed if a certain annotation is selectedin the UI. If the annotation now has several such areas, focussing annotations may not behave as expected or we have to build a union area first. I would probably implement this by not returning an EvAnnotation from ev_annot_from_poppler_annot() but an EvMappingList and then appending that list to the return value of pdf_document_annotations_get_annotations().
I don't see the bounding box as a problem.
A more elaborate but not so quick fix would require a change in how annotations are handled in evince in general. To accomodate the requirements for interaction as well as displaying, an EvAnnotation must have both quadrilaterals (which may also be slanted, ftm) and the bound box rectangle (which is always aligned to page borders) defined by EvMapping. libview would then use the quadrilaterals of an annotation to handle interactions and e.g. the mouse pointer shape and resort to the bounding box for focussing, refreshing the cairo context or similar tasks.
I don't think it is necessary to touch the cairo context. Take a look at poppler-glib-demo (demo/annots.c). The demo use poppler to set any change in the PDF, and poppler renders back the PDF. In particular, you might want to check: http://cgit.freedesktop.org/poppler/poppler/tree/glib/demo/annots.c#n1005 This is updated during the interaction with the mouse. If I were you, I would start implementing straight lines. That should give you a sense of the interaction. Lines is a simple type of annotation, once you get it there, you will get circles and squares for free. After that, you can go for text markups. -- Germán Poo-Caamaño http://calcifer.org/
Attachment:
signature.asc
Description: This is a digitally signed message part