Index ¦ Archives ¦ RSS

Transparent shadow for tables from PPTX in Impress

Estimated read time: 2 minutes

Impress is now able to correctly render shadows for table shapes, even if the shadow itself or the fill of the table cells have transparency. The result is now compatible with PowerPoint.

First, thanks to our partner SUSE for working with Collabora to make this possible.

Motivation

We got a PPTX document, which has a table shape with pink background and a blurry shadow. Impress rendered a red background, making the text hard to read.

The request was to improve the shadow rendering to be PowerPoint-compatible and in general correctly support transparency when it comes to table cell fills and table shadows.

Results so far

The table shadow now looks like this:

https://share.vmiklos.hu/blog/sd-table-transparent-shadow/new.png
Figure 1. New render result in Impress

Matching the reference rendering:

https://share.vmiklos.hu/blog/sd-table-transparent-shadow/ref.png
Figure 2. Reference render result

While background was red previously:

https://share.vmiklos.hu/blog/sd-table-transparent-shadow/old.png
Figure 3. Old render result in Impress

You can see that not only the background in the top center cell is pink now, but the blurry table shadow is still correct.

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 fixes:

With these, it’s now possible to add transparency to both table cell fills and to table shadows, and the rendering will take both into account, correctly.

Want to start using this?

You can get a snapshot / demo of Collabora Office and try it out yourself right now: try 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.3).


Start of list level support in Writer paragraph styles

Estimated read time: 2 minutes

Writer now has the start of list level support in Writer paragraph styles. This improves ODT and DOCX compatibility, and it’ll improve the style previews and the UI in the future.

First, thanks Docmosis who made this work by Collabora possible.

Motivation

A paragraph might have an associated list in Writer and that list can have multiple levels. This is direct formatting. When it comes to paragraph styles, referring to a list was already possible, but defining a custom list level was not.

Loosing this information in Word documents was quite annoying, and it turned out that ODF also has markup for this, just LibreOffice didn’t implement it.

This work is currently done for the document model, scripting API and file filters: style previews & UI still needs finishing.

Results so far

Writer can at the moment preserve list level info from ODT and DOCX files. Here is how a file written by Writer looks like in Word:

https://share.vmiklos.hu/blog/sw-parastyle-listlevel/parastyle-listlevel.png
Figure 1. Writer exporting a paragraph style with list level info

You can see that the style preview in Word takes the list level into account. Doing the same and applying the list level as part of applying the paragraph style on the Writer UI is still future work.

Thanks to Justin Luth who did the follow-up work to adapt the DOC filter accordingly, and also doing other related fixes.

How is this implemented?

If you would like to know a bit more about how this works, continue reading… :-)

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


Unshare shape properties for the same type before insertion in Impress

Estimated read time: 2 minutes

Shape properties were shared by shape type (e.g. shared between group shapes) before insertion into a document model in Impress. This is now fixed: the property names and types are still shared to help performance, but their values are no longer shared. This helps matching the user expectation that separate opened documents don’t share information with each other.

First, thanks to our partner SUSE for working with Collabora to make this possible.

Motivation

I was working on a testcase for tdf#132696 when I noticed that the existing CppunitTest_oox_drawingml testsuite runs fine before my changes, also a newly added testGroupShapeSmartArt testcase runs fine in isolation, but if I run the whole testsuite, then it breaks.

Further investigation revealed that in case testGroupShapeSmartArt is executed first, then testTdf131082 fails. This means:

  • the first document is opened

  • the first document is closed

  • the second document is opened

  • the second document is saved

And at this point information from the first document is leaked to the second document, even if the first document was already closed by the time we performed the save. It turns out the root cause was i#114206 (reported in 2010), i.e. group shapes shared their property values till they got inserted to the document model. The first document import did not consume pending SmartArt properties on a to-be-inserted group shape, the second import was looking for pending properties, found them. And then the second document’s save wrote those pending properties to the file, leading to this unexpected leak.

Here is how the first document looks like, containing the blue rectangles (a SmartArt):

https://share.vmiklos.hu/blog/sd-groupshape-unshare/first.png
Figure 1. First document with a SmartArt

Here is how the second document looks like, without a SmartArt:

https://share.vmiklos.hu/blog/sd-groupshape-unshare/second.png
Figure 2. Second document after loading, no SmartArt

And here is how the second document looks, after saving to PPTX and reloading:

https://share.vmiklos.hu/blog/sd-groupshape-unshare/second-saved.png
Figure 3. Second document after reloading, with a SmartArt

Results so far

The fix is to split out part of SvxItemPropertySet to a separate class, so that we can keep sharing SvxItemPropertySet between multiple instances of the same shape type (describing the name and type of the various properties), while introducing a new SvxItemPropertySetUsrAnys that is specific to each not-yet-inserted shape. This way each pending shape is independent, and in case they are not inserted to the document model later, that results in no side-effects.

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


Calc buttons with macros: better XLSX support

Estimated read time: 2 minutes

Embedding macros to Calc documents and invoking them by clicking on buttons is a common use-case. There was also decent support for importing these from XLSX (XLSM to be precise), but the export side was not on par with the binary XLS export.

