Tuesday, October 13, 2020

PDF annotations support

In Draw, a PDF document can be opened using the PDFium library for rendering, where each page in the Draw document contains an rendered image from the PDF. This mode is useful for viewing PDFs and allows for the best fidelity. With viewing, there is also a need to review and comment and this is where PDF annotations come in as adding the support for the PDF annotations and to support a review based workflow has been one of my recent task at Collabora Productivity.

PDF supports a wide variety of annotations, but we don't support all of them in Draw. What we do support are comments, which are similar to pop-up note annotations in PDF, so the easiest is to add those first. To be able to use pop-up notes in Draw, we need to import them. This is done at import by using PDFium after we created the PDF graphic for rendering. In Draw, we then insert this as comments and so we get the basic support for manipulating with annotations, but how to save the changes? PDF export already supports saving comments as annotations, so this mostly already works (I needed to fix some bugs and add support for saving all needed properties).

Figure 1. Pop-up Note annotation in PDF viewer (Evince) and Draw

How the output compares between a PDF viewer and inside LibreOffice can be seen in Figure 1. All this is available in LibreOffice master and should be included in LibreOffice 7.1.

What about other annotations that are supported in PDF? The work to add those is ongoing and the recent success has been adding support to draw vector graphic annotations like polygon, ink (freehand), squares (rectangles) and circles (ellipses). So the idea is that instead of the usual marker for a comment, we draw a vector graphic that we read from the PDF annotation. 

The first thing I needed to do is to extend the PDFium library, which didn't support reading all polygon vertices and ink strokes from the document. What also wasn't supported is reading the border information, which is needed for line widths.

Next thing is extending the import to read the geometry data, so I dded a special PDFAnnotationMarker class for that. Then the geometry data needs to be stored on the sd::Annotation class (implementation of XAnnotation, but I didn't extend XAnnotation at this point as it wasn't needed - yet) . Drawing is performed in AnnotationTag, where we create a new OverlayPolyPolygon object, that is responsible for creating the Primitive2D for the marker. What we get after this is done is shown in figure 2.


Figure 2. Multiple annotations in PDF Viewer and Draw

This work will shortly be merged to the LibreOffice master. 

No comments:

Post a Comment