Writer has the concept of recording tracked changes or not: if recording, typing into a document or
deleting content will create tracked changes of type insertion or deletion. So far this was a
per-document setting, but now individual users can enable or disable this as they wish.
This work is primarily for Collabora Online, but the feature is
available in desktop Writer as well.
When Alice keeps typing and Bob enables change tracking, then surprisingly the typed characters of
Alice will form a tracked insertion, which is surprising, since that was not the case a second ago
and Alice didn't do anything other than typing.
Giving users a choice if they enable recording for just this user or for all users fixes this
problem.
You can get a development edition of Collabora Online 25.04 and try it out yourself right now: try
the development edition. 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 (25.8).
LibreOffice Technology had the concept of digital signing, but this was not available in Collabora
Online, so it was not possible to combine this with collaborative
editing. Also, once Collabora Online started to expose digital signing with software certificates
for ODF files, that also allowed taking a further step and start supporting electronic signing for PDF
files. Partnering with eID Easy, you can create strongest of the electronic
signatures – the mighty QES. This
means signing with Collabora Online allows you to:
create proper electronic signatures
not share your document with a 3rd-party, only the
hash of your
PDF will be sent to the external service
integrate with e.g. Nextcloud, use the feature without installing anything other than the
Nextcloud AIO image
potentially combine signing with other security features like Secure
View and
work with visual signing in a WYSIWYG way, which allows
placing a visible signature widget at the specified page, then dragging it to the preferred
position.
The sample integration presented here is for Nextcloud, but the feature can be made available in
other integrations as well.
See Collabora's blog
post
if you prefer less technical information about this feature.
Digital and electronic signing of documents is meant to be based on cryptographic security, and
traditionally this has been exposed to users in a very complex way. You need to know that first you
have to sign your macros and only then your document, you need to somehow get PEM files to have a
signing certificate, you need to somehow get your certificate trusted by some certificate authority
that is commonly trusted by other people who will verify your signature, and so on.
This lead to the need to first support digital signatures in COOL using a single signatures dialog
for ODF files and then later to provide electronic visual signing for PDF files, while continuing to
respect your privacy by not sharing your document with a 3rd-party service.
First the signature viewer dialog was turned into a read-write digital signatures dialog in COOL
that is still async (compatible with collaborative editing), first for ODF files & using PEM files.
Related to this, we automatically sign macros (if the document has macros) when signing the
document, so you can’t forget about this or get the order wrong (sign macros first, then the
document).
At this stage implementing signature removal was possible, which again needs an async conversion so
the user can confirm they really want to remove a signature. This also means the signature status of
the document can change, the COOL UI now supports this.
You can now associate a signing certificate / key / CA chain with a COOL editor, so you can sign the
document, but not an other editor working on the same document.
Finally adding a digital signature is now possible, where the certificate chooser just shows your
signing certificates and hides it from other editors.
Here is a screenshot of the early digital signatures dialog at this stage:
The second half of digital signing support in COOL started with WOPI extensions, so an integrator of
COOL can specify the signature settings on their user settings page and pass that to COOL when a
document is edited. We then send this to the document editor process only when needed, i.e. not on
file open, but when the actual signing process would start.
UI is also added on the notebookbar in the form of a new button that allows adding signatures to a
previously unsigned document – before you could only trigger the signatures dialog if the status bar
said something about existing signatures, and only then you could add a signature. This button is
hidden if you don’t have signature settings configured. It looks like this:
When was still missing here is automated Cypress tests to make sure signing e.g. an ODT file keeps
working and the SDK
documentation now
also describes what does it take to support digital signatures in your COOL integration. For example
you can create a Nextcloud integration like this:
Once digital signing of ODF files is handled, let’s switch to PDF signing, which is much more
interesting: you typically want to sign something final, and we see PDF as a final output of your
documents. So first support for digital signing of PDFs was added.
The next part is to integrate with eID Easy, which can do privacy-friendly electronic signing for
us. This is a 5 step process:
Extract the hash of the to-be-signed document. This is similar to signing, you start the process
but once you have the hash that you would sign locally, you just take that hash and abort the
actual signing.
Send this hash to the electronic signing service.
Open a popup and let the user authenticate with their credentials (passport, personal ID, etc)
using one of the providers (different providers support different countries) and sign the hash.
Download the signed hash from the service.
Serialize this signed hash into the local document. This requires producing the local PDF
signature once more, but this time using the previous timestamp (instead of the system clock, so
the hash is table) and using the downloaded PKCS#7 signature instead of locally signing something.
At the end we got something that looks like a signature produced externally, but there was no UI for
this. An initial popup for step 3 looked like this in the test environment (that doesn’t work with
real passport numbers or anything sensitive):
The next step was to create a user interface for electronic signing. The Insert menu had a new menu
item to insert electronic signatures and to specify your country, finally choose one of the
providers available in your country.
Also support for two types of providers is added: the first is the “in context” one, the other is a
“redirect based” one. We now support both: all the redirect (should be familiar to you if you ever
did e.g. online payments) happens in the popup, so the original COOL editor is never closed.
eID also has the concept of multiple tokens for signing: initiating the signing costs money, so is
done using a “secret”, which is never sent to the COOL JS code. Then the “client ID” identifies the
client, but can’t be used to start signing. Finally any single signing transaction has a specific
“document ID”. We took care to follow the guidelines here, so the sensitive “secret” for signing is
always kept on the server.
Similar to the initial document signing, electronic signing settings are also possible to specify
from an integration, we documented this in the
SDK
and also created a sample Nextcloud integration for this.
The last part of this electronic signing effort was to expose visual singing in COOL, something that
was added to LibreOffice Draw back in 2020, see this earlier blog
post.
First this was exposed in COOL with digital signing, in a way that the current page gets a signature
widget inserted at the page center and then the user can move that signature widget to the desired
location.
Combining this with electronic signing is a bit more tricky, since we don’t want to select a
certificate when the signature widget is inserted, we’ll deal with that in the external service, as
usual.
Also, there was no real reason to not use visual signing unconditionally, so now the way to initiate
a signing process is to open your PDF in COOL, use the Insert → Signature line menu item to insert a
signature widget, move it to the wanted position, click “finish” on the snackbar and that completes
the process with the usual electronic signing popup.
The final problem was that our multi-page PDF viewer was not really prepared to deal with changed
PDF content (assuming your PDF rendering will not change is reasonable), so some last minute work
had to be done to make sure the signature widget’s graphical selection indicator, its dragging and
its rendering works fine even on non-first pages of a PDF document.
At the end, a test signature using the d-trust signature provider’s test environment looks like
this:
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.
Collabora Online now takes the visible area (viewport) of large
Writer documents into account in more cases, leading to better performance & interactivity.
Collabora Online has two kinds of "visible areas" for a document: on one hand, the entire document
is visible, so in case any part of the document changes, the browser client gets notified; on the
other hand, there is a viewport in the web browser, and keeping that up to date is a priority,
compared to the rest of the document.
There were some cases in the past where we handled the entire document with the same priority,
leading to slower than ideal update times on the UI.
Wouldn't it be nice to always update the visible part first, and only then deal with the rest, on
idle?
When looking at this topic, we noticed a cluster of problems:
First, consider the case of a long (~300 pages) document, where you insert a page break at the start
and wait for the update of the visible area. The entire document layout (now 301 pages) were
calculated, and now we do this for the visible area synchronously (and the rest on idle). This
operation is now about 19 times faster.
Second, loading a long document calculated the entire layout before showing the first page. This is
now improved, the document loading time itself at a LOK API level for such a long document is now
about 5 times faster.
Third, COOL didn't consider the priority of core tasks when interrupting to do its own work (COOL's
document editing process and LibreOffice core shares the same main loop). Now we do this,
categorizing the core tasks into "high priority" and "low priority" buckets and we only interrupt
when core doesn't have high priority tasks any more (this is only in 25.04).
Fourth, there was no easy access to a large Writer document during development. Now make run
COOL_WRITER_LARGE=y allows opening a long document in your local browser for development / testing
purposes.
Writer has the concept of paragraph margins and page margins, but what happens when you combine the
two? It turns out the expectation is that sometimes the top paragraph margin is ignored in this
case. We'll see two cases where the behavior of Writer is now improved to better match Word in this
regard.
This work is primarily for Collabora Online, but the feature is
available in desktop Writer as well.
As described in a previous bugreport,
there was a first problem where Word ignored the top paragraph margin of a document, but Writer did
not. A recent bugreport then pointed
out that the first implementation went too far and now a wanted top margin was ignored. This lead to
a set of conditions which now does a decent emulation of Word's rules in this regard.
You can get a development edition of Collabora Online 24.04 and try it out yourself right now: try
the development edition. 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 (25.2).
Impress shape text doesn't have much support for styles, e.g. the default UI in Writer gives you a
paragraph style dropdown, and you don't get the same in Impress. Still, a paragraph style is
attached to bullets based on their outline level, and Impress has a View → Outline menu item to give
you that styled text you can copy. Pasting that to Writer started to lose styles recently and it's
now fixed to work again.
This work is primarily for Collabora Online, but the feature is
available in desktop Impress as well.
As described in a previous
commit, I had a
case where lots of not needed paragraph styles were exported to RTF in case an Impress document had
enough master pages. The idea was to only export actually used paragraph styles, to avoid wasting
CPU power.
Turns out filtering out paragraph styles has to happen at two locations:
in the style table to assign an index to a paragraph style
when referring to those styles
The problem was that unused styles were removed from the style table, but not from the style → index
mapping, so as soon as you had both used and unused paragraph styles, the declared and the referred
style indexes didn't match anymore.
You can get a development edition of Collabora Online 24.04 and try it out yourself right now: try
the development edition. 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 (25.2).
Writer TextBoxes provide the user with shapes that can have complex geometry and complex content.
There is also a feature to capture shapes inside page boundaries: now the two features interact with
each other better.
This work is primarily for Collabora Online, but the feature is
available in desktop Writer as well.
As described in a previous post, Writer implements the TextBox
feature with a pair of objects: a Draw shape (with complex geometry) and a (hidden) Writer TextFrame,
providing complex content. To avoid wrapping problems, the underlying TextFrame always has its wrap
type set to "through", i.e. text may wrap around the Draw shape, but the hidden TextFrame is always
ignored during text wrapping.
In most cases this provides the expected behavior, because the user sees one object, so wrapping
around at most one object is not surprising.
However, there is also an other feature, that shapes may be captured inside page frames: if their
position would be outside the page frame, Writer corrects this, so they are not off-page. This also
makes sense, so it can't happen that your document has a shape that is hard to find, due to a silly
position.
The trouble comes when these two are combined: the Draw shape's position gets adjusted to be
captured inside the page frame, but the TextFrame's wrap type is "through", and objects with this
wrap type are an exception from the capturing mechanism, so the position of the two shapes get out
of sync.
The problem is now solved by improving the layout, so in case the TextFrame is actually part of a
Draw shape + TextFrame pair (forming a TextBox), then we calculate the effective wrap type of the
TextFrame based on the wrap type of its Draw shape, so either both objects are captured or none,
which results in consistent render result.
Here is a sample document where all margins are configured to be equal, but capturing corrected the
Draw shape (and not the TextFrame):
You can get a development edition of Collabora Online 24.04 and try it out yourself right now: try
the development edition. 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 (25.2).
The SVG export in Impress now supports a per-paragraph setting to handle semi-transparent shape
text, while previously this was only possible to control at a per-shape level.
This work is primarily for Collabora Online, but the feature is
available in desktop Impress as well.
As described in a previous post, Impress already
had the capability to have semi-transparent shape text, but the SVG export of this for the case when
not all paragraphs have the same setting was broken.
Transparency in SVG can be described as a property of a group (<g style="opacity: 0.5">...</g>)
and it can be also a property of the text (<tspan fill-opacity="0.5">...</tspan>).
The SVG export works with the metafile of the shape, so when looking for meta actions, it tries to
guess if the transparency will be for text: if so, it needs to use the tspan markup, otherwise
going with the g markup is OK.
What happened here is that meta action for a normal text started, so the SVG export assumed the text
is not semi-transparent, but later the second line was still transparent, so we started a group
element, and this resulted in a not even well-formed XML output.
You can get a development edition of Collabora Online 24.04 and try it out yourself right now: try
the development edition. 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 (25.2).
I recently worked with a document that has relatively simple structure, but it has 300 pages, and
most of the content is part of a numbered list. Pasting a simple string (like an URL) into the end
of a paragraph resulted in a short, but annoying hang. It turns out we updated Writer's layout for
all the 300 pages before the content was repainted on the single visible page. In theory, you
could reorder events, so you first calculate the first page, you paint the first page, then you
calculate the remaining 299 pages. Is this possible in practice? Let's try!
This is a good sample, because pasting into a numbered list requires invalidating all list items in that
list, since possibly the paste operation created a new list item, and then the number portion has to
be updated for all items in the rest of the list. So if you paste into a numbered list, you need to
re-calculate the entire document if all the document is just a numbered list.
The first problem was that Writer tracks its visible area, but LOK needs two kinds of visible areas.
The first kind decides if invalidations are interesting for part of the document area. LOK wants to
get all invalidations, so in case we cache some document content in the client that is near the
visible area, we need to know when to throw away that cache. On the other hand, we want to still
track the actually visible viewport of the client, so we can prioritize visible vs hidden parts of
the document. Writer in LOK mode thought that all parts of the document are a priority, but this
could improved by taking the client's viewport into account.
The second problem was that even if Writer had two layout passes (first is synchronous, for the
visible area; second is async, for the rest of the document), both passes were performed before
allowing a LOK client to request tiles for the issued invalidations.
This is now solved by a new registerAnyInputCallback() API, which allows the LOK client to signal if
it has pending events (e.g. unprocessed callbacks, tiles to be painted) or it's OK for Writer layout
to finish its idle job first.
The end result for pasting a URL into this 300 pages document, when measuring end-to-end (from
sending the paste command to getting the first updated tile) is a decrease in response time, from
963 ms to 14 ms.
You can get a development edition of Collabora Online 24.04 and try it out yourself right now: try
the development edition. 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 (25.2).
Font embedding is meant to solve the problems around missing fonts, but you can also find documents
with stub embedded fonts that are to be ignored and our code didn't have any sanity check on such
fonts, leading to unexpected glyph-level fallbacks. Additionally, once font-level fallback happened,
we didn't take the font style (e.g. sans vs serif) into account, which is expected to work when
finding a good replacement for the missing font.
Once the handler for the embedded fonts in ODT/DOCX was improved to ignore stub fonts where even
basic glyphs were not available, the result was a bit more consistent, but still bad. Here is a
different document to show the problem:
Note how now we used the same font, but the glyphs are always sans, not serif. So the final step was
to import the font type from DOCX and consider that while deciding font fallback:
With this, we ignore stub embedded fonts from DOCX, we import the font type and in general font
fallback on Linux takes the font type into account while deciding font fallback.
You can get a development edition of Collabora Online 24.04 and try it out yourself right now: try
the development edition. 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 (24.8).
As described in a post from 2014,
Writer reads the drawingML markup for shapes in DOCX files, including line shapes. While
investigating a simple-looking problem around a horizontal vs vertical line, it turns out that there
is a deeper issue here, and it looks like now have proper fix for this bug.
Imagine that your company template has a nice footer in two columns, and the content in the columns
are separated by a vertical line shape, but when you open your DOCX in Writer, it crosses the text
of that footer instead:
While researching how line shapes are represented in our document model and how ODT import works, it
turned out that the proper way to create a line shape is to only consider size / scaling when it
comes to the individual points of the line, everything else (e.g. position / translation) should go
to the transform matrix of the shape, then the render result will be as expected:
It was also interesting to see that this also improved other, existing test documents, e.g. core.git
sw/qa/extras/ooxmlimport/data/line-rotation.docx looked like this before:
Just stick to the rule: scaling goes to the points -- translation, rotation and horizontal shear
goes to the shape.
For now, this is only there for toplevel Writer lines, but in-groupshape and Calc/Impress lines
could also follow this technique if there is a practical need.
The "after" screenshots show ~no red, which means there is ~no reference output, where the Writer
output would be missing.
You can get a development edition of Collabora Online 24.04 and try it out yourself right now: try
the development edition. 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 (24.8).