Index ¦ Archives ¦ RSS

Start of multi-page floating tables in Writer

Estimated read time: 5 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.

Motivation

As requested in tdf#61594 10 year ago, the use-case is that you can already have floating tables:

Table in a Writer text frame

And multi-page tables:

Multi-page table

And what we want is a combination of them, like this:

Multi-page floating table

This is a quite complicated feature, since both floating objects and tables are complex, and this combines them to create even more complexity.

However, such constructs are used in existing DOCX files and we're expected to correctly display them.

Results so far

The feature is 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 4 files now which are rendered exactly the way Word does.

A bit of terminology: once a frame is split, the first element of the chain is called master, the remaining frames are called follows.

Here are some screenshots from the journey so far:

Not splitting Writer text frame

This is a fly frame with enough content that it doesn't fit the body frame. It should split, but fly frames could not be split.

Writer text frame kept inside the body frame

First try, just limit the height of the (master) fly frame, so at least it stays inside the body frame. But now some content is not rendered.

Incorrect split of a text frame

Next try. Now have have 2 flys, but the second has zero height and the content of the second fly leaks into the body of the second page.

Last version with bad anchoring

This one is better, but the position of the follow fly frame is bad, no actual wrapping happens. Also, we assume that there are multiple paragraphs after the table, which will cause problems for floating tables at the end of the document. So I reworked the anchoring code to split the anchor to as many pages as necessary...

Duplicated anchor text

Which sounds good, but now the text around the anchor point is duplicated.

Less duplicated anchor text on the first page

Better, now the anchor text is gone in the master anchor, but still there is a misleading paragraph marker.

Last text frame without a table

And now this looks reasonable. Fine, we have some minimal split flys, let's try it with tables instead of just two paragraphs:

Floating table with duplicated anchor text

With a bit of work, the table's two rows can split, but again the text in the anchor is duplicated.

Bad horizontal position

Next try, now the anchor text is correct, but the horizontal position of the table is still bad, it bleeds out towards the left margin area.

Fixed horizontal position

And with more work, now this looks correct.

Fixed vertical position

Let's add some vertical offset! That should be only applied on the first page, and now the follow fly doesn't have that unwanted offset.

Now we have 2 documents that lay out correctly on 2 pages. Let's try 3 pages:

Wanted 3 pages, have 2 pages

This falls apart, the 2nd and the 3rd row are both on page 2.

Correctly rendered 3 pages

After partitioning the fly frames to 3 categories (master, non-last follows, last follow), more than 2 pages also work.

Row split is not performed at all

This is a sample where the table has a single cell, so we need to split the (only) row, not just split the table's rows. The first is harder. Currently we don't even try to split it.

Row split is performed, but the 2nd page's object has a bad position

Next try, now we split it, but the position of the follow fly is wrong.

Row split with correct object positioning on all pages

Finally split of a single row inside multi-page floating tables also work. That's where we are. Don't try to do anything too custom (like inserting a header or footer), those cases are still known-broken.

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:

The design of the layout representation is documented in the SwFormatFlySplit constructor.

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

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