Index ¦ Archives ¦ RSS > Tag: en

Insert PDF as image in LibreOffice 5.3

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. ;-)


Small capitals toolbar button in LibreOffice Writer

Estimated read time: 1 minutes

It was requested to be able to set the small capitals character property via a toolbar button in Writer, which was indeed not possible. Not only the toolbar button wasn’t there, but the underlying UNO command was also missing (which you can use e.g. from a macro to format the current selection).

So my commit added a simple set of icons to the galaxy theme for the new toolbar button, defined the new UNO command for Writer text and added it to Writer’s text object bar, next to the upper case and lower case buttons (hidden by default). One difference from those buttons is that those buttons perform a transliteration, while this one really just sets a character property, you can easily undo the property later if needed.

Wrt. other icon themes, see this mail, hopefully the design team can help there.

As usual, you can try this right now with a 5.3 daily build. :-)


Using clang-based tools beyond loplugin LOCon lightning talk

Estimated read time: 1 minutes

The last week I gave a Using clang-based tools beyond loplugin lightning talk at LibreOffice conference 2016, on the last day. Click on the image to see all the slides.

If you’re a vim or emacs user and you work with C++11 code, you probably want to have a look at clang-rename, include-fixer and some editor plugin exposing the power of libclang (like YouCompleteMe or libclang-vim), sometimes these are really helpful.


A year in LibreOffice's RTF support LOCon talk

Estimated read time: 1 minutes

Last week I gave a year in LibreOffice’s RTF support talk at LibreOffice conference 2016, in the development track. Click on the image to see all the slides.

I’ve also published a number of (mostly) sightseeing pictures based on wondering around in Brno before and after the conference.


Collaborative editing using LibreOfficeKit LOCon talk

Estimated read time: 1 minutes

Yesterday I gave a Collaborative editing using LibreOfficeKit talk at LibreOffice conference 2016, in the development track. There were many interested parties — not a surprise, as this is the power horse behind LibreOffice Online. :-)


Improved digital signature handling in LibreOffice LOCon talk

Estimated read time: 1 minutes

Earlier today I gave a Improved digital signature handling in LibreOffice talk at LibreOffice conference 2016, in the development track. The room was well-crowded — seems this year classification was a hot topic. ;-)

Quite some pictures are now available on Twitter, don’t miss them.


LibreOffice now bundles the latest libxmlsec version

Estimated read time: 1 minutes

I wrote about how LibreOffice uses the XMLSec Library in an earlier post from March. There are two long-term goals regarding xmlsec in LibreOffice:

  • bundle the latest xmlsec version, instead the one from 2009

  • upstream enough of the patches, so building & running against xmlsec as provided by a Linux distro also works

I’m happy to say that the first goal is now reached:

  • libreoffice-5-1 bundled xmlsec 1.2.14 from 2009

  • libreoffice-5-2 bundles xmlsec 1.2.20 from 2014

  • master bundles the latest xmlsec 1.2.22, released earlier this year :-)

This is good, as this way it’s easier to integrate xmlsec upstream improvements into LibreOffice in the future.

Regarding the other goal, shrinking the patch list is still to be done. ;-)


A LibreOffice / AddressSanitizer setup

Estimated read time: 5 minutes

sanitizers (ASAN, UBSAN, etc.) is a collection of tools to detect memory corruption bugs, undefined behavior and more by instrumenting the code generated by the compiler. (That’s the main difference from valgrind.) From LibreOffice’s perspective one more important difference is that there is a Jenkins_Linux_Ubsan tinderbox that makes sure that the master branch is kept clean from errors detected by a given configuration.

So when the tinderbox failed after a commit of mine, I wanted to set up a similar environment locally, reproduce and fix the bug, and push the fix once I saw that the fix indeed solves the problem. You can set many options both at build and runtime, so while we have some documentation on the TDF wiki (and also Stephan was kind enough to share his config) on how to use these sanitizers, it wasn’t clear to me what to do step by step. So here is one possible setup that worked for me — in my case I wanted to reproduce a stack-use-after-return problem. If you haven’t ever built LibreOffice before, then go to the Development wiki page, first do a normal build, and if everything went fine, came back here.

Build options

My autogen.input looks like this:

CC=clang -fsanitize=address
CXX=clang++ -fsanitize=address
--enable-dbgutil
--disable-firebird-sdbc

Which is a normal clang debug build, except:

  • you need to add -fsanitize=... to CXX (not to CXXFLAGS), as explained on the wiki

  • you need to explicitly disable Firebird integration for now

Building

My first attempt failed at build time, as even the tools used only during the build are instrumented, and some memory leak was detected there, which means the build aborted before reaching the problem I was interested in. To disable leak detection during build, and disable parallelism (I needed this, as I did the build in the background while using the machine for something else):

make build-nocheck ASAN_OPTIONS=detect_leaks=0 PARALLELISM=1

This also means that I explicitly disabled running any tests, as I knew which is the single unit test I want to run for the purposes of reproducing and fixing the problem.

Testing

Once the build completed, it turns out that the stack-use-after-return detection is disabled at runtime by default, which means I could not see any problem locally. Here is the commandline to run one specific CppunitTest with this detection on:

cd sw; make -sr CppunitTest_sw_tiledrendering ASAN_OPTIONS=detect_leaks=0:detect_stack_use_after_return=1

Again, this is just one possible setup, you can use other -fsanitize=... options, other environment variables during build and during testing — but hopefully it helps in the future to avoid pushing fixes for such problems detected by sanitizers just blindly.

Update, 2019-01-25

The above described "do it yourself" way doesn’t work with LibreOffice master (towards 6.3) and openSUSE Leap 15.0 anymore. I tried to debug what is the exact problem, but there are many moving parts here:

  • gcc version (providing libstdc++)

  • clang version (5.0.2 is too old; 7 failed to build the plugins, trunk towards 9 also generated false positives for me)

  • various sanitizer-related environment variables

  • various sanitizer-related compiler options

So it’s much easier to just use the combination used by the Jenkins_Linux_Ubsan tinderbox than something custom. Doing that is reasonably straightforward, but still there are a couple of non-trivial steps. What worked for me is:

  • Set up LODE according to its wiki page.

  • Instead of plain ./setup --dev, do:

./setup --jenkins
./setup --jenkins-san
./setup --dev
cd $LODE_HOME/dev/core

This will build a working version of both gcc and clang for you.

  • Instead of manually setting up the environment variables, do:

. $LODE_HOME/bin/lode_ubsan_env
  • Instead of manually setting autogen options, use this autogen.input:

--with-distro=Jenkins/Linux_ubsan_master
  • Finally to build the code and run a specific test based on tinderbox mail:

make build-nocheck
cd sw; make -sr CppunitTest_sw_unowriter CPPUNIT_TEST_NAME="testPasteListener"

Update, 2019-11-14

The 2019-01-25 setup can be fine-tuned further. Sadly LODE mixes two goals: setting up dependencies / environment and cloning repos. I recently added support for bypassing any cloning, so you can use LODE even if you already built the code and want to keep using your own way. The tricks are:

  • Use autogen.env-san in two ways: first comment out the second half to run the above ./setup --jenkins && ./setup --jenkins-san, then to source the full environment. This means you get all the up to date environment variables from LODE, but you don’t need a chroot to avoid LODE messing up your environment.

  • Use autogen.input-san to again inherit all up to date autogen switches from LODE, but avoid the submodule pain that would be the default. Now you can do a make check gb_SUPPRESS_TESTS=y to build (but not run) all the code & tests.

  • Use up.sh to build and run all Online code & tests — with new enough core.git master and online.git master the online.git make check passes for me in this environment.

I believe this setup mostly delegates (envrionment, config switches and toolchain) maintenance to LODE, still allows not running in a chroot and managing your git clones without LODE.

Update, 2023-12-02

These days it works to use the system clang compiler, so no need to to execute ./setup in lode.git. This means:

  • Use (source) autogen.env-san to set the compiler flags and environment variables from LODE.

  • Use autogen.input-san as autogen.input in the core.git build to set the autogen options.

  • Use up.sh to build Online the usual way.


On LibreOffice's ViewContact/ViewObjectContact/ObjectContact

Estimated read time: 1 minutes

I’ve recently fixed a missing-repaint problem in LibreOffice’s headless backend, but the root cause wasn’t close to the symptom I saw first. Part of the debugging process was to understand what’s the relation between sdr::contact::ViewContact, sdr::contact::ViewObjectContact and sdr::contact::ObjectContact.

See this old presentation and the review of my documentation update for the details, but the short version is that:

  • somewhat confusingly, sdr::contact::ViewContact is part of the model, and there is one sdr::contact::ViewContact object per shape

  • sdr::contact::ViewObjectContact is part of a view, and there is one sdr::contact::ViewObjectContact per shape, per view

  • finally sdr::contact::ObjectContact is part of a view, and there is one sdr::contact::ObjectContact per view

So the answer to my original Is it normal that I have two object contacts and a single view contact for a shape and two views? question is: yes, that’s expected. ;-) Hopefully the updated documentation is now more clear, the incorrect 1:N relation in the original class diagram first confused me.


RTF shape import: group scaling and flip in LibreOffice Writer

Estimated read time: 1 minutes

Some kind of simple logo was reported to be mis-imported in the RTF filter, it looked like this:

https://farm8.staticflickr.com/7451/27320164444_f437d0418e_o.png

which is interesting, but the reference output is different:

https://farm8.staticflickr.com/7317/27898228066_f5918e59bf_o.png

With a bit of investigation, it turns out this was a flipped group shape with a few rectangles, so the mis-rendering of the logo was due to two independent problems. The first is that the child shapes inside a group shape were scaled incorrectly. See the commit for the exact details, after fixing scaling, it looked closer to the original:

https://farm8.staticflickr.com/7301/27320164424_4ce2ced16c_o.png

The second problem was that the group itself was flipped, and this was again ignored on import. After fixing that problem:

https://farm8.staticflickr.com/7228/27898228076_f89fabeb00_o.png

the result is basically the same as the reference. Both fixes are not only on master (towards LibreOffice 5.3) but also backported to LibreOffice 5.2. :-)

© Miklos Vajna. Built using Pelican. Theme by Giulio Fidente on github.