Calc now got a series of incremental improvements to map our form controls (buttons in particular) to OOXML’s form controls, especially when macros are assigned to such buttons.

This work is primarily for Collabora Online, but the feature is fully available in desktop Calc as well.

Motivation

Excel has both form controls and ActiveX controls, and tdf#106181 XLSX export: output form controls last year started adding support for form control export to XLSX.

Hoping that this will be mostly shared drawingML export code fixing (benefiting DOCX and PPTX as well), it seemed reasonable to assume that we can improve button handling from the "it’s lost" state to "it’s good enough" with some effort.

Results so far

Now Excel shows the button and you can click on it:

https://share.vmiklos.hu/blog/sc-xlsx-button-macro/new.png
Figure 1. Excel consuming our XLSM output with a button and a macro

While it used to just refuse our export result:

https://share.vmiklos.hu/blog/sc-xlsx-button-macro/old.png
Figure 2. Excel refusing bad XLSM output

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:

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


Writer line heights: removing a 16bit limit

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.

First, thanks Vector who made this work by Collabora possible.

Motivation

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:

https://share.vmiklos.hu/blog/sw-line-height/sw-line-height.png
Figure 1. Writer as-char image with height that is larger than 65k twips

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:

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


Bibliography improvements in LibreOffice Writer: refer to a specific page

Estimated read time: 3 minutes

The bibliography feature in Writer allows authors of e.g. scientific papers to track sources: first you can insert bibliography entry fields, then at the end you can generate a bibliography table automatically.

Writer recently gained two improvements in this area, and now there is one more: the ability to refer to a specific page of a (potentially long) source.

First, thanks TUBITAK ULAKBIM who made this work by Collabora possible.

Motivation

The same feature in normal HTML linking / citation is well-known: you can place anchors in your document and then links can refer to not only to your page, but also can set the fragment part of the URL to jump to a specific section directly. E.g. this link will jump to the "Motivation" section of the above referred previous post.

Wouldn’t it be nice if you could also jump to a specific page of a scientific PDF?

Results so far

You can add such references by choosing the Insert → Table of Contents and Index → Bibliography Entry menu item. Set Bibliography Source to Document Content and press the New button. The appearing dialog now has widgets to set a specific page number:

https://share.vmiklos.hu/blog/sw-bibliography-page/page.png
Figure 1. Refer to a specic page of a bibliography source, user interface

This is then stored in the URL by setting its fragment to page=..., and typically PDF readers understand this syntax, so when you click on the URL, the PDF will open exactly on the cited page.

This also works the other way around: URLs with such syntax are presented to the user with the dedicated widget to see, edit or delete the page number of the URL.

Finally, if you refer to different pages of the same source, the bibliography text generator detects this and lists the source in the bibliography only once.

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 incremental development steps:

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


Improving borders of merged table cells in Writer

Estimated read time: 2 minutes

Writer now has better support for Word-compatible border rending when it comes to vertically merged cells in tables.

First, thanks Docmosis who made this work by Collabora possible.

Motivation

Both Word and Writer allow specifying borders for any kind of table cells. When the user creates a vertically merged cell, there is a covering cell and there is one or more covered table cells.

The Writer approach is to render the cell borders according to the properties of the covering cell. This has the benefit that each edge of the table cell has a single border style (e.g. dashed or hairline).

The Word approach is to render the cell borders as if there would be no vertical merge, according to the properties of the covered cell. This has the benefit that merging the content of cells vertically doesn’t change the border rendering, but it also requires more complex code for painting.

Results so far

Writer can now detect that your tables originate from Word formats and render table borders the Word way in that case.

Here is how the new rendering result look like:

https://share.vmiklos.hu/blog/sw-merged-border/new.png
Figure 1. Writer rendering in compatibility mode, new output

And here is how it used to look like:

https://share.vmiklos.hu/blog/sw-merged-border/old.png
Figure 2. Writer rendering in compatibility mode, old output

And finally the reference rendering is:

https://share.vmiklos.hu/blog/sw-merged-border/ref.png
Figure 3. Writer rendering in compatibility mode, reference output

You can see that the B4 and B5 cells are covered, they had some unwanted border on their left side and this is now gone.

How is this implemented?

If you would like to know a bit more about how this works, continue reading… :-)

  • First, some building blocks were introduced: SwCellFrame::GetCoveredCellInRow() can look up a covered cell in a certain row, provided that this cell covers it

  • Building on top of this, SwCellFrame::GetCoveredCells() can provide a list of cell frames which are covered by the current cell, due to vertical merge. This is needed, because previously the layout didn’t have to consider properties of covered cells, so while the document model had this information, it was not visible to the layout in a convenient way

  • Using the above functionality, SwTabFramePainter::Insert() can suppress painting of certain border lines in Word compatibility mode

  • Finally, the code change can be covered with a test by recording the rendering and asserting the vertical positions of border points: we can check that all the positions belong to the 1st, 2nd or 3rd rows, and not to a row below them

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


My hack week at Collabora: improvements to gutter margin in Writer

Estimated read time: 3 minutes

As mentioned in a previous such report, a hack week is when we are allowed to hack on anything we want in LibreOffice / Collabora Office / Collabora Online for a few days at Collabora. I used this time to implement core support for RTL gutter margin in Writer.

Motivation

I posted about Writer gutter margin in general back in February, and two follow-up requests accumulated around this new feature since then.

First, the gutter margin could be on the left or at the top for non-mirrored documents, which initially sounded like a complete solution, but later it turned out that right-to-left (RTL) documents want it on the right.

Second, there was a request from the OASIS TC to to implement the ODF filter differently for gutter margin.

Neither of these is simple to do, so this hackweek was a good opportunity to address these problems.

Results so far

Here is the layout and user interface for RTL gutter looks like:

https://share.vmiklos.hu/blog/hackweek-2021/layout-ui.png
Figure 1. RTL gutter margin in Writer, layout and UI

You can see how the gutter is on the right (not the left) and you can alter this behavior with a dedicated checkbox on the UI.

How is this implemented?

If you would like to know a bit more about how this works, continue reading… :-)

Finally I had a little bit of remaining time, so I addressed a request from the OASIS ODF TC:

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


Bibliography improvements in LibreOffice Writer

Estimated read time: 2 minutes

The bibliography feature in Writer allows authors of e.g. scientific papers to track sources: first you can insert bibliography entry fields, then at the end you can generate a bibliography table automatically.

Writer now has two improvements in this area: more information about these entries in the form of a mouse tooltip and clickable URLs in the table.

First, thanks TUBITAK ULAKBIM who made this work by Collabora possible.

Motivation

Generating a bibliography (table) for a document is a two-step process: first the user inserts bibliography entry fields to refer to sources, then later the bibliography can be auto-generated. It was not great that details of a source was only visible in the Writer edit window after generating the bibliography table. A somewhat related shortcoming was that URLs of sources were handled as plain text, while users expect that references are also clickable, similar to e.g. table of contents.

Results so far

This is how a tooltip looks like, available even if there is no bibliography table yet:

https://share.vmiklos.hu/blog/sw-bibliography/tooltip.png
Figure 1. Tooltip for bibliography entry fields

And URLs in the bibliography table are now clickable:

https://share.vmiklos.hu/blog/sw-bibliography/url.png
Figure 2. Clickable URLs in the bibliography table

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 incremental development steps:

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


Gutter margin in Writer

Estimated read time: 3 minutes

The page gutter defines the amount of extra space added to the specified margin (typically left), above any existing margin values.

Writer now has much better support for gutter margins: not only this margin type can be specified explicitly, it’s also possible to select if the gutter should be on the left or on the top, and it works with mirrored margins as well.

This work is primarily for Collabora Online, but the feature is fully available in desktop Writer as well.

Motivation

Word has a gutter margin feature, and we saw that some UI-level workaround appeared to have something similar based on the LibreOffice technology. We thought it’s much better to impelement this properly, so that the result is interoperable with Word, and also available both in Online and on the desktop.

Results so far

This is how the UI looks like in Online:

https://share.vmiklos.hu/blog/sw-gutter-margin/online.png
Figure 1. New UI in Online

This is how the new render result looks like:

https://share.vmiklos.hu/blog/sw-gutter-margin/new.png
Figure 2. New render result in Writer

Matching the reference rendering:

https://share.vmiklos.hu/blog/sw-gutter-margin/ref.png
Figure 3. Reference render result

While the gutter was just missing previously:

https://share.vmiklos.hu/blog/sw-gutter-margin/old.png
Figure 4. Old render result in Writer

You can see that the gutter margin is now handled properly.

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 incremental development steps:

  • First, we added a new "gutter" margin type (length) and a gutter position (left or top) to the document model & UNO API.

  • This was followed by adding the layout, which is always the most challenging part of a new Writer feature. In this case the basic functionality was implemented by reducing the "print area" of page frames, so that the positioning of header, body and footer frames all respect the gutter margin. Then additional care was taken to ignore the gutter margin for page borders to be compatible with Word. Finally the margin position and mirrored margin support was implemented.

  • Then we looked at import/export: this feature is now supported with the ODP, DOCX, DOC and RTF formats. Note that some best-effort handling was there in the DOC filter already, but the gutter margin was (semantically) lost on export.

  • You already saw the new UI above: this allows changing the amount of the gutter margin, specifying its position, finally the preview widget also takes the gutter margin into account. Note that this dialog is shared code between Writer, Calc and Impress: we made sure to not break those other apps with the extended UI, which is specific to Writer.

  • Brief help has been added for these new UI controls and submitting an ODF extension proposal to OASIS is in progress to standardize the so far LO-specific markup:

<style:page-layout-properties loext:margin-gutter="1.27cm">

With these, it’s now possible to add, modify, render and delete gutter margins for your documents, while preserving them during ODT and DOCX import/export, without introducing any weird fake line shapes.

Want to start using this?

You can get a snapshot / demo of Collabora Office and try it out yourself right now: try 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.2).

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