Estimated read time: 6 minutes
Writer now has the early 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 first post for background.
The previous post finished with split rows are now in a reasonable shape towards our journey to fix tdf#61594. In this post, we'll see what else is needed to get perfect rendering for that single document.
The plan is to iterate on that later, adding more and more incremental improvements & fixes for this feature.
Results so far¶
The feature is still enabled by default, but the DOCX import only makes use of it if you set the
SW_FORCE_FLY_SPLIT=1 environment variable. This allows playing with the feature even if there are
lots of known problems still.
On the positive side, core.git
sw/qa/core/layout/data/ has 12 files now which are rendered exactly
the way Word does. 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
Here are some screenshots from the effort so far:
Here the problem was that a normal row went to a next page after a split row. Now the document is correctly of 2 pages, instead of the previous unwanted 3 pages.
Here the additional complexity was to have multiple columns on a table, since previously we always had 1 column and 2 or more rows. Now these are also split correctly across pages.
This is an incorrect table row split, because widow control is broken.
And here is how it looks when it's working. That little line on page 2 is no longer alone.
Even better when the minimal height for non-first ("follow") table frames is working, as you can notice that space between the last line and the table bottom border on page 2.
At this point, the bug document from the motivation section worked fine, apart from the workaround that one has to re-save it in non-legacy mode in Word. So what's next? We need to instantly add a legacy mode for the brand new (not even fully enabled) multi-page floating table feature, since otherwise whatever we do, some DOCX files will be handled incorrectly.
As it turns out, the core of the legacy mode is that the floating table is sometimes allowed to flow into the footer / bottom margin area of the page, but not always. It's quite inconsistent, so one can understand why this is no longer the default behavior. The above is the naive rendering, which is logical, but incorrect.
And this is the correct result in legacy mode. After a bit of experimenting, it seems one can flow into the bottom margin area if the height of the table frame would fit the body frame, but some vertical offset causes it to be pushed down.
The final trick with legacy mode is to make sure that all tables (first one, middle ones, last one) have the required minimal height, which can result in not splitting the row in case a part of that would be less than the minimal height. E.g. a 3 cm minimal height means that a total height of 4 cm (2cm + 2cm) is not enough for a split row.
With this, we reached the goal to render that given bug document perfectly (when compared to Word), and the next step is to fix up breakage that would be caused by enabling by default.
The first problem was tracked changes support, which needs special care: as the importer converts body text to table cells, we need to keep the tracked insert/delete text ranges correctly. This is now working fine.
The next problem is around nested tables: a normal inner table inside a floating table was lost on DOCX file open, now fixed.
The other version is when a normal table has an inner floating table. This broke badly, the outer table was not imported at all.
And it's now better. The inner table is still not actually floating, but turns out that was never working for DOCX files, so it's not a regression. Fine to revisit that only later.
So far all the previous tables were aligned to the left. It turns out that the horizontal positioning was bad in every other case for non-first tables, e.g. when you wanted to center them.
And it's now fixed.
As a last fix for this post, let's look at traveling with the cursor:
After fixing this, now you can use the up/down arrows to go from the A1 cell to A2 and back. The cursor traversal code wasn't aware that the master/follow table frame was connected.
And that's where we stand. Hope to enable even the DOCX import bit by default soon.
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:
- sw floattable: update layout when enabling fly split via UNO
- sw floattable: teach the UI about SwFormatFlySplit
- sw floattable: don't leave body in SwFrame::GetNextFlyLeaf()
- sw floattable: fix vertical position of follow flys with rel orient = page
- sw floattable: undefined behavior in SwFlyFrame::UpdateAttr_()
- sw floattable: try to grow fly parent when trying section/table
- sw floattable: clean up not needed scope in SwTextFormatter::FormatLine()
- sw floattable: grow the print area as well in SwFlyFrame::Grow_()
- sw floattable: partially re-enable widow / orphan control in tables
- sw floattable: enable widow / orphan control in split rows
- sw floattable: ignore height of masters in lcl_CalcMinRowHeight()
- sw floattable: handle Word 2010 legacy mode in SwFlyFrame
- sw floattable: reject small(er than min height) row master at page bottom
- sw floattable, legacy: restrict height when using bottom margin area
- sw floattable, legacy: also consier fly position when deciding the bottom
- sw floattable: unconditionally map
- sw floattable: fix redline import from DOCX
- sw floattable: fix CppunitTest_sw_ooxmlexport10's testTdf8255
- sw floattable: fix CppunitTest_sw_ooxmlexport10's testTdf99140
- sw floattable: fix handling of nested non-floating tables at cell start
- sw floattable, CppunitTest_sw_ooxmlexport9: assert the layout in testTdf107889
- sw floattable, CppunitTest_sw_ooxmlexport9: assert can-split in testTdf109063
- sw floattable, CppunitTest_sw_ooxmlimport2: assert the layout in testTdf114217
- sw floattable: fix inner floating table inside normal outer table from DOCX
- sw floattable: limit the unfloat button to non-DOCX files
- sw floattable: fix current page number when editing document with a split fly
- sw floattable: fix bad position of follow fly if anchor is positioned late
- sw floattable: fix up/down cursor travel at fly boundary
- sw floattable: remove empty follow flys on follow table removal
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).