Estimated read time: 2 minutes
Line heights in Writer are typically defined in points on the UI (e.g. 12pt), though they are measured in twips internally (1 point is 20 twips). This height was stored in a 16bit unsigned integer, so the maximum allowed height was 65536 twips, around 116 cm.
Now we track line heights with 32 bits ints, so this limitation is practically removed.
Once you insert an image to a Writer document, you can customize its anchor type. The as-char anchor type is handy if you don’t want text to flow around the image. This has the side effect that a large image significantly increases the nominal height of a line. The problematic document had an image height of 118.9 cm (46.81 inch), so the unsigned integer used to represent its height wrapped around, leading to an incorrect layout.
Results so far
Now it looks like the way you would expect it:
How is this implemented?
If you would like to know a bit more about how this works, continue reading… :-)
As usual, the end goal was reached via a set of incremental commits:
The very first integer truncation was found using gdb, manually. At that point it was clear that some tool to catch the problematic places would accelerate development. First sw: replace most static_cast<sal_uInt16>() calls with o3tl::narrowing() prepared Writer code so that sanitizers can flag the interesting code locations when using
-fsanitize=implicit-unsigned-integer-truncation -fsanitize=implicit-signed-integer-truncation. This is important, as conversion with
static_cast<>counts as an explicit integer conversion, and sanitizers can’t flag such conversions.
Then sw: allow the height of a line to be larger than 65536 twips took care of the height part.
Finally sw: allow the width of a line portion to be larger than 65536 twips fixed the width part.
Want to start using this?
Collabora intends to continue supporting and contributing to LibreOffice, the code is merged so we expect all of this work will be available in TDF’s next release (7.2).