Estimated read time: 3 minutes
Results
LibreOffice 5.3 will add one more vector-based format that can be inserted as an image into documents: PDF. First, thanks to PMG who made this work possible. On the user interface you can now select PDF files when you choose e.g. Writer’s Insert → Image option:
The first page of the PDF document will be shown, which is handy if the PDF file is basically used as a vector image format.
Similarly to the SVG feature, the original vector image is stored in the document, but when saving to ODF, a replacement PNG file is also generated to be backwards compatible with older ODF readers. The image context menu → Save menu item allows to extract your original PDF data from the image, too:
And that’s it, as long as you save your document in ODF, your PDF-as-an-image will be kept without loosing any data. As usual, you can try this right now with a 5.3 daily build. :-)
However, if you’re interested in how this is implemented, keep reading…
Document model
The PDF image in the document model is really similar to how SVG is handled,
next to Graphic::getSvgData()
, there is now a Graphic::getPdfData()
.
This new member function exposes the original PDF data, otherwise the Graphic
is just a metafile.
UNO API
The ReplacementGraphicURL
property of the image at an UNO level now exposes
the generated metafile for PDF images. This is implemented for both Draw and
Writer images, and is used by the ODF export filter.
Layout
When the Graphic
instance is rendered, the layout knows nothing about the
PDF data attached to the object, only parses the generated metafile. This way
the display of the PDF image works out of the box.
Filters
First I’ve implemented a PDF import-as-graphic filter, then the export equivalent of it. As you can see, the PDF import-as-graphic filter isn’t too complicated, it completely reuses the existing "import PDF into Draw" filter, it simply copies the first page of the resulting document model as a metafile.
Second, once the graphic filters were working, I’ve also
improved
the ODF import to recognize PDF data — the export side needed no explicit
work, once the ReplacementGraphicURL
bits were in place.
Tests
As mentioned above, the Draw and the Writer image implementation is separate,
so first I’ve added tests for ODT files in the testEmbeddedPdf
of
CppunitTest_sw_odfexport
, and then SdExportTest::testEmbeddedPdf()
to
cover ODP files (and other ODF formats). Second, the PDF part of the graphic
swapout/in code has a dedicated test in GraphicObjectTest::testPdf()
, and
the UI’s "Save original PDF" feature has a new
XOutdevTest::testPdfGraphicExport()
test.
Oh, and if you intent to test this manually in a self-created build, make sure
to avoid --disable-pdfimport
, otherwise this feature can’t work. ;-)