This release brings support for flattening annotations,
i.e. making the appearances of annotations part of the page content itself.
Since AcroForm fields also use annotations for their visual display, this functionality also allows
flattening of form fields. Form field flattening can now
also be done with the hexapdf form CLI command.
Additionally, basic support for the AcroForm signature field was added. However, this does not allow
signing a PDF yet.
There is also a breaking change with respect to how annotation appearances are accessed. The
change simplifies getting the correct appearance stream.
As always, have a look at the changelog for an overview of all changes.
This smaller release mostly contains performance enhancements. Due to them being especially
benefical in long running processes that handle a lot of PDFs, updating is still very recommended.
The following script was used to evaluate TrueType font and serialization related optimizations:
require'hexapdf'font_path='/usr/share/fonts/truetype/liberation/LiberationSans-BoldItalic.ttf'font_file=HexaPDF::Font::TrueType::Font.new(File.open(font_path,'rb'))1000.timesdodoc=HexaPDF::Document.newfont=doc.fonts.add(font_path)doc.pages.add.canvas.font(font,size: 10).text("The quick brown fox jumps over the lazy dog",at: [200,200])doc.write('/tmp/out.pdf')end
In HexaPDF 0.14.0 this script allocated about 2.74 million objects and took 4.20 seconds to run.
With this release object allocation was reduced by around 33% to 1.85 million and runtime by around
23% to 3.21 seconds.
These benefits are without any changes to existing code. By using the new font loader to load the
TrueType font object only once (e.g. in the code above use font_file instead of font_path), we
can further reduce the object allocation to 1.29 million and runtime to 2.41 seconds.
Furthermore, the HexaPDF::Importer class has been modified to avoid problems with memory
retention. If you have had problems with that, you should definitely try out this new version!
Here is a before and after comparison for the “raw_text” benchmark: