New features in the PDF Library 2.11.25

A quick summary

Our latest PDF Library has a few important aspects to it. The most significant is that this release fixes a security vulnerability relating to JavaScript. If you're a customer we should have emailed you already about this, so if you haven't got this already then please contact and they'll give you the details.

You can read the Changelog for the full list, but the main aspects of this release are:

  • support for BarCode fields, which have been in Acrobat since 7.0 but not officially documented until the PDF 2.0 specification, which should be out shortly (we've written a separate article on these).
  • Improvements to the viewer: the multi-page viewport has been rewritten for speed, and we've added the ability to optionally capture handwritten signatures using an Android or iOS device (there's a separate article on that too).
  • Lastly, we've put in some long overdue changes relating to List: specifically lists of annotations, as returned by PDFPage.getAnnotations() and FormElement.getAnnotations().

This last one deserves a bit more of an explanation. Many users of the PDF Library find themselves merging PDF documents in one way or another, in particular when a document has form fields. Quite a common operation is to move all a field's annotations from one page to another, and in previous builds this could lead to a contradiction:

List annots1 = page1.getAnnotations();
List annots2 = page2.getAnnotations();
// Move all annotations from page1 to page2

// Contradiction ahead: page 1's annotation not on page 1!
assert annots1.isEmpty(); // fails!
PDFAnnotation annot = (PDFAnnotation)annots1.get(0);
assert annot.getPage() == page1;   // fails!

The problem comes about because while in general, an item in a java.util.List can belong to more than one list, an annotation can only be on one page at a time. Adding all the annotations from page 2 to page 1's list should remove them from page 2, but if you try to do that with a normal list you'll quickly come up against a ConcurrentModificationException. The same problem exists when moving widgets between form fields.

We've finally got a a solution to this in the shape of a new List implementation, which manages the moving of items from one list to another without any ConcurrentModificationExceptions. Your Iterators in the following will work properly:

List annots1 = page1.getAnnotations();
List annots2 = page2.getAnnotations();
for (Iterator i = annots1.iterator();i.hasNext();) {
    i.remove();   // optional - it's going to happen anyway
assert annots1.isEmpty();

And if you're just copying the annotation list to a regular java.util.List, everything will work as normal:

List annots1 = page1.getAnnotations();
List temp = new ArrayList();
for (Iterator i = annots1.iterator();i.hasNext();) {
assert annots1.size() == temp.size();

The result is that your PDF's structure is internally consistent all of the time, which clears the way for us to put out some further improvements in a forthcoming release. Watch this space.