Estimated read time: 5 minutes
Writer now has continued steps to handle tables that are both floating and span over multiple pages.
This work is primarily for Collabora Online, but is useful on the desktop as well. See the fourth post for background.
Motivation¶
The previous post finished with a first fix for overlapping tables: this is a cluster of problems where tables are allowed to overlap, but various other formatting make them not overlap in practice in Word, but they do overlap in Writer. In this post, we'll see what started to work during the past month.
Results so far¶
The feature is enabled by default and the DOCX/DOC/RTF import makes use of it. This allows stress-testing the layout code with complex user documents. The next target is to actively search for documents that rendered reasonably in the past but are now unreadable and fix them.
On the positive side, core.git repository has has 40 files now which are focusing on correct
handling of floating tables (filename matching floattable-|floating-table-
). Also, there are
additional tests that quickly build a specific multi-page floating table in the memory and do some
operation on it, e.g. delete the last row and assert what happens.
Here are some screenshots from the fixes this month:
The first problem was that in case two floating tables were directly after each other, a section break between them was lost. What you can see above is a successful transfer of the break properties to the first paragraph on the next page, so the tables don't overlap but are laid out on separate pages.
Looking through internal documents, a sample was found where a table with 2 rows was not split, even if the previous page would have enough space for the first row. This is the old, bad layout.
And this is how it looks after the fix.
The rest of the screenshots are from a complex internal document, which has 4 pages, but in total contains 11 floating tables. First I focused on getting correct rendering of this in Writer for DOCX. All the problems were not visible previously, as non-floating tables can't overlap, so bad formatting problems did not cause problems in practice. The first subset (public reproducer) had 3 tables in it, but Writer only rendered one of them.
After fixing the problem, both lost tables are now there.
The next case is about overlapping tables: the table is there, but the anchor positions are so close that the content overlaps and it's hard or impossible to read the text.
And this is how it looks after the fix.
The next trouble is with nested floating tables: in case all inner tables are inline, then the table above the images will require more space then requested and that will lead to overlapping text later.
The first fix is to make these inner tables also float if requested in the file format (but not split for now, to develop incrementally). This helps, but the position of the inner table's anchor is still incorrect.
Finally the anchor position of the table is also correct: no intersecting borders, no overlapping text, no unexpected need for lots of vertical space.
The next problem was a layout loop, which was terminated by the built-in loop control in a way that rendered text outside the table to show up inside the table.
And here is the correct rendering. Note that in case a floating table's anchor is positioned with a negative vertical offset, then it can happen that text before the table will be rendered below the table. But this is intentional and also happens in Word.
The last problem for this blog post is the case when a large floating table is anchored in a single-line paragraph. Now Writer insists that the anchored object and the anchor text is on the same page, so even if there is space for the last table on a previous page, it moves the table to the next page.
And here is the correct rendering: all tables fitting the first page. Also note that the last table is moved up, so while the document model order is "after-table-2-second table-3 after-table-3", the rendered / layout order will be "table-3 after-table-2-second after-table-3" -- again, intentionally.
And that's where we stand. Certainly more work is needed to fix some remaining unwanted overlapping of floating tables, but we get there step by step.
How is this implemented?¶
If you would like to know a bit more about how this works, continue reading... :-)
As usual, the high-level problem was addressed by a series of small changes:
- tdf#103869 sw floattable: fix lost table right before a section break from DOCX
- sw floattable: ignore keep-with-next for anchors of non-last split flys
- sw floattable: fix lost tables around a floating table from DOCX
- sw floattable, DOCX import: clean up not needed dmapper-level anchor insert
- sw floattable, compat mode: handle lower margin of anchor for fly intersect
- sw floattable: import non-split inner floating tables from DOCX
- sw floattable: fix anchor position of inner floating table
- sw floattable: fix handling of upper margin of anchor for fly intersect
- sw floattable: avoid layout loop for negative vert offset in MakePos()
- sw floattable: fix negative vertical offset handling on page boundary
Want to start using this?¶
You can get a snapshot / demo of Collabora Office 23.05 and try it out yourself right now: try the unstable snapshot. 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 too (7.6).