LO/COOL Book Project
State-of-the-art readability and typography of ISO document formats by DTP-compliant microtypography, default optical sizing, document and baseline grid tools for multi-column pagination in open source office suites
1Summary
LibreOffice, the open source office suite is the reference implementation of ISO OpenDocument (ODF) format. As part of LibreOffice Technology, Collabora Online is key for the digital sovereignty of open source online document editing. The previous LO/COOL Typography project has fixed the lost paragraph layout interoperability of Writer word processor by implementing several ISO OOXML/MSO DOCX interoperability features, including the new line break algorithm introduced in MS Word 2013 (see development report). This continuation enhances readability of text document stored in ISO document formats by adding microtypography, paragraph-level line breaking and better variable font and multi-column pagination support to Writer. It results a new type of software with the print quality of proprietary DTP programs and with productivity and ISO document format support of word processors.
The improved paragraph layout with consistent text density, without rivers of white, also the improved font and grid support allow multi-column pagination on typewriter papers used in schools, public administration, organizations and at home printing, achieving the optimal line length and word spacing proposed by accessibility and typography experts.
Main parts of the project:
Microtypography (by László Németh) • following the previous custom word spacing developments, add custom letter spacing (tdf#167648) and glyph scaling (tdf#168251) to get readable multi-column pagination (which is the proposed pagination for typewriter papers to avoid too long lines for children and for people with reading disabilities);
Paragraph composer (by László Németh) • remove remaining rivers of white and huge word spacing by paragraph-level justification like DTP software do, combined with custom level of hyphenation (tdf#38159/ooo#3243);
Optical font sizes (by Khaled Hosny) • following web standards and web typography, apply default optical sizing using variable fonts with optical compensation to get more readable small and large text and better typography (tdf#153368);
Variable fonts • Support design-variation features and named instances of variable fonts to get real readable bold, condensed and slanted font variants instead of unacceptable letter distortion of word processors (tdf#152396, tdf#35538);
Document grid (by Tamás Zolnai) • fix lost visibility and precision of document grid on normal high-resolution displays, restoring one of the most important tools for multi-column pagination (tdf#89544, tdf#48245);
Baseline grid (by Tamás Zolnai) • add basic design tool of DTP software to guarantee minimum typography requirements of multi-column pagination (~tdf#144542).
The results are integrated with the main development branch of LibreOffice, documented by a development report with description of the manual testing, and depending on the task, contain automated unit and regression testing.
2Microtypography 1: Maximum letter spacing
by László Németh
Already minor, 3–5% expansion of letter spacing can minimize rivers of white and bad word spacing a lot, especially in narrow columns, where it’s not possible to get the desired word spacing only by hyphenation and minimum/maximum word spacing.
Figure 1: Demonstration of maximum letter spacing. Depending on the justified lines (e.g. no space or no hyphenation), it’s possible to use bigger letter spacing, than the approved 3–5%. (original PDF version: letter_spacing_demo.pdf).
Figure 2: GIF animation of maximum word spacing, resulting the desired word spacing by enlarging letter spacing. Its proposed value is 3% for normal line width (70-80 characters), and 5% or more for narrow paragraphs (35-70) or paragraphs with no no or limited hyphenation.
2.1Developments
Description |
tdf#167648 cui offapi xmloff sw: add DTP-feature maximum letter spacing (commit: f83a04c51056445bbf947a31c8c1866a5c30bef1) Add new paragraph justification option "Maximum letter spacing" to distribute letters on (part of) the available blank area of the justified line instead of overstretching word spacing, like DTP software do. This improves typography a lot, allowing typesetting visually better i.e. more readable paragraphs, minimizing or removing rivers and too big word spacing (which was common in columns or text without hyphenation). – Add spin box to Alignment in paragraph formatting dialog window, (also add spin boxes for future Minimum and the alternative percent-based Desired letter spacing, see CharKerning); For example (only ASCII visualization!), 100% maximum letter spacing adds a space character-width blank space between the characters, including the original space: 0%: Lorem ipsum pellentesque dolores vitae. 100%: L o r e m i p s u m pellentesque dolores vitae. Normal value: 3%-5% (or more for very narrow columns), which means e.g. 1-2 twips (twip = 1/20 pt) letter spacing in a ~12 pt text. Note: resolution of the custom letter spacing is only 1 twip yet. – Store properties in paragraph model: css::style::ParagraphProperties::ParaPropLetterSpacingMaximum css::style::ParagraphProperties::ParaPropLetterSpacingMinimum Note: desired letter spacing is already supported by ODF/UNO, see css::style::CharacterProperties::CharKerning. – Implement visual layout of maximum letter spacing. Note: after the last character of the line, there is an unwanted letter-spacing, yet (which is visible only with big letter-spacing values). – Add ODF import/export (loext:letter-spacing-maximum and loext:letter-spacing-minimum) – Add ODF unit test. Note: hyphenated lines and lines with multiple portions do not yet use custom letter spacing, yet. |
2.2Manual testing
Daily builds of LibreOffice allow to check the improvements:
1. In Writer, open the test document tdf167648_0_5_25_and_100_percent_letter_spacing.fodt of Bug 167648. The document contains four paragraphs. Maximum letter spacing of the paragraphs are 0%, 5%, 25% and 100%, which is visible in the size of the word spacing and size of letter spacing. (PDF version of the test document: https://bug-attachments.documentfoundation.org/attachment.cgi?id=202097).
2. Test direct formatting: Select the first paragraph or put the test cursor inside it. Open paragraph formatting dialog window using Format→Paragraph menu item, and choose the Alignment pane. Modify Maximum letter spacing to 15% and press Enter. The result is word spacing nearer to the desired one by bigger letter spacing, between the second paragraph (5%) and the third paragraph (25%).
3. Test paragraph style: Open paragraph style formatting dialog window using Styles→Edit Style… menu item. Choose Alignment pane and select Justified alignment in Options. Set the maximum 500% Maximum letter spacing, and press Enter. Remove direct paragraph formatting by selecting the whole text and Format→Clear Direct Formatting. All paragraph lines get the desired word spacing, using (too) big letter spacing.
3Microtypography 2: glyph scaling and minimum letter spacing
by László Németh
In this task, the following microtypography elements were implemented: 1) minimum letter spacing, as continuation of the previous maximum letter spacing, 2) minimum and maximum glyph scaling, i.e. compression and expansion of letters. (Desired glyph stretching and desired letter spacing are already implemented by as Scale width and Character spacing on Format → Character… → Position pane.)
Already minor, 1–3% glyph scaling can minimize rivers of white and bad word spacing a lot, especially in narrow columns, where it’s not possible to get the desired word spacing only by hyphenation and minimum/maximum word spacing. Combined with maximum and minimum letter spacing, glyph scaling is the basic element of microtypography used by DTP software.
In Writer’s implementation of the algorithm, letter spacing has got greater priority over glyph scaling yet: when maximum letter spacing and the available word spacing allow, only letter spacing is applied. When using maximum letter spacing is not enough for the desired word spacing, also glyph scaling is applied in the line.
Figure 3: Demonstration of minimum/maximum letter spacing and glyph scaling. The original paragraph (top left) is variously optimized with combination of the four settings, eliminating rivers of white and blank spaces (original PDF version: tdf168251_demo.pdf).
Figure 4: GIF animation of maximum glyph scaling, resulting the desired word spacing by enlarging letter width by distortion. Its proposed value is 1–3% for normal line width (70-80 characters), and 1–5% or more for narrow paragraphs (35-70) or paragraphs with no no or limited hyphenation. Note: at recent letter distortion of Writer glyph scaling, vertical and horizontal lines lose their uniformity, resulting unacceptable glyphs at greater values, so the animation is only for demonstration. Supporting design-variation width axis of variable fonts can result in using greater values without letter distortion.
3.1Developments
Description |
tdf#167648 sw letter spacing: implement minimum letter spacing (commit 3c53797210bf0a4e3ffb36ed2beac4d5ce229ff2) Implement new paragraph justification option "Minimum letter spacing" allowing to shrink text lines more, choosing better paragraph layout instead of hyphenation or rivers of space. * Implement visual layout of minimum letter spacing. * Enable Minimum letter spacing spin box on Alignment pane of the paragraph formatting dialog window * Remove also desired letter spacing spin box from the alignment pane. It will be better to visualize CharKerning with percentage value instead of adding a new user interface to the same setting. * Set minimum and maximum spin box ranges to [-100, 0] and [0, 500], and remove unnecessary handlers. * offapi: extend API description with ranges of letter spacing [-100, 500] and word spacing ([0, 1000]). * Add ODF unit test. Note: hyphenated lines, lines with multiple portions haven’t been using custom letter spacing, yet. Note: resolution of the custom letter spacing is only 1/20 point (1 twip) yet. Note: adjust testTdf163149 failing on a test machine, maybe because the DOCX test document contains the not supported Arial font, resulting small differences based on the font replacement. Follow-up to commit f83a04c51056445bbf947a31c8c1866a5c30bef1 "tdf#167648 cui offapi xmloff sw: add DTP-feature maximum letter spacing". |
tdf#168251 cui offapi xmloff sw glyph scaling: extend UNO/UX/ODF (commit: 45ec7bd76196dcc60b4c2db2f6f00623ecbaf5a4) Add new paragraph justification options "Minimum glyph scaling" and "Maximum glyph scaling" to improve typography, like DTP software do, allowing to typeset visually better paragraphs, especially narrow columns without unacceptably big word spacing. * Add spin boxes to Alignment in paragraph formatting dialog window; * Store properties in paragraph model: css::style::ParagraphProperties::ParaPropScaleWidthMinimum css::style::ParagraphProperties::ParaPropScaleWidthMaximum Note: desired glyph scaling is already supported by ODF/UNO, see css::style::CharacterProperties::CharScaleWidth. * Implement visual layout of minimum and maximum glyph scaling, limited by the available extra word spacing and letter spacing, too. Note: last line can exceed the paragraph width, because minimum glyph scaling, also minimum letter scaling of the last line haven't been applied there, yet. * Add ODF import/export (loext:text-scale-maximum and loext:text-scale-minimum, where style:text-scale is for the desired text scaling). * Add ODF unit test. Note: hyphenated lines, lines with multiple portions haven't been using custom glyph scaling, yet. Note: resolution of glyph scaling is 1 percent, which will avoid of overgeneration of font types using variable fonts. |
tdf#167648 sw letter spacing: fix division by zero (commit: 9d8a54d4b65e9f16dee05c8152cfe4bd68f0b047) /sw/source/core/text/portxt.cxx:351:90: runtime error: division by zero #0 0x7f7bf4700824 in SwTextPortion::SetSpacing(SwTextFormatInfo&, o3tl::strong_int<int, Tag_TextFrameIndex>, int, short) /sw/source/core/text/portxt.cxx:351:90 (<https://ci.libreoffice.org//job/lo_ubsan/3669/>) Regression from commit 3c53797210bf0a4e3ffb36ed2beac4d5ce229ff2 "tdf#167648 sw letter spacing: implement minimum letter spacing". |
3.2Manual testing
Daily builds of LibreOffice allow to check the improvements:
1. In Writer, open the test document tdf168251_demo.fodt of Bug 168251. The document contains six paragraphs with different minimum/maximum letter spacing and glyph scaling combinations (Figure 3. PDF version of the test document: https://bug-attachments.documentfoundation.org/attachment.cgi?id=202747).
2. Test minimum letter spacing: Select the first paragraph or put the test cursor inside it. Open paragraph formatting dialog window using Format→Paragraph menu item, and choose the Alignment pane. Modify Minimum letter spacing to –3% and press Enter. The second line contains 4 words “consectetur adipiscing elit. Vestibulum”, not 3 words (“consectetur adipiscing elit.”) any more.
3. Test maximum glyph scaling: in the previous settings, set also the maximum 200% Maximum glyph scaling and press Enter. The paragraph lines contain the desired word spacing instead of 3–6 times bigger blank spaces.
4. Test minimum glyph scaling: in the previous settings, set also minimum glyph scaling to 97%. The 5th line contains 5 words, not 4 words any more: “quis commodo dolor posuere. Curabitur”, not “quis commodo dolor posuere.” any more.
4Microtypography 3: hyphenation, multi-portion etc.
by László Németh
These developments extended microtypography developments for 1) hyphenated lines and 2) other text lines with multiple text portions, for example, containing emphasized words. Moreover, they 3) fixed text cursor positions during moving in the compressed or expanded text line with reduced or enlarged letter spacing and 4) removed the unnecessary blank space at the end of lines with enlarged letter spacing (Figure 5).
Figure 5: Problems of the first implementation of microtypography: 1) enlarged letter spacing was applied at the end of the lines, too, resulting bad justification (yellow bar). 2) there was no microtypography in lines with multiple text portions, resulting huge word spacing (blue circle). 3) There was no microtypography in hyphenated lines. 4) Where microtypography was enabled in multiportion lines by accident, the result was missing word spacing or justification (red box) (original PDF version: tdf169168_new_annotated.pdf).
Figure 6: Solved problems: 1) removed blank space at the end of the lines, 2) applying microtypography in lines with multiple text portions, 3) applying microtypography in lines with hyphenation, 4) fixed word spacing and justification (original PDF version: tdf169168_newer.pdf).
Figure 7: For comparison, the test document opened in an old Writer version before the microtypography developments: it contains huge word spacing and rivers of white (original PDF version: tdf169168.pdf).
4.1Developments
Description |
tdf#168448 sw letter spacing: enable it + glyph scaling at hyphenation (commit d86f68e6b845f65896c1ffc4f55d09ec48fd9840) Letter spacing and glyph scaling were disabled in hyphenated lines because of their broken layout. Now the hyphen mark is positioned correctly at the end of the line, not before that, applying plus letter spacing and glyph scaling on horizontal position of the hyphen portion, and without expanding the text over the hyphen portion. |
tdf#169168 sw letter spacing: extend it for multiportion lines (commit: 97f97ba44e6af2be2e94ae26054b060b0303933a) Enable custom letter spacing and glyph scaling for multiportion lines, i.e. lines with emphasized and underlined words, or lines hyphenated automatically or with soft hyphen etc. For this, width of the text portions are modified temporarily according to the actual available blank space of the lines at processing the last text portion. Depending on the filling of the text line with text portions during line breaking, portion width data are changed back and forth. Note: Letter spacing and scaling data are stored in SwLineLayout instead of SwTextPortion. Other fixes and changes: – itrcrsr.cxx: text cursor position follows the custom letter spacing and custom glyph scaling applied in the line; – itradj.cxx: at letter spacing, the enlarged blank space is removed after the last letter in the line, fixing jittering of the right side of the lines. – guess.cxx: fix crashing during typing before a terminating text portion; – portxt.cxx: fix bad letter spacing, when the line contains zero width characters (soft hyphen, zero-width space etc.); – testTdf168351: extend test document, because compression is not applied in the last line any more. Note: this is likely not a problem (in fact, it's the opposite, because filling the last line completely can destroy the clear separation of the paragraphs, especially without first line indent). – testTdf168251 and testTdf168448: adjust the tests according to the fixed line breaking. |
tdf#168351 sw letter spacing: fix spaces in the last line (commit: 33f20d0a0fb32bf4452c15c6ae0e7c85b2ee6d46) Minimum letter spacing and glyph scaling were applied in the last paragraph line incompletely, because of missing update of the break width, when the last two paragraph lines were compressed into a single one. This resulted in calculating more blank space, than available, and positive kerning, also glyph expansion with missing word spacing and overlapping words, instead of negative kerning and glyph compression for the desired word spacing. |
tdf#168528 sw letter spacing: fix freezing with minimum spacing/scaling (commit: 8306c4e86aacfe0e2a7b2aedb88c404735dccdcd) Fix never-ending loop in SwTextFrame::Format_() resulted by bad compression of lines with COMPLETE_STRING cut position. Note: to test the fix of the rare freezing, a subset font has been created from Source Serif 4 Variable, and embedded in the test file. Follow-up to commit 33f20d0a0fb32bf4452c15c6ae0e7c85b2ee6d46 "tdf#168351 sw letter spacing: fix spaces in the last line"… |
tdf#168528 sw letter spacing: fix false alarm with missing font (commit: e03dbd2e30805c4d84e772e0509dd0fc1c8a89ae) Font used by the test is embedded in the document, but modules with enabled gb_CppunitTest_set_non_application_font_use failed with false alarms. As a quick fix, move the test into sw_core_text, where gb_CppunitTest_set_non_application_font_use is not enabled, and revert the vcl exception added for the test previously. Regression by 8306c4e86aacfe0e2a7b2aedb88c404735dccdcd "tdf#168528 sw letter spacing: fix freezing with minimum spacing/scaling". |
4.2Manual testing
Daily builds of LibreOffice allow to check the improvements:
1. In Writer, open the test document tdf169168.odt of Bug 169168. The document contains 2-2 paragraphs in 12 sections. The first column contains only custom letter spacing. The second one contains only custom glyph scaling. The last one contains combined custom letter spacing and glyph scaling. Second paragraphs of the sections contain multiple text portions, i.e. different line parts with italic, bold or underlined text formatting. Now microtypography is applied in these lines, too, resulting smaller word spacing. (Figure 5. PDF version of the test document: https://bug-attachments.documentfoundation.org/attachment.cgi?id=203649). (Note: for better visibility of the developments, the tests use bigger values for custom letter spacing and glyph scaling, than proposed.)
2. Test multiportion lines with microtypography: select the first word “Lorem” of the document, and apply bold formatting. Remove the first two letter of the word. Result: letter spacing follows the changes, keeping normal word spacing and justification. Note: when the text portion matches the line boundary exactly, microtypography is not applied yet (i.e when the first word of the second line is underlined, but not the last word of the first line).
3. Test hyphenated lines: in the HYPHENATION sections, remove the first and the second letter. Result: the letter spacing and glyph scaling follow the changes, keeping normal word spacing and justification in the lines hyphenated automatically. Note: soft hyphens support only glyph scaling, but not letter spacing, yet.
4. Test removed blank space at line end: Open the document again to restore the first paragraph. Start to delete the first letters by pressing Delete. The end of the line touches the right border of the paragraph, i.e. no visible blank space between them, as previously. (Note: an exception, when the paragraph starts with a space, which is a typographic/editing mistake in itself.)
5. Test cursor position: Put the text cursor in the first letter of the document, and press right arrow multiple times: now the cursor follows the letters with reduced/enlarged letter spacing, too. Note: mouse clicking doesn’t follow the changed letter positions yet.
5Fix document grid 1: visualization
by Tamás Zolnai
In Writer, the grid functionality had a visibility problem compared to other LibreOffice applications, such as Draw and Impress. Writer rendered the grid using light-gray, 1-pixel dots that were barely visible for comfortable work. Learning from the design decisions made for Draw and Impress, we implemented the same behavior for Writer (and also for Calc), improving the user experience for the future use of the grid functionality. With this change, grid now has a consistent appearance across all four main applications of LibreOffice.
Figure 8: Grid’s visual appearance in Writer before the fix
Figure 9: Grid’s visual appearance In Writer after the fix
Besides improving the visibility of the grid in Writer (and in Calc), some bugs were also identified in the algorithm originally used for positioning and rendering the grid markers. These bugs were also investigated and fixed. Increasing the visibility of the grid would have also increased the visibility of these issues of the rendering code.
5.1Developments
Description |
tdf#89544: Change default grid color to a darker gray in Writer (commit: 592df0a2e5e838567f1c8a1e0983e9ffd9886502) The same change was made earlier for Impress / Draw. Grid in Writer has the same issue in terms of visibility. Apply the same default color in this case. See tdf#117348. |
tdf#89544: Display small, 3x3 pixel crosses for main grid points. (commit: 5eac589ffae1bf1ea027d48ce52a6ae20f67084e) In Writer (and in Calc). To improve visibility of the grid. The same happens in Draw and in Impress. Implement the same behavior for Writer (and Calc). Writer is the main scope, but Calc shares the rendering code with Writer and I don’t see a good reason to increase the complexity of the code by defining different behavior for Calc. |
tdf#169226: Avoid rendering grid points outside of the drawing area in Writer. (commit: e49b92a479dc88f02c4adeb9db732d9b5c11b9bc) The drawing area might be very small. The code always drew the first segment of the grid without considering that this segment might not be fully visible. |
tdf#169311: Improve accuracy of rendering of grid points in Writer. (commit: b3ea96543b61a02017350fecae53b4c6637915a9) Before: The first visible grid point was used as anchor point which could be a main grid point or a secondary grid point. However because of the inevitable numeric imprecisions, different anchor points lead to different final position values (one pixel differences). After: A main grid point is used as anchor point, whose position can be determined precisely. Whichever grid points are actually visible in the current painting area the selection of anchor point is consistent and so the final position value will be too. |
tdf#169384: Apply proper subdivision settings by startup in Writer. (commit: 28c842ba5271947a47d32cf70077b2b6fe28eeec) Internal division numbers need to be increased by one to get proper grid distance values. See also SwViewShell::ImplApplyViewOptions() method which applies grid settings in other use cases. |
5.2Manual testing
Daily builds of LibreOffice allow to check the improvements:
1. Test visualization of grid in Writer (tdf#89544, tdf#169311). Open an empty document in Writer and enable the grid using View → Grid and Helplines → Display Grid. Zoom in, zoom out and scroll through the document. Writer displays a 3×3-pixel cross for the main grid points and a 1-pixel dot for the secondary grid points, both in dark gray.
2. Test rendering with different grid settings (tdf#89544). Open Tools → Options… → LibreOffice Writer → Grid settings page. Change the resolution or subdivision values to check how they are rendered in the document. Both main grid points and secondary grid points are rendered correctly according to the specified resolution and subdivision.
3. Test that grid settings are properly applied after restarting Writer (tdf#169384). Ensure that the grid is displayed before closing Writer. Then open a new document and verify that the number of subdivision points reflects the previously defined settings. Note: Grid settings are part of the user preferences and therefore they persist after a document is closed.
4. Test proper rendering of grid at the bottom of the document (tdf#169226). Open a document, set the zoom level to 100% and scroll from the top to the bottom of the document. The grid appears only within the drawing area defined by the margins.
6Fix document grid 2: snap to grid
by Tamás Zolnai
In Writer, a long-standing issue with the grid functionality is that snapping objects to the grid is inaccurate. Depending on the zoom level or the defined page margins, this inaccuracy can be very small or quite noticeable. The first report of this issue dates back to 2003, before LibreOffice was forked from OpenOffice.org.
Figure 10: Snap to grid accuracy in Writer before the fix
Figure 11: Snap to grid accuracy in Writer after the fix
6.1Developments
Description |
tdf48245, tdf126493: Fix snap to grid accuracy in Writer (commit: d74bf7117b6f71b222ba06c4341d51524c35952e ) In case of Writer the grid has a different origin, than for other applications (Impress, Calc, Draw). For Writer there are multiple grids (one grid per page). Replicate the behavior of the grid drawing code to identify the proper grid origin. See SdrPageView::DrawPageViewGrid(). The grid is drawn in the user area, but use the wider "paper rect" to identify the correct grid frame for snapping. So there isn’t an abrupt change in snapping behavior when an object moves outside the printing area (partly or entirely). Do some extensive testing of snap to grid functionality. There were no tests for it yet. |
6.2Manual testing
Daily builds of LibreOffice allow to check the improvements:
1. Test snapping to grid while inserting a shape in Writer. Open an empty document, enable “display grid” and “snap to grid” features: View → Grid and Helplines → Display Grid and View → Grid and Helplines → Snap to Grid. Insert a rectangle shape onto the grid: Insert → Shape → Basic Shapes → Rectangle. While drawing the shape using drag-and-drop, the edges of the new rectangle accurately snap to the grid points. Note: Both main grid points and secondary grid points serve as snapping positions.
2. Test snapping of an existing shape. Open an empty document and insert a shape while all grid related options are disabled. Then enable “display grid” and “snap to grid” features. Resize the shape to align it with the grid. While resizing the object using drag-and-drop, the shape’s edges accurately align with the grid. Resize the shape in all four directions to align with the grid, then move the shape using drag-and-drop. While moving the shape, its new position follows the grid points.
3. Test snapping a line shape to the grid. Open a new Writer document and enable “display grid” and “snap to grid” features. Then insert a line shape into the document: Insert → Shape → Line → Line. Try connecting two main grid points with the new line shape. While drawing the line using drag-and-drop, the line accurately snaps to the grid points.
4. Test snapping a text frame to the grid. Open a new Writer document and enable “display grid” and “snap to grid” features. Then insert a text frame into the document: Insert → Frame → Frame Interactively. While drawing the text frame using drag-and-drop, the frame’s edges accurately snap to the grid points.
7Add baseline grid
by Tamás Zolnai
LibreOffice Writer has had a page line-spacing feature for some time (previously called register-true typesetting). Page line-spacing aligns all affected text to an invisible vertical grid. With the new baseline grid feature, this previously invisible grid can now be displayed, allowing users to verify whether page line-spacing has been applied correctly and whether text is aligned consistently across pages and paragraphs (for example, when printing a book).
Figure 12: New baseline grid feature in Writer.
The baseline grid is calculated based on the reference style defined for the page line-spacing. If page line-spacing is not enabled for a given page, the standard reference style (i.e. Body Text) is used to position the baseline grid. The color of the baseline grid can be customized, it has a dark gray color by default.
Figure 13: Custom color baseline grid on page columns
The baseline grid feature also helps identify issues with the page line-spacing feature in LibreOffice. During the implementation and testing of the baseline grid, two such issues were identified: tdf#169922 and tdf#170000.
7.1Developments
Description |
tdf#169806: Display baseline grid for page line-spacing. (commit: 6f46f068d48310e43f09f3c5b0b73080995a2105) 1. Add a new option to the Grid tab page for displaying the baseline grid. * Add a new checkbox to LibreOffice Writer -> Grid tab page to enable/disable displaying of the grid. * Make the new option hidden by default and show it only for Writer normal view (see SwGridTabPage class). * Rename the tab page title from "Grid" to "Grids" to reflect the new content of the tab page (options for two different types of grids).
2. Add a new configuration option for displaying the baseline grid. * Extend Writer configuration with a new section for baseline the grid option(s). * Introduce a new ConfigItem for the new baseline grid related option to allow saving it to and loading it from the user preferences. (see SwBaselineGridConfig class). * Handle the possible read-only state of the configuration option and lock the related checkbox on the grid tab page, if necessary.
3. Compute the proper position of the baseline grid's horizontal lines. * First, extract the ComputeRegister() method to calculate the proper height/ascent values used for register-true rendering. * Use this ComputeRegister() method to calculate the proper height/ascent values both for the text formatting code and for the drawing code of the baseline grid.
4. Draw the baseline grid. * Draw the grid based on the reference style used by page line-spacing, if specified. * If there is no page line-spacing set, use the "standard" reference style (i.e. "Body text"). * Draw the baseline grid on top of other objects (e.g. shapes, frames), so the user can verify the text alignment inside these objects as well. * Trigger a repaint of the whole page if the baseline grid is visible and page line-spacing settings are changed.
5. Don't display the baseline grid when printing. * Don't display the grid for print preview, for printing, or for exporting to PDF. |
tdf#169806: Add customizable color for baseline grid. (commit: 9ebbdb3db96af8b07a85a907fe71697d62b8ea74) |
tdf#169806: Add baseline grid feature to Writer menu. (commit: 2f1136f178a7b74a5af3856342d3e1cb332e3fc7) * Create a "Display Baseline Grid" menu item, which triggers the rendering of the baseline grid. * Rename the parent menu item from "Grid and Helplines" to "Grids and Helplines" (plural grids). * Display the new menu items for Writer normal mode and master document mode (not shown in web mode, for example). |
tdf#169806: Add baseline grid feature to notebook bar. (commit: 4124b83635c2b2dd3a343ce2d61fbb11f72d5162) |
tdf#169806: Add new baseline grid feature to help pages. (commit: ef7c93eaa59b5cd398c2c9719084e44dd10cd1bf) |
tdf#169806: Add icon for new "Grids and Helplines" menu item. (commit: 0f5add6cd2fd2f68f6fe0cdfdde41f181af06232) Reuse the icon from the original "Grid and Helplines" menu item. |
tdf#169806: Fix saving baseline grid configuration option on Windows. (commit: 792fca692594a642762c8ea62581d43fb56300d4) |
7.2Manual testing
Daily builds of LibreOffice allow to check the improvements:
1. Test displaying the baseline grid for a document with page line-spacing enabled: Open the test document from the bug report and display the baseline grid: Tools → Options → LibreOffice Writer → Grids → Baseline Grid → Visible grid. The displayed baseline grid aligns with the text in the document. Note: This test document has page line-spacing enabled for all paragraphs.
2. Enable the baseline grid via menu: Open the test document from the bug report and display the baseline grid via menu: View → Grids and Helplines → Display Baseline Grid. The displayed baseline grid aligns with the text in the document.
3. Test changing the color of the baseline grid: Open the test document from the bug report and display the baseline grid via menu: View → Grids and Helplines → Display Baseline Grid. Change the color of the baseline grid at the following location: Tools → Options → LibreOffice → Appearance → Customizations → Baseline grid. The displayed baseline grid changes its color to the selected new color.
4. Test updating the baseline grid when changing page line-spacing: Open the test document from the bug report and display baseline grid via menu: View → Grids and Helplines → Display Baseline Grid. Change the reference style of the page line-spacing at the following location: Format → Page Style… → Page → Layout Settings → Reference Style. Select “Title” as reference style. All text in the document is realigned based on the “Title” style and the baseline grid is also updated with a larger distance between the grid lines.
8Fix page line-spacing issues
by Tamás Zolnai
The page line-spacing feature makes LibreOffice Writer more suitable for desktop publishing and enables more refined text layout control. However, there were some uses cases in which this feature did not work properly. Within this project, the following issues were fixed to enhance the usability of this feature:
1. Text inside frames was not aligned properly to the baseline grid (tdf#93785).
2. Text inside multi-column sections was not aligned properly to the baseline grid (tdf#170000).
3. Proper page line-spacing alignment was lost after removing a page (tdf#169922).
(+1. Vertical text in tables disappeared when page line-spacing was enabled (tdf#169821).)
Figure 14: Fixed page line-spacing formatting within frames.
8.1Developments
Description |
tdf#93785, tdf#170000: Fix page line-spacing formatting in sections and frames. (commit: 2b47f4090df08fd70b6f51bafd11acc56b3998df) The offset position (RegStart) for page line-spacing should be defined by the body frame of the given page to be aligned with the baseline grid properly. For fly frames and sections with their own body frame, this offset was incorrectly defined based on another layout frame. Since a fly frame can be outside of the page’s body frame, we also need to align the line height calculation to handle this corner case. |
tdf#169922: Apply page line-spacing properly after removing a page. (commit: 39018ea836bb73862a9fa509f375ee88750dc93f) The invalidation code tries to minimise what needs to be recalculated and reformatted in specific scenarios when a text frame is modified. In this case, the code attempted to calculate the new line height determined by the page line-spacing using invalid frame area. When we don't have valid frame print area information, we can't compute the new text alignment incrementally, so a full reformat is required instead. |
tdf#169821: Ignore vertical text when applying page line-spacing. (commit: a967abc63f7962639e88624cfe3bb545a10e9efa) It does not make sense to try to align vertical text to a horizontal grid line. The text formatter code attempted to align the text to the baseline grid, which led to an integer underflow for top-to-bottom text, resulting in a line height of -64667. |
Add unit tests for page line-spacing in preparation for future development. (commit: a1f1204dd2360015af41c51282900ecb28ec5472) |
Add more unit tests for page line-spacing. (commit: 9c56e440d80b74a8a2ffe22264f64d5a8f2ea361) |
8.2Manual testing
Daily builds of LibreOffice allow to check the improvements:
1. Test page line-spacing inside frame (tdf#93785): Open the test document from the bug report and display the baseline grid via menu: View → Grids and Helplines → Display Baseline Grid. The text inside the frame aligns with the baseline grid.
2. Test page line-spacing alignment while moving a frame (tdf#93785): Open the test document from the bug report and display the baseline grid. Move the frame around in the document using drag-and-drop. The text inside the frame aligns with the baseline grid after every movement.
3. Test page line-spacing inside a multi-column section (tdf#170000): Open the test document from the bug report and display the baseline grid. The text inside the multi-column section aligns with the baseline grid.
4. Test page line-spacing after removing a page (tdf#169922): Open the test document from the bug report and display the baseline grid. The text on all pages aligns properly with the baseline grid. Then remove the second (empty) page. After the page is removed, the text is still aligns properly with the baseline grid.
9Optical font sizes and better variable font support
by Khaled Hosny (Alif Type)
With these series of commits (and other foundational changes before them), I have added support for OpenType opsz axis (Support optical size for OpenType variable fonts: tdf#153368), also more efficient PDF export of variable fonts:
1. A new font-optical-sizing property (under loext namespace for now), modeled after the similarly named CSS property: https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/font-optical-sizing
2. When enabled, the opsz axis (for fonts that support it) is set to the font’s point size.
3. In Writer, Draw, and Impress, optical sizing is enabled by default for new documents.
4. For backward compatibility, it remains disabled by default for old documents.
5. The Position tab of the Character dialog has a new Optical Font Sizing option.
6. ODF importing/exporting supports the new property.
7. HTML importing/exporting uses the CSS equivalent.
8. PDF export instances the font into static instances and embeds them as regular fonts (no more Type 3 fonts, except for CFF2). This should be more efficient (e.g. faster rendering, smaller file size) and preserve most font data like hinting.
Figure 15: Test document that uses https://fonts.google.com/specimen/Fraunces, with above text enabling Font Optical sizing, and below text disabling it. Notice how the above text gets more thinner strokes as the font size increases and some letters (like h, n, and s) change there shape compared to the smallest point size.(OpticalFontSizing.odt, OpticalFontSizing.pdf)
Figure 16: Screenshot of the Position page of the Character formatting dialog window with the new Optical Font Sizing checkbox. Optical font sizing is applied in the font preview, too.
Figure 17: Comparison of embedded fonts of Writer PDF exports in GNOME Document Viewer (Evince) before and after, setting also bold formatting on the first letter “W” of the test document before the PDF exports. Top: from LibreOfficer 25.8, bottom: from development version of LibreOffice (26.8). The old export contains only two “No name” Type 3 fonts for the regular and bold formattings. The new one contains static TrueType fonts for all optical sizes (regular, 21 pt, 44 pt, 96 pt), and the two used weights, regular (width=400) and bold (weight=700). The embedded fonts are named correctly according to the design-variation axes “opsz” and “wght” of the font “Fraunces”.
9.1Developments (optical sizing)
Description |
Use HarfBuzz for instancing variable fonts (commit: 7ffb13159276c0a74ce4fffc49bb0da4a1950f1d) Instance variable fonts into static instances for embedding in PDF as regular fonts, instead of drawing the glyph outlines in PDF Type 3 fonts. This should be more efficient and preserve most font data like hinting. Variable fonts with CFF2 table (which are rare) continue to be drawn as Type 3 fonts as we would also need to to convert CFF2 to CFF and current versions of HarfBuzz has no support for that yet. The new APIs we use require HarfBuzz 8.3.1 |
tdf#153368: Support optical size for variable fonts, part 1 (commit: 9e67072a21bdbdfa9dc8da826654bf6fb4ec6116) Font plumbing to enable opsz axis and set it to font’s point size. |
tdf#153368: Support optical size for variable fonts, part 2 (commit: d128bdf1feadd167485f819a582af533cfde6523) Add SvxOpticalSizingItem and EditEngine plumbing. Mostly mindlessly copying stuff here. Let’s hope for the best. |
tdf#153368: Support optical size for variable fonts, part 3 (commit: 331e2c3b89d4f5fe53822489aab463a81fb19810) Add loext:font-optical-sizing attribute with two values, "auto" and "none", modeled after CSS font-optical-sizing: https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/font-optical-sizing |
tdf#153368: Support optical size for variable fonts, part 4 (commit: 1802e84d03c3d458edc3e124d2a7839660bc53d0) Support saving/loading font-optical-sizing in Writer. The font-optical-sizing property is enabled on the standard style for new documents, and for old documents it remains unset for backward compatibility. Add no-op stubs to DOCX, RTF, WW8, and HTML filters. |
tdf#153368: Support optical size for variable fonts, part 5 (commit: 475ec1aa3683cd4a7ff9e5f89d0b3fc858763fa3) Support import/export of font-optical-sizing in HTML filter. |
tdf#153368: Support optical size for variable fonts, part 6 (commit: 3fb0c4e15f66e383c6fe2e44eeb6b3a3b64b2721) Add Optical Font Sizing checkbox to the Position page of Character dialog. I’m not sure if this is the best place, but I have no better idea. |
tdf#153368: Support optical size for variable fonts, part 7 (commit: 059b717535bf48243b7a63e309d6e22d7b2fcd1b) Enable by default for new documents in Draw/Impress. |
tdf#153368: Support optical size for variable fonts, part 8 (commit: 5825e9cfdbe8c8ab33a4db06bc9581aaed6c48de) Channel optical sizing option through drawing layer, otherwise it doesn’t work in Draw/Impress. |
9.2Developments (improved PDF export)
Description |
Use HarfBuzz for instancing variable fonts (commit: 7ffb13159276c0a74ce4fffc49bb0da4a1950f1d) Instance variable fonts into static instances for embedding in PDF as regular fonts, instead of drawing the glyph outlines in PDF Type 3 fonts. This should be more efficient and preserve most font data like hinting. Variable fonts with CFF2 table (which are rare) continue to be drawn as Type 3 fonts as we would also need to to convert CFF2 to CFF and current versions of HarfBuzz has no support for that yet. The new APIs we use require HarfBuzz 8.3.1 |
Use HarfBuzz subsetter to subset fonts for PDF (commit: 76095f9252f8e88e995415ac94ce9920df539086) This gives us a more up-to-date subsetter and would allow dropping most of our low-level, CVE-happy, font subsetting code. Update required HarfBuzz version to the version that provides all new APIs we are now using. |
Generate PostScript name for variable font named instances (commit: 23dd80ffe5c73a082acd1ce1bee4edd0fe870b67) Named instances can have a PostScript name which we should use instead of the font’s PostScript name which would be the same for all instances. |
Generate PostScript name for variable font arbitrary instances (commit: 46a382e244bd81c85029a994d9aa2ba891e9686c) Implements Adobe Technical Note #5902: “Generating PostScript Names for Fonts Using OpenType Font Variations” https://adobe-type-tools.github.io/font-tech-notes/pdfs/5902.AdobePSNameGeneration.pdf |
Add LogicalFontInstance::[G|S]etVariations() (commit: c992dc2c534bebad70de4327a4046a6b357c8571) First step towards supporting font variations beyond named instances. |
Apply font variations when drawing text with Skia (commit: ece6f72de3d9487ccfea3094f028877dfd7e89a0) Set variations on the Skia font since now we allow the user to set font variations, and they can be different from the variations the font was created with. Previously we only supported named instances and these got their variations set by the platform font API. |
Apply font variations when drawing text with cairo (commit: 6a0ac36db8c9017bfab8026dec37708924d0cdce) Similar to the previous commit but for cairo. |
Apply font variations when drawing text with CoreText (commit: 3de5214a77ebd1704e1ae256f999ac0485cca3c0) Similar to the previous commit but for CoreText when Skia is disabled (e.g. when printing). |
Clamp variation values to axis min and max (commit: 89fe022707aa1d59b0486587d572f575839aac1a) Avoids creating needless PDF subsets for instances that are effectively the same. |
Downgrade CFF2 table to CFF if we have a new enough HarfBuzz (commit: 150b3deb2ac4e1b6930d296799bec3ded43f1b3d) Instead of drawing the outlines as Type 3 fonts, we now convert CFF2 table to CFF which then goes to our regular PDF embedding process (i.e it gets converted to Type 1 fonts for now). The test expectations are updated to reflect that. |
9.3Manual testing
Daily builds of LibreOffice allow to check the improvements.
Implement default optical sizing based on text size
1. Install the variable font Fraunces of the test document from Google Font site (https://fonts.google.com/specimen/Fraunces). Click on the top right “Get Font” button, and “Download” button to download Fraunces.zip. For example on Linux, install the variable fonts in the ~/.fonts/ directory, and re-start LibreOffice to access to the newly installed fonts:
$ unzip Fraunces.zip Fraunces*ttf -d ~/.fonts
Archive: Fraunces.zip
extracting: /home/user/.fonts/Fraunces-VariableFont_SOFT,WONK,opsz,wght.ttf
extracting: /home/user/.fonts/Fraunces-Italic-VariableFont_SOFT,WONK,opsz,wght.ttf
2. Open the test document OpticalFontSizing.odt from the bug report. The first two paragraphs use automatic optical sizing, resulting in relatively thinner strokes as the font size increases and other minor differences (see on Figure 15).
3. Test user interface of optical sizing: select the last paragraph, and enable Optical Font Sizing → Auto in Position page of the Character formatting dialog window. The layout of the text changes according to its actual size.
4. Test automatic optical sizing: Decrease and increase the font size of the first word “Whereas”: ratio of the stroke widths changes, according to the automatic optical sizing.
Extend ODF format to allow setting font variations
The recent development has added loext:font-optical-sizing character property to LibreOffice extension of ODF format. This extension allows the optional usage of the “opsz” (later, possibly other) design-variation axes of the variable fonts, guaranteeing back-compatibility of the older documents.
1. ODT export/import: Open the previous test document, format the first letter as bold, and save and reload the result in ODT format. Optical sizing remains enabled.
2. Default optical sizing. Create a new empty document in Writer. Write a 96 pt text using the previously installed variable font Fraunces. The text has got default optical sizing. Save it in flat ODT (.fodt) format. The result, a plain text file contains loext:font-optical-sizing="auto", i.e. enabled optical sizing. Reload the document to show it.
3. Back-compatibility. Create a similar document in an old LibreOffice (version 26.2 or before). Load it in the development version of LibreOffice. There is no optical sizing, and the optical sizing → Auto checkbox is disabled in character settings of the text.
Improve PDF export to instance variable fonts when embedding fonts in PDF
1. TrueType fonts named after the variable axes: Open the test document OpticalFontSizing.odt from the bug report. Format the first letter “W” in bold, and export the document in PDF. Open the PDF in e.g. GNOME Document Viewer (Evince), and choose the Properties in the main menu. Check the names and types of the embedded fonts on the Fonts pane of the Properties dialog window. They are TrueType fonts, not Type 3 any more, and named after the used design-variation axes of the variable font Fraunces (Figure 17).
10Paragraph Composer
by László Németh
The new Paragraph Composer balances word spacing in the consecutive lines, fixing fundamental incompleteness of the “greedy” single line composer of the word processors. Enable Format → Paragraph → Alignment → Paragraph Composer to remove huge word spacing by shifting words from the previous lines, only if the new break points would not result in larger word spacing than before. Setting Maximum word spacing greater than the Desired word spacing, shifting words will be limited by this value, too (Figure 19–Figure 21).
Improved readability
The Paragraph Composer can produce more readable text when the appropriate settings (limit, line width, microtypography and hyphenation) are applied, because
– it reduces large word spacing;
– it reduces large differences between lines (when a line with normal word spacing is followed by a line containing large spaces),
– combined with maximum letter spacing and maximum glyph scaling, ensures normal-sized spaces,
– and thereby reduces the number of rivers, continuous empty area that extends across several lines.
Improved readability of DOCX files
The paragraph composer keeps paragraph length and page layout interoperability with MS Word, while ensures better readability. (Note: this interoperability needs the default Minimum word spacing = 80% of the DOCX import, but not the minimum letter spacing and glyph scaling – which would result in more compact paragraphs.)
Figure 18: New menu option for Paragraph Composer in Alignment pane of the paragraph formatting dialog window. The new paragraph-level line breaking algorithm has been supported only during justification and without minimum letter spacing, yet.
Figure 19: Improving extreme bad typography (an example only for demonstration purpose). The red arrows mark the lines with improved word spacing. The same narrow text column typeset by the original line breaking algorithm (left), the limited (center) and unlimited (right) paragraph composers. The new tool can not only eliminate rivers, but can also create new ones in the event of poor typographic settings, especially at long words without hyphenation and with unlimited paragraph composer. (Test documents: tdf38159_disabled.fodt, tdf38159_limited.fodt, tdf38159.fodt.)
Note: beware of extreme bad typography: the length of the text lines must be at least 35 characters, use hyphenation, microtypography and limited paragraph composer, or disable justification. See this example with hyphenation and microtypography (but without the proposed 35 characters): tdf38159_microtypography.odt and its PDF export.
Figure 20: There was a better position for the word “I” in a normal text with 80-letter line width: The limited paragraph composer balances spaces of the consecutive lines using the common 133% maximum word spacing (in the previous example with the extreme bad typography, the limit was 300%, i.e. 3 space width for the narrow columns without hyphenation).(Test document: paragraph_composer_demo2.odt.)
Figure 21: Increasing maximum word spacing can handle extreme long words without hyphenation, too, shifting multiple words, if needed for balancing word spacing, removing the extreme differences – very short and very long word spacing – in the consecutive lines. (Test document: paragraph_composer_demo.odt.)
10.1Developments
As part of the recent paragraph layout developments, regressions of the custom glyph scaling were fixed, too.
Description |
tdf#38159 cui sw offapi xmloff: add paragraph composer (commit 62aecba14cc9d5a4707b4d7fb21b4e41777d323d) Balance word spacing within the consecutive lines to get uniform grayness and less rivers for better readability, enabled by the new paragraph property com::sun::star::text::ParaComposer and the following developments:
Note: "Smart justify" line breaking algorithm chooses space shrinking (limited by Minimum word spacing) only if shifting the last word isn't better based on the desired word spacing. This was still a greedy line breaking algorithm, resulting big word spacing in the lines before a longer word. The paragraph composer shifts the last word (or the first part of the hyphenated last word) from the previous line to decrease big word spacing in the actual line. Note: balancing very big word spacing in narrow consecutive lines can result vertical rivers. To avoid this, use limited paragraph composer by setting maximum word spacing. Follow-up to "smart justify", word spacing, letter spacing and glyph scaling developments. Selected commits: commit 529755f0919217a84a12daad0fddfddd1124f0e9 "tdf#166113 sw smart justify: adjust algorithm for interoperability", commit 7d08767b890e723cd502b1c61d250924f695eb98 "tdf#130088 "tdf#119908 smart justify: fix DOCX line count + compat opt.", commit 7d6696757dcdfa3cee481ac7795a91b2b47da363 "tdf#159923 sw cui offapi xmloff: add custom word spacing", commit 5a48070f5904c51dc9e7bbad4213d802fd4bc89b "tdf#126154 sw offapi xmloff cui: add min/max word spacing", commit f83a04c51056445bbf947a31c8c1866a5c30bef1 "tdf#167648 cui offapi xmloff sw: add DTP-feature maximum letter spacing", commit 3c53797210bf0a4e3ffb36ed2beac4d5ce229ff2 "tdf#167648 sw letter spacing: implement minimum letter spacing", commit 45ec7bd76196dcc60b4c2db2f6f00623ecbaf5a4 "tdf#168251 cui offapi xmloff sw glyph scaling: extend UNO/UX/ODF". |
tdf#169491 tdf#168251 sw glyph scaling: fix all scale width regressions (commit f25371fa95b2c46ff4a73ef6995c341c157e62d4) Do not disable scale width character setting, if it is applied in a text span (except when the paragraph uses automatic glyph scaling, yet). Regression since commit 45ec7bd76196dcc60b4c2db2f6f00623ecbaf5a4 "tdf#168251 cui offapi xmloff sw glyph scaling: extend UNO/UX/ODF". Follow-up to commit 7ed8a8ee39951f74e364091fafff20269359ba15 "tdf#171161 tdf#168251 sw glyph scaling: fix scale width regression". |
tdf#171161 tdf#168251 sw glyph scaling: fix scale width regression (commit: 7ed8a8ee39951f74e364091fafff20269359ba15) Do not disable scale width character setting if line-level automatic glyph scaling is not applied in the paragraph. Regression since commit 45ec7bd76196dcc60b4c2db2f6f00623ecbaf5a4 "tdf#168251 cui offapi xmloff sw glyph scaling: extend UNO/UX/ODF". |
10.2Manual testing
Daily builds of LibreOffice allow to check the improvements:
1. Improved layout by the paragraph composer. In Writer, open the test document paragraph_composer_demo.odt of Bug 38159. The document contains 3 justified paragraphs in 3 sections. The first justified paragraph doesn’t use the paragraph composer. The second one contains the same paragraph content using the paragraph composer with limited word spacing (Maximum word spacing = 133%), which resulted in shifting only the word “I”. The third one uses a bigger limit (Maximum word spacing = 250%), which resulted in shifting the words “aimet I” (Figure 21) to balance word spacing better in the consecutive lines.
2. Set unlimited paragraph composer. In the first justified paragraph, enable the Format → Paragraph → Alignment → Paragraph Composer checkbox and set Maximum word spacing to 100% (= Desired word spacing). In this case, the only limitation for balancing word spacing in the consecutive lines is that shifting word(s) mustn’t result in bigger word spacing, than before. Here the result is shifting the words “aimet I” (just like in the last justified paragraph with Maximum word spacing = 250%).
3. Set limited paragraph composer. In the previous paragraph, Set Maximum word spacing to 133%. Only the word “I” is shifted to the second line.
4. ODF import/export. Save the previous test document and reload it using File → Reload. The document (containing the new loext:paragraph-composer paragraph property) keeps the paragraph composer setting, resulting in the more balanced word spacing in Writer.
This project was funded through the NGI0 Core Fund, a fund established by NLnet with financial support from the European Commission’s Next Generation Internet programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 101092990. More information : https://nlnet.nl/project/LO-Bookproject