Re: [evince] Ink Annotations Toy Implementation



Hey, your mail is too long, it is better to discuss on IRC :) Anyway, I'll try to address most comments inline below


On Wed, Dec 10, 2014 at 6:22 AM, Daniel Sim <Daniel Sim 2010 pem cam ac uk> wrote:
Hi all,

I have been working recently on a toy project to get ink annotations
working in Evince.

My end goal is actually to develop a Cairo-based alternative to
Xournal (which is currently based on the obsoleted libgnomecanvas and
doesn't do cool stuff like highlights properly).

To this end, I have done the following

- Implemented a loose quadtree
(https://www.cs.umd.edu/users/hjs/pubs/sigmod13-header.pdf) for ink
annotation segments
Is this implemented in a sort of canvas-model for the EvView widget? if so, that's nice. 
 
- Added Ink Annotation support to Poppler-glib

The code can be found at:

https://github.com/xkjyeah/evince_ink
https://github.com/xkjyeah/poppler_ink

At its current state, you can click on ink annotations and modify
their contents. You cannot select annotations or draw new annotations
yet.

At this point, I would like to ask the more experienced developers how
to progress from here.

- To meet my goal, I need extensions to PDF -- variable line width,
different compositing operators (multiply for highlights). Is this a
viable alternative? Could it be saved as a different file format, e.g.
"PDF with Evince annotations"?
I don't think you need extensions to PDF, but of course I don't know your goals. I would imagine that 
using the /AP section of an ink annotation you can do whatever you want, but I haven't try it though. In any case, iI think it would be 
best to first implement things that conform to the PDF spec. If you still want to do extensions, I guess they can be saved as metadata together with the file (this of course may cause problems when copying the file.. or send it) or just doing a sort of PDF + json or whatever you like (but in two files could be simpler for evince)
 



- It boggles my mind that Evince uses the poppler_glib backend, which
is itself an intermediate layer written in C to the C++ poppler
backend.

What is the C++ poppler backend? There is poppler core, which is written in C++ and has different backends to do the drawing, cairo, splash, arthur, etc. and some frontends, a new one is written in C++ other in C (glib) and some others also in C++ (qt4, qt5) 

What I guess you call the C++ poppler backend is NOT intended to be public API and can be broken anytime you want. On the contrary, we try that poppler-glib API be stable (this is not always the case though). 
 
The poppler_glib backend is not complete.

Sure, it is not complete, poppler is something where people from KDE and GNOME world are working together, Sometimes KDE people add a feature and sometimes (less often) we add some feature. The frontends are updated in a custom fashion, whenever okular or evince start using a feature that is available in core. 
 
The reason I
mention this is that it would be nice to be able to write the
abstraction layers once and not twice -- once for poppler_glib and
once for evince. In any case, the files in backend/pdf are written in
C++, so I why wasn't the Poppler C++ backend used here? This is just
an annoying detail.

I answered why poppler core i not used. Yes, having to copy some of the things back and forth is cumbersome, we welcome any nice idea on how to make it better, but there are smoe reasons I can't remember now why this was the way to go. Also rememeber that Evince is quite an old beast, and why it would make sense to rewrite some of it using new patterns and trying to do some zero-copy thingie, the fact is that we just have the manpower to do proper maintainership (Carlos does a great job on it)! and slowly add new features :) 



- I foresee having to rewrite the hit-detection to use a quadtree

Ink annotations (as well as circles, polygons etc. if they are
implemented in the future) are quite a different beast from nice
rectangles, because selecting them requires clicking on their *filled*
sections and not simply on their bounding boxes.

Current hit-detection algorithm f : (x,y) -->
link/annotation/clickable/etc. works as follows:

Prereq: Each ink annotation has a quadtree implementation
Input: (x,y)
1. Find (x,y) relative to page
2. Find *one* annotation at (x,y) by bounding box
3. If annotation is and Ink, detect if (x,y) is within width/2 of one
of the segments
4. Return annotation

It would need to be reworked to:

Prereq: Each *page* has a quadtree implementation
1. Find (x,y) relative to page
2. Find ALL annotations parts at (x,y) using quadtree sorted by z-index
3. Return top-most annotation

Any comments?

These are problems of a proper canvas implementation... I would say follow new work on gsk, graphene and gtk to see how much of the machinery they are building can be reused in a canvas's based version of evince. In practice
one is not going to have many annotations being intersected... but what we do in highlight annotations is something different: 
1. Find (x,y) relative to page
2. Find all annotations at (x,y) by bounding box
3. If annotation implements a special "is_inside_annotation" method, call this method, if the method returns true, return annotation
4. go to next annotation. 


In my opinion this is better (it could be the same thing as your second algorithm  actually depending on implementation details) because It makes explicit that you are first finding object using bounding boxes, which with quadtrees will be fast, and then, asking for the annotation itself to tell you wether it contains the said point. Most of the time you will find just one annotation. One thing I haven't think though is z-order, I am not that familiar with the pdf spec to say something about it.

 
Regards,
Daniel
_______________________________________________
evince-list mailing list
evince-list gnome org
https://mail.gnome.org/mailman/listinfo/evince-list



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