LO/COOL Book Project

State-of-the-art readability and typogra­phy of ISO docu­ment for­mats by DTP-com­pliant microtypog­raphy, de­fault optical sizing, document and base­line grid tools for multi-column pagi­nation in open source office suites

1Summary

LibreOffice, the open source of­fice suite is the reference implem­entation of ISO OpenDocument (ODF) format. As part of LibreOffice Technol­ogy, Collabora Online is key for the digital sovereignty of open source on­line docu­ment editing. The previo­us LO/COOL Typography project has fixed the lost para­graph lay­out in­teroperability of Writer word pro­cessor by im­plementing several ISO OOXML/MSO DOCX interoper­ability fea­tures, includ­ing the new line break algo­rithm intro­duced in MS Word 2013 (see development report). This continua­tion en­hances read­ability of text docu­ment stored in ISO docu­ment for­mats by adding mi­crotypography, para­graph-level line break­ing and better variable font and multi-column pagi­nation sup­port to Writer. It results a new type of soft­ware with the print qual­ity of proprietary DTP programs and with pro­ductivity and ISO docu­ment format sup­port of word process­ors.

The improved paragraph layout with consistent text den­sity, without rivers of white, also the improved font and grid sup­port al­low multi-col­umn pagination on type­writer pa­pers used in schools, public adminis­tration, or­ganizations and at home print­ing, achiev­ing the opti­mal line length and word spacing pro­posed by accessibili­ty and ty­pography ex­perts.

Main parts of the project:

Microtypogra­phy (by László Németh) • following the previ­ous cus­tom word spac­ing de­velopments, add cus­tom letter spacing (tdf#167648) and glyph scaling (tdf#168251) to get read­able multi-col­umn pagination (which is the pro­posed paginat­ion for typewriter pa­pers to avoid too long lines for chil­dren and for peo­ple with reading dis­abilities);

Paragraph composer (by László Németh) • re­move re­maining rivers of white and huge word spacing by para­graph-level justifi­cation like DTP software do, combined with cus­tom level of hy­phenation (tdf#38159/ooo#3243);

Optical font sizes (by Khaled Hosny)following web stan­dards and web ty­pography, ap­ply de­fault optical siz­ing using vari­able fonts with optical com­pensation to get more readable small and large text and bet­ter typography (tdf#153368);

Variable fontsSupport design-varia­tion fea­tures and named in­stances of vari­able fonts to get real readable bold, condensed and slanted font variants instead of un­acceptable letter distortion of word proces­sors (tdf#152396, tdf#35538);

Document grid (by Tamás Zolnai) fix lost visibility and preci­sion of docu­ment grid on normal high-resolution dis­plays, restor­ing one of the most impor­tant tools for multi-col­umn pagina­tion (tdf#89544, tdf#48245);

Baseline grid (by Tamás Zolnai)add basic design tool of DTP soft­ware to guaran­tee mini­mum ty­pography re­quirements of multi-column pagination (~tdf#144542).

The results are in­tegrated with the main devel­opment branch of LibreOffice, docu­mented by a devel­opment re­port with descript­ion of the manual testing, and depend­ing on the task, con­tain au­tomated unit and re­gression testing.

2Microtypogr­aphy 1: Maxi­mum letter spac­ing

by László Németh

Already minor, 3–5% expansion of let­ter spacing can mini­mize rivers of white and bad word spac­ing a lot, espec­ially in nar­row columns, where it’s not possi­ble to get the de­sired word spacing only by hyphenation and minimum/maxi­mum word spac­ing.

 

Figure 1: Demonstrat­ion of maxi­mum letter spac­ing. De­pending on the justi­fied lines (e.g. no space or no hyphen­ation), it’s pos­sible to use bigger letter spacing, than the approved 3–5%. (original PDF ver­sion: letter_spacing_demo.pdf).

 

Figure 2: GIF animat­ion of maxi­mum word spac­ing, result­ing the desired word spacing by en­larging letter spacing. Its pro­posed value is 3% for normal line width (70-80 char­acters), and 5% or more for narrow para­graphs (35-70) or paragraphs with no no or limited hy­phenation.

2.1Develop­ments

Description

tdf#167648 cui of­fapi xmloff sw: add DTP-feature maxi­mum letter spac­ing

(commit: f83a04c51056445bbf947a31c8c1866a5c30bef1)

Add new para­graph justifica­tion option "Maximum let­ter spac­ing" to distrib­ute letters on (part of) the available blank area of the justi­fied line in­stead of over­stretching word spac­ing, like DTP software do.

This improves ty­pography a lot, al­lowing typesetting vis­ually better i.e. more readable paragraphs, mini­mizing or removing rivers and too big word spacing (which was com­mon in col­umns or text without hyphen­ation).

Add spin box to Alignment in para­graph for­matting dia­log win­dow, (also add spin boxes for future Mini­mum and the alternat­ive per­cent-based De­sired letter spac­ing, see CharKerni­ng);

For example (only ASCII visu­alization!), 100% maximum letter spacing adds a space character-width blank space between the char­acters, in­cluding 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 col­umns), 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 proper­ties in para­graph model:

css::style::Para­graphProperties::ParaPropLetterSpacingMaxim­um

css::style::Para­graphProperties::ParaPropLetterSpacing­Minimum

Note: desired letter spacing is already sup­ported by ODF/UNO, see css::style::Charac­terProperties::CharKern­ing.

Implement vis­ual layout of maximum letter spacing.

Note: after the last character of the line, there is an un­wanted let­ter-spacing, yet (which is visi­ble only with big letter-spac­ing val­ues).

Add ODF im­port/export (loext:letter-spac­ing-maximum and loext:let­ter-spacing-minimum)

Add ODF unit test.

Note: hyphen­ated lines and lines with multi­ple portions do not yet use cus­tom letter spac­ing, yet.

2.2Manual test­ing

Daily builds of LibreOffice allow to check the improve­ments:

  1. 1. In Writer, open the test docu­ment tdf167648_0_5_25_and_100_percent_letter_spacing.fodt of Bug 167648. The docu­ment con­tains four paragraphs. Maxi­mum letter spac­ing of the para­graphs are 0%, 5%, 25% and 100%, which is visi­ble in the size of the word spac­ing and size of letter spac­ing. (PDF ver­sion of the test docu­ment: https://bug-attachments.documentfoundation.org/attachment.cgi?id=202097). 

  2. 2. Test direct for­matting: Select the first para­graph or put the test cur­sor in­side it. Open para­graph formatt­ing dia­log win­dow using For­mat→Para­graph menu item, and choose the Alignment pane. Mod­ify Maxi­mum letter spac­ing to 15% and press En­ter. The re­sult is word spac­ing nearer to the de­sired one by big­ger letter spacing, be­tween the sec­ond paragraph (5%) and the third para­graph (25%). 

  3. 3. Test para­graph style: Open para­graph style format­ting dia­log win­dow us­ing StylesEdit Style… menu item. Choose Alignment pane and select Justi­fied align­ment in Op­tions. Set the maxi­mum 500% Maxi­mum letter spac­ing, and press Enter. Re­move di­rect para­graph for­matting by se­lecting the whole text and Format→Clear Direct For­matting. All para­graph lines get the de­sired word spac­ing, us­ing (too) big let­ter spac­ing. 

3Microtypogr­aphy 2: glyph scaling and mini­mum let­ter spacing

by László Németh

In this task, the following microtypography elements were im­plemented: 1) minimum letter spacing, as continu­ation of the previous maximum letter spacing, 2) mini­mum and maxi­mum glyph scaling, i.e. compression and expansion of letters. (Desired glyph stretching and de­sired letter spacing are al­ready imple­mented by as Scale width and Character spacing on Format → Character… → Posi­tion pane.)

Already minor, 1–3% glyph scaling can mini­mize rivers of white and bad word spacing a lot, es­pecially in nar­row col­umns, where it’s not possible to get the desired word spacing only by hyphena­tion and mini­mum/maxi­mum word spac­ing. Com­bined with maxi­mum and minimum letter spac­ing, glyph scal­ing is the basic ele­ment of mi­crotypography used by DTP software.

In Writer’s implementation of the algorithm, letter spac­ing 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 maxi­mum letter spacing is not enough for the desired word spacing, also glyph scaling is ap­plied in the line.

Figure 3: Demonstrat­ion of mini­mum/maximum let­ter spac­ing and glyph scal­ing. The original paragraph (top left) is variously opti­mized with com­bination of the four set­tings, eliminating rivers of white and blank spaces (origi­nal PDF ver­sion: tdf168251_demo.pdf).

 

Figure 4: GIF animat­ion of maxi­mum glyph scal­ing, result­ing the desired word spacing by en­larging letter width by distort­ion. Its proposed value is 1–3% for normal line width (70-80 characters), and 1–5% or more for nar­row para­graphs (35-70) or paragraphs with no no or limited hyphen­ation. Note: at re­cent letter distortion of Writer glyph scal­ing, vertical and hori­zontal lines lose their uni­formity, re­sulting unaccept­able glyphs at greater values, so the ani­mation is only for demonstration. Sup­porting design-varia­tion width axis of variable fonts can re­sult in us­ing greater val­ues with­out letter distortion.

3.1Develop­ments

Description

tdf#167648 sw let­ter spacing: imple­ment mini­mum let­ter spac­ing

(commit 3c53797210bf0a4e3ffb36ed2beac4d5ce229ff2)

Implement new paragraph justificat­ion option "Minimum let­ter spac­ing" allow­ing to shrink text lines more, choos­ing bet­ter paragraph lay­out instead of hy­phenation or rivers of space.

* Implement vis­ual layout of minimum letter spacing.

* Enable Mini­mum letter spacing spin box on Alignment pane of the para­graph for­matting dialog window

* Remove also de­sired letter spacing spin box from the align­ment pane. It will be better to vi­sualize CharK­erning with per­centage value instead of adding a new user inter­face to the same set­ting.

* Set minimum and maximum spin box ranges to [-100, 0] and [0, 500], and re­move unneces­sary handlers.

* offapi: extend API description with ranges of letter spac­ing [-100, 500] and word spacing ([0, 1000]).

* Add ODF unit test.

Note: hyphen­ated lines, lines with multiple portions haven’t been using cus­tom letter spac­ing, yet.

Note: resolution of the custom letter spacing is only 1/20 point (1 twip) yet.

Note: adjust testTdf163149 fail­ing on a test ma­chine, maybe be­cause the DOCX test docu­ment contains the not sup­ported Arial font, result­ing small differ­ences based on the font re­placement.

Follow-up to com­mit f83a04c51056445bbf947a31c8c1866a5c30bef1 "tdf#167648 cui offapi xmloff sw: add DTP-feature maxi­mum letter spac­ing".

tdf#168251 cui of­fapi xmloff sw glyph scaling: extend UNO/UX/ODF

(commit: 45ec7bd76196dcc60b4c2db2f6f00623ecbaf5a4)

Add new para­graph justifica­tion options "Minimum glyph scal­ing" and "Maxi­mum glyph scaling" to improve typog­raphy, like DTP software do, al­lowing to type­set visually bet­ter para­graphs, especially nar­row col­umns without unaccepta­bly big word spac­ing.

* Add spin boxes to Alignment in para­graph for­matting dia­log window;

* Store proper­ties in para­graph model:

css::style::Para­graphProperties::ParaPropScaleWidthMini­mum

css::style::Para­graphProperties::ParaPropScaleWidth­Maximum

Note: desired glyph scaling is already sup­ported by ODF/UNO, see css::style::Charac­terProperties::CharScaleWidth.

* Implement vis­ual layout of minimum and maximum glyph scal­ing, lim­ited by the avail­able extra word spac­ing and letter spac­ing, too.

Note: last line can exceed the para­graph width, be­cause mini­mum glyph scaling, also minimum letter scaling of the last line haven't been applied there, yet.

* Add ODF im­port/export (loext:text-scale-maximum and loext:text-scale-minimum, where style:text-scale is for the de­sired text scaling).

* Add ODF unit test.

Note: hyphen­ated lines, lines with multiple portions haven't been using cus­tom glyph scal­ing, yet.

Note: resolution of glyph scaling is 1 percent, which will avoid of over­generation of font types using variable fonts.

tdf#167648 sw let­ter spacing: fix divi­sion by zero

(commit: 9d8a54d4b65e9f16dee05c8152cfe4bd68f0b047)

/sw/source/core/text/portx­t.cxx:351:90: run­time error: divis­ion by zero

#0 0x7f7bf4700824 in SwTextPor­tion::SetSpac­ing(SwTextFormatI­nfo&, o3tl::strong_int<int, Tag_TextFrameIn­dex>, 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 let­ter spacing: imple­ment mini­mum let­ter spac­ing".

3.2Manual test­ing

Daily builds of LibreOffice allow to check the improve­ments:

  1. 1. In Writer, open the test docu­ment tdf168251_demo.fodt of Bug 168251. The document con­tains six para­graphs with differ­ent mini­mum/maxi­mum letter spacing and glyph scaling combi­nations (Figure 3. PDF ver­sion of the test docu­ment: https://bug-attachments.documentfoundation.org/attachment.cgi?id=202747). 

  2. 2. Test mini­mum letter spacing: Select the first para­graph or put the test cursor in­side it. Open para­graph format­ting dia­log win­dow us­ing For­mat→Para­graph menu item, and choose the Alignment pane. Mod­ify Mini­mum letter spacing to –3% and press En­ter. The second line con­tains 4 words “con­sectetur adip­iscing elit. Vestibu­lum, not 3 words (“con­sectetur adipisc­ing elit.”) any more. 

  3. 3. Test maxi­mum glyph scaling: in the previ­ous set­tings, set also the maxi­mum 200% Maxi­mum glyph scaling and press En­ter. The para­graph lines contain the de­sired word spac­ing instead of 3–6 times bigger blank spa­ces. 

  4. 4. Test mini­mum glyph scaling: in the previ­ous set­tings, set also mini­mum glyph scaling to 97%. The 5th line con­tains 5 words, not 4 words any more: “quis commodo do­lor po­suere. Cur­abitur”, not “quis com­modo dolor po­suere.” any more. 

4Microtypogr­aphy 3: hyphenation, multi-por­tion etc.

by László Németh

These developments extended microtypography devel­opments for 1) hyphenated lines and 2) other text lines with mul­tiple text portions, for example, containing em­phasized words. Moreover, they 3) fixed text cursor posi­tions during moving in the com­pressed or expanded text line with reduced or en­larged letter spacing and 4) re­moved the unnecessary blank space at the end of lines with enlarged letter spacing (Fig­ure 5).

Figure 5: Problems of the first implementation of microty­pography: 1) en­larged letter spacing was applied at the end of the lines, too, resulting bad justification (yellow bar). 2) there was no microty­pography in lines with multiple text portions, result­ing huge word spacing (blue circle). 3) There was no microty­pography in hyphen­ated lines. 4) Where microty­pography was enabled in multiportion lines by accident, the result was miss­ing word spacing or justificat­ion (red box) (origi­nal PDF ver­sion: 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) apply­ing microtypography in lines with hy­phenation, 4) fixed word spacing and justification (origi­nal PDF ver­sion: tdf169168_newer.pdf).

 

Figure 7: For comparison, the test document opened in an old Writer ver­sion before the microtypography develop­ments: it con­tains huge word spacing and rivers of white (origi­nal PDF ver­sion: tdf169168.pdf).

4.1Develop­ments

Description

tdf#168448 sw letter spacing: enable it + glyph scaling at hyphena­tion

(commit d86f68e6b845f65896c1ffc4f55d09ec48fd9840)

Letter spacing and glyph scaling were disabled in hy­phenated lines be­cause of their broken layout. Now the hyphen mark is po­sitioned cor­rectly at the end of the line, not before that, ap­plying plus letter spac­ing and glyph scaling on horizontal position of the hyphen por­tion, and without expanding the text over the hy­phen portion.

tdf#169168 sw letter spacing: extend it for multiportion lines

(commit: 97f97ba44e6af2be2e94ae26054b060b0303933a)

Enable custom letter spacing and glyph scaling for multi­portion lines, i.e. lines with emphasized and underlined words, or lines hyphenated automatically or with soft hy­phen etc.

For this, width of the text portions are modified tempo­rarily ac­cording to the actual available blank space of the lines at pro­cessing 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 in­stead of SwTextPortion.

Other fixes and changes:

– itrcrsr.cxx: text cursor position follows the custom letter spac­ing and custom glyph scaling applied in the line;

– itradj.cxx: at letter spacing, the enlarged blank space is re­moved after the last letter in the line, fixing jittering of the right side of the lines.

– guess.cxx: fix crashing during typing before a terminat­ing text por­tion;

– portxt.cxx: fix bad letter spacing, when the line contains zero width characters (soft hyphen, zero-width space etc.);

– testTdf168351: extend test document, because com­pression is not ap­plied in the last line any more. Note: this is likely not a problem (in fact, it's the opposite, be­cause filling the last line completely can destroy the clear separation of the para­graphs, especially without first line indent).

– testTdf168251 and testTdf168448: adjust the tests ac­cording 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 para­graph line incompletely, because of miss­ing update of the break width, when the last two para­graph lines were com­pressed into a single one. This re­sulted in calculating more blank space, than available, and posi­tive kerning, also glyph expansion with missing word spacing and over­lapping words, instead of negative kerning and glyph compression for the desired word spacing.

tdf#168528 sw letter spacing: fix freezing with minimum spac­ing/scal­ing

(commit: 8306c4e86aacfe0e2a7b2aedb88c404735dccdcd)

Fix never-ending loop in SwTextFrame::Format_() re­sulted by bad com­pression of lines with COMPLETE_STRING cut posi­tion.

Note: to test the fix of the rare freezing, a subset font has been created from Source Serif 4 Variable, and embed­ded 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 mod­ules with enabled gb_CppunitTest_set_non_appli­cation_font_use failed with false alarms. As a quick fix, move the test into sw_core_text, where gb_CppunitTest_set_non_applica­tion_font_use is not en­abled, and re­vert the vcl exception added for the test previ­ously.

Regression by 8306c4e86aacfe0e2a7b2aedb88c404735dccdcd "tdf#168528 sw letter spacing: fix freezing with minimum spac­ing/scal­ing".

4.2Manual test­ing

Daily builds of LibreOffice allow to check the improve­ments:

  1. 1. In Writer, open the test docu­ment tdf169168.odt of Bug 169168. The document con­tains 2-2 para­graphs in 12 sec­tions. The first col­umn contains only custom letter spac­ing. The second one contains only custom glyph scaling. The last one contains combined cus­tom letter spacing and glyph scaling. Second para­graphs of the sec­tions contain multi­ple text por­tions, i.e. different line parts with italic, bold or un­derlined text formatting. Now mi­crotypography is applied in these lines, too, resulting smaller word spacing. (Fig­ure 5. PDF ver­sion of the test docu­ment: 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 pro­posed.) 

  2. 2. Test multiportion lines with microtypography: se­lect the first word “Lorem” of the document, and ap­ply bold formatt­ing. Re­move 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 ex­actly, microty­pography 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. 3. Test hyphenated lines: in the HYPHENATION sec­tions, re­move the first and the second letter. Result: the letter spac­ing and glyph scal­ing follow the changes, keeping normal word spacing and justifica­tion in the lines hy­phenated auto­matically. Note: soft hyphens sup­port only glyph scaling, but not letter spacing, yet. 

  4. 4. Test removed blank space at line end: Open the docu­ment 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 be­tween them, as previ­ously. (Note: an ex­ception, when the paragraph starts with a space­, which is a typographic/editing mistake in itself.) 

  5. 5. Test cursor position: Put the text cursor in the first letter of the document, and press right arrow multi­ple times: now the cursor follows the letters with re­duced/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 com­pared to other LibreOffice applications, such as Draw and Impress. Writer ren­dered 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 imple­mented the same behavior for Writer (and also for Calc), im­proving the user experience for the future use of the grid func­tionality. With this change, grid now has a consistent appear­ance across all four main ap­plications 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 origi­nally used for posi­tioning and rendering the grid markers. These bugs were also investi­gated and fixed. In­creasing the visibility of the grid would have also in­creased the visibility of these issues of the rendering code.

5.1Develop­ments

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 be­havior 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 in­crease the com­plexity of the code by defining different behavior for Calc.

tdf#169226: Avoid rendering grid points outside of the draw­ing 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 seg­ment 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. How­ever because of the inevitable numeric imprecisions, different anchor points lead to different fi­nal position values (one pixel differences).

After: A main grid point is used as anchor point, whose posi­tion 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 test­ing

Daily builds of LibreOffice allow to check the improve­ments:

  1. 1. Test visualization of grid in Writer (tdf#89544, tdf#169311). Open an empty document in Writer and en­able the grid us­ing View → Grid and Helplines → Display Grid. Zoom in, zoom out and scroll through the docu­ment. Writer displays a 3×3-pixel cross for the main grid points and a 1-pixel dot for the sec­ondary grid points, both in dark gray. 

  2. 2. Test rendering with different grid settings (tdf#89544). Open Tools → Options… → LibreOffice Writer → Grid set­tings 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 subdi­vision. 

  3. 3. Test that grid settings are properly applied after restart­ing Writer (tdf#169384). Ensure that the grid is displayed be­fore clos­ing Writer. Then open a new docu­ment and verify that the number of subdivision points re­flects the previously defined settings. Note: Grid settings are part of the user pref­erences and therefore they per­sist after a document is closed. 

  4. 4. Test proper rendering of grid at the bottom of the docu­ment (tdf#169226). Open a document, set the zoom  level to 100% and scroll from the top to the bottom of the docu­ment. The grid ap­pears 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 functional­ity is that snap­ping objects to the grid is inaccurate. De­pending on the zoom level or the defined page margins, this inaccuracy can be very small or quite no­ticeable. The first report of this is­sue 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.1Develop­ments

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 ap­plications (Impress, Calc, Draw). For Writer there are multi­ple grids (one grid per page). Replicate the be­havior of the grid drawing code to identify the proper grid origin. See Sdr­PageView::DrawPageViewGrid().

The grid is drawn in the user area, but use the wider "pa­per rect" to identify the correct grid frame for snapping. So there isn’t an abrupt change in snapping behavior when an object moves out­side the print­ing area (partly or entirely).

Do some extensive testing of snap to grid functionality. There were no tests for it yet.

6.2Manual test­ing

Daily builds of LibreOffice allow to check the improve­ments:

  1. 1. Test snapping to grid while inserting a shape in Writer. Open an empty document, enable “display grid” and “snap to grid” fea­tures: View → Grid and Helplines → Dis­play Grid and View → Grid and Helplines → Snap to Grid. Insert a rec­tangle shape onto the grid: Insert → Shape → Basic Shapes → Rec­tangle. While drawing the shape using drag-and-drop, the edges of the new rectangle accu­rately snap to the grid points. Note: Both main grid points and sec­ondary grid points serve as snapping positions. 

  2. 2. Test snapping of an existing shape. Open an empty docu­ment and insert a shape while all grid related options are disabled. Then enable “display grid” and “snap to grid” fea­tures. Resize the shape to align it with the grid. While resiz­ing the object using drag-and-drop, the shape’s edges accu­rately align with the grid. Resize the shape in all four direc­tions to align with the grid, then move the shape using drag-and-drop. While moving the shape, its new posi­tion follows the grid points. 

  3. 3. Test snapping a line shape to the grid. Open a new Writer docu­ment and enable display grid” and “snap to grid” fea­tures. Then insert a line shape into the docu­ment: Insert → Shape → LineLine. Try con­necting 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. 4. Test snapping a text frame to the grid. Open a new Writer docu­ment and enable display grid” and “snap to grid” fea­tures. Then insert a text frame into the docu­ment: Insert → FrameFrame In­teractively. While draw­ing 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 typeset­ting). Page line-spac­ing aligns all affected text to an invisi­ble vertical grid. With the new baseline grid fea­ture, this previously invisible grid can now be displayed, allowing users to verify whether page line-spacing has been ap­plied correctly and whether text is aligned consis­tently across pages and paragraphs (for exam­ple, when printing a book).

 

Figure 12: New baseline grid feature in Writer.

The baseline grid is calculated based on the reference style de­fined for the page line-spacing. If page line-spac­ing 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 base­line grid on page col­umns

The baseline grid feature also helps identify issues with the page line-spacing feature in LibreOffice. During the implementat­ion and testing of the baseline grid, two such issues were identi­fied: tdf#169922 and tdf#170000.

7.1Develop­ments

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 base­line 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 re­flect 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 base­line the grid option(s).

* Introduce a new ConfigItem for the new baseline grid re­lated option to allow saving it to and loading it from the user prefer­ences. (see SwBaselineGridConfig class).

* Handle the possible read-only state of the configuration op­tion and lock the related checkbox on the grid tab page, if necessary.

 

3. Compute the proper position of the baseline grid's horizon­tal lines.

* First, extract the ComputeRegister() method to calcu­late 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" refer­ence

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 visi­ble

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 ex­porting 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 trig­gers 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 mas­ter

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 Win­dows.

(commit: 792fca692594a642762c8ea62581d43fb56300d4)

7.2Manual test­ing

Daily builds of LibreOffice allow to check the improve­ments:

  1. 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 base­line grid: Tools → Op­tions → LibreOffice Writer → Grids → Baseline Grid → Visi­ble 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. 2. Enable the baseline grid via menu: Open the test document from the bug report and display the base­line grid via menu: View → Grids and Helplines → Dis­play Base­line Grid. The displayed baseline grid aligns with the text in the document. 

  3. 3. Test changing the color of the baseline grid: Open the test document from the bug report and display the base­line grid via menu: View → Grids and Helplines → Display Baseline Grid. Change the color of the baseline grid at the following location: Tools → Op­tions → LibreOffice → Ap­pearance → Cus­tomizations → Baseline grid. The dis­played baseline grid changes its color to the selected new color. 

  4. 4. Test updating the baseline grid when changing page line-spacing: Open the test document from the bug re­port 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 → Refer­ence Style. Select “Ti­tle” as reference style. All text in the docu­ment is re­aligned based on the “Title” style and the baseline grid is also updated with a larger distance be­tween 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 lay­out control. However, there were some uses cases in which this feature did not work properly. Within this project, the fol­lowing issues were fixed to en­hance the usability of this fea­ture:

1. Text inside frames was not aligned properly to the base­line grid (tdf#93785).

2. Text inside multi-column sections was not aligned prop­erly to the baseline grid (tdf#170000).

3. Proper page line-spacing alignment was lost after re­moving a page (tdf#169922).

(+1. Vertical text in tables disappeared when page line-spac­ing was en­abled (tdf#169821).)

 

Figure 14: Fixed page line-spacing formatting within frames.

8.1Develop­ments

Description

tdf#93785, tdf#170000: Fix page line-spacing formatting in sec­tions and frames.

(commit: 2b47f4090df08fd70b6f51bafd11acc56b3998df)

The offset position (RegStart) for page line-spacing should be de­fined 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 han­dle this cor­ner case.

tdf#169922: Apply page line-spacing properly after re­moving a page.

(commit: 39018ea836bb73862a9fa509f375ee88750dc93f)

The invalidation code tries to minimise what needs to be recalc­ulated 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 refor­mat

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 hori­zontal

grid line. The text formatter code attempted to align the text to the

baseline grid, which led to an integer underflow for top-to-bot­tom text, resulting in a line height of -64667.

Add unit tests for page line-spacing in preparation for fu­ture de­velopment.

(commit: a1f1204dd2360015af41c51282900ecb28ec5472)

Add more unit tests for page line-spacing.

(commit: 9c56e440d80b74a8a2ffe22264f64d5a8f2ea361)

8.2Manual test­ing

Daily builds of LibreOffice allow to check the improve­ments:

  1. 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 → Dis­play Baseline Grid. The text inside the frame aligns with the baseline grid. 

  2. 2. Test page line-spacing alignment while moving a frame (tdf#93785): Open the test document from the bug report and dis­play the baseline grid. Move the frame around in the document us­ing drag-and-drop. The text inside the frame aligns with the base­line grid after every movement. 

  3. 3. Test page line-spacing inside a multi-column sec­tion (tdf#170000): Open the test document from the bug re­port and dis­play the baseline grid. The text in­side the multi-col­umn section aligns with the base­line grid. 

  4. 4. Test page line-spacing after removing a page (tdf#169922): Open the test document from the bug re­port and display the baseline grid. The text on all pages aligns properly with the baseline grid. Then re­move the second (empty) page. After the page is re­moved, the text is still aligns properly with the base­line grid. 

9Optical font sizes and better variable font sup­port

by Khaled Hosny (Alif Type)

With these series of commits (and other foundational changes before them), I have added support for Open­Type opsz axis (Sup­port optical size for OpenType vari­able fonts: tdf#153368), also more efficient PDF export of variable fonts:

  1. 1. A new font-optical-sizing property (under loext names­pace for now), modeled after the similarly named CSS property: https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/font-optical-sizing 

  2. 2. When enabled, the opsz axis (for fonts that support it) is set to the font’s point size. 

  3. 3. In Writer, Draw, and Impress, optical sizing is enabled by de­fault for new documents. 

  4. 4. For backward compatibility, it remains disabled by de­fault for old documents. 

  5. 5. The Position tab of the Character dialog has a new Opti­cal Font Siz­ing option. 

  6. 6. ODF importing/exporting supports the new property. 

  7. 7. HTML importing/exporting uses the CSS equivalent. 

  8. 8. PDF export instances the font into static instances and em­beds them as regular fonts (no more Type 3 fonts, ex­cept 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 en­abling Font Optical sizing, and below text disabling it. Notice how the above text gets more thinner strokes as the font size in­creases 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 formatt­ing dia­log window with the new Optical Font Sizing check­box. Optical font siz­ing is applied in the font preview, too.

 

Figure 17: Comparison of embedded fonts of Writer PDF ex­ports 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 LibreOffi­cer 25.8, bottom: from develop­ment 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.1Develop­ments (optical sizing)

Description

Use HarfBuzz for instancing variable fonts

(commit: 7ffb13159276c0a74ce4fffc49bb0da4a1950f1d)

Instance variable fonts into static instances for embed­ding in PDF as regular fonts, instead of drawing the glyph outlines in PDF Type 3 fonts. This should be more effi­cient 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 cur­rent 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-op­tical-sizing property is enabled on the standard style for new documents, and for old documents it re­mains unset for back­ward 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 fil­ter.

tdf#153368: Support optical size for variable fonts, part 6

(commit: 3fb0c4e15f66e383c6fe2e44eeb6b3a3b64b2721)

Add Optical Font Sizing checkbox to the Position page of Charac­ter

dialog. I’m not sure if this is the best place, but I have no bet­ter

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, oth­erwise 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 embed­ding in PDF as regular fonts, instead of drawing the glyph outlines in PDF Type 3 fonts. This should be more effi­cient 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 cur­rent 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 al­low drop­ping most of our low-level, CVE-happy, font sub­setting code.

Update required HarfBuzz version to the version that pro­vides all new

APIs we are now using.

Generate PostScript name for variable font named in­stances

(commit: 23dd80ffe5c73a082acd1ce1bee4edd0fe870b67)

Named instances can have a PostScript name which we should use in­stead of the font’s PostScript name which would be the same for all in­stances.

Generate PostScript name for variable font arbitrary in­stances

(commit: 46a382e244bd81c85029a994d9aa2ba891e9686c)

Implements Adobe Technical Note #5902: “Generating Post­Script Names for Fonts Using OpenType Font Varia­tions” https://adobe-type-tools.github.io/font-tech-notes/pdfs/5902.AdobeP­SNameGeneration.pdf

Add LogicalFontInstance::[G|S]etVariations()

(commit: c992dc2c534bebad70de4327a4046a6b357c8571)

First step towards supporting font variations beyond named in­stances.

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 varia­tions the font was created with. Previously we only sup­ported named in­stances and these got their varia­tions 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 dis­abled (e.g. when printing).

Clamp variation values to axis min and max

(commit: 89fe022707aa1d59b0486587d572f575839aac1a)

Avoids creating needless PDF subsets for instances that are effec­tively the same.

Downgrade CFF2 table to CFF if we have a new enough Harf­Buzz

(commit: 150b3deb2ac4e1b6930d296799bec3ded43f1b3d)

Instead of drawing the outlines as Type 3 fonts, we now con­vert CFF2 table to CFF which then goes to our regular PDF em­bedding process (i.e it gets converted to Type 1 fonts for now).

The test expectations are updated to reflect that.

9.3Manual test­ing

Daily builds of LibreOffice allow to check the improve­ments.

Implement default optical sizing based on text size

  1. 1. Install the variable font Fraunces of the test docu­ment from Google Font site (https://fonts.google.com/specimen/Fraunces). Click on the top right “Get Font” button, and “Download” button to down­load Fraunces.zip. For example on Linux, install the vari­able fonts in the ~/.fonts/ direc­tory, 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. 2. Open the test document OpticalFontSizing.odt from the bug re­port. The first two paragraphs use auto­matic opti­cal siz­ing, result­ing in relatively thinner strokes as the font size in­creases and other minor differences (see on Figure 15). 

  3. 3. Test user interface of optical sizing: select the last para­graph, and enable Optical Font Sizing → Auto in Position page of the Charac­ter formatting dialog win­dow. The lay­out of the text changes ac­cording to its actual size. 

  4. 4. Test automatic optical sizing: Decrease and in­crease the font size of the first word “Whereas”: ratio of the stroke widths changes, ac­cording to the auto­matic optical siz­ing. 

Extend ODF format to allow setting font variations

The recent development has added loext:font-optical-sizing charac­ter property to LibreOffice extension of ODF format. This exten­sion allows the optional usage of the “opsz” (later, possibly other) design-variation axes of the variable fonts, guaranteeing back-compatibility of the older docu­ments.

  1. 1. ODT export/import: Open the previous test docu­ment, for­mat the first letter as bold, and save and reload the re­sult in ODT format. Optical sizing re­mains enabled. 

  2. 2. Default optical sizing. Create a new empty docu­ment in Writer. Write a 96 pt text using the previously installed vari­able font Fraunces. The text has got de­fault optical sizing. Save it in flat ODT (.fodt) format. The result, a plain text file contains loext:font-optical-sizing="auto", i.e. en­abled optical siz­ing. Reload the document to show it. 

  3. 3. Back-compatibility. Create a similar document in an old LibreOffice (version 26.2 or before). Load it in the developm­ent ver­sion of LibreOffice. There is no opti­cal sizing, and the optical sizing → Auto checkbox is disabled in character set­tings of the text. 

Improve PDF export to instance variable fonts when embedd­ing fonts in PDF

  1. 1. TrueType fonts named after the variable axes: Open the test document OpticalFontSizing.odt from the bug re­port. Format the first letter “W” in bold, and export the document in PDF. Open the PDF in e.g. GNOME Docu­ment Viewer (Evince), and choose the Properties in the main menu. Check the names and types of the embed­ded fonts on the Fonts pane of the Properties dialog win­dow. They are True­Type fonts, not Type 3 any more, and named after the used design-variation axes of the vari­able font Fraunces (Figure 17). 

10Paragraph Composer

by László Németh

The new Paragraph Composer balances word spacing in the consecu­tive lines, fixing fundamental incompleteness of the greedy” single line composer of the word proces­sors.  Enable Format → Paragraph → Align­ment → Paragraph Composer to re­move huge word spacing by shifting  words from the previous lines, only if the new break points would not result in larger word spac­ing than be­fore. Setting Maximum word spac­ing greater than the De­sired word spacing, shifting words will be limited by this value, too (Figure 19Figure 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 lay­out in­teroperability with MS Word, while ensures better readability. (Note: this interoperability needs the de­fault 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 Align­ment pane of the paragraph formatting dialog win­dow. The new para­graph-level line breaking algorithm has been sup­ported only dur­ing justification and without mini­mum letter spacing, yet.

 

Figure 19: Improving ex­treme 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 algo­rithm (left), the limited (center) and unlim­ited (right) paragraph com­posers. 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, microtypogra­phy and limited paragraph composer, or dis­able justi­fication. 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 nor­mal text with 80-letter line width: The limited para­graph com­poser balances spaces of the consecutive lines using the com­mon 133% maximum word spacing (in the previous example with the ex­treme bad typography, the limit was 300%, i.e. 3 space width for the narrow columns without hy­phenation).(Test document: paragraph_composer_demo2.odt.)

 

Figure 21: Increasing maximum word spacing can handle ex­treme long words without hyphenation, too, shifting multiple words, if needed for balancing word spacing, re­moving the ex­treme differences – very short and very long word spacing – in the consecutive lines. (Test document: paragraph_composer_demo.odt.)

10.1Develop­ments

As part of the recent paragraph layout developments, regres­sions 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 uni­form gray­ness and less rivers for better readability, enabled by the new para­graph property

com::sun::star::text::ParaComposer

and the following developments:

  • •.Add Paragraph Composer checkbox on Alignment pane of the paragraph formatting dialog window (not default yet); 

  • •.Implement paragraph composer: big word spacing of a line is de­creased by shifting the last word from the previ­ous line, only if the word spacing is better, than before, and the in­creased word spac­ing in the previous line doesn't exceed the Maximum word spacing (limited paragraph composer); 

  • •.When Maximum word spacing is not greater than the De­sired word spacing, shifting of the last word is not lim­ited by the Maximum word spacing (unlim­ited paragraph com­poser) 

  • •.Add loext:paragraph-composer attribute, as LibreOffice ODF ex­tension; 

  • •.Add ODF unit tests for the limited and not limited para­graph com­poser. 

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 algo­rithm, resulting big word spacing in the lines before a longer word.

The paragraph composer shifts the last word (or the first part of the hy­phenated last word) from the previous line to de­crease big word spac­ing in the actual line.

Note: balancing very big word spacing in narrow consecu­tive lines can result vertical rivers. To avoid this, use limited para­graph 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", com­mit 7d08767b890e723cd502b1c61d250924f695eb98 "tdf#130088 "tdf#119908 smart justify: fix DOCX line count + compat opt.", commit 7d6696757dcdfa3cee481ac7795a91b2b47da363 "tdf#159923 sw cui of­fapi xmloff: add custom word spac­ing", commit 5a48070f5904c51dc9e7bbad4213d802fd4bc89b "tdf#126154 sw offapi xmloff cui: add min/max word spacing", commit f83a04c51056445bbf947a31c8c1866a5c30bef1 "tdf#167648 cui offapi xmloff sw: add DTP-feature maxi­mum let­ter spac­ing", commit 3c53797210bf0a4e3ffb36ed2beac4d5ce229ff2 "tdf#167648 sw letter spacing: implement minimum let­ter 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 re­gressions

(commit f25371fa95b2c46ff4a73ef6995c341c157e62d4)

Do not disable scale width character setting, if it is ap­plied in a text span (except when the paragraph uses au­tomatic glyph scal­ing, 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 regress­ion".

tdf#171161 tdf#168251 sw glyph scaling: fix scale width regress­ion

(commit: 7ed8a8ee39951f74e364091fafff20269359ba15)

Do not disable scale width character setting if line-level auto­matic 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 test­ing

Daily builds of LibreOffice allow to check the improve­ments:

  1. 1. Improved layout by the paragraph composer. In Writer, open the test docu­ment paragraph_composer_demo.odt of Bug 38159. The document con­tains 3 justified para­graphs in 3 sec­tions. The first justified paragraph doesn’t use the para­graph composer. The sec­ond one contains the same para­graph content using the paragraph com­poser with limited word spacing (Maximum word spacing = 133%), which re­sulted in shifting only the word “I”. The third one uses a big­ger limit (Maximum word spacing = 250%), which re­sulted in shifting the words “aimet I” (Figure 21) to balance word spac­ing better in the consecu­tive lines. 

  2. 2. Set unlimited paragraph composer. In the first jus­tified para­graph, enable the Format → Paragraph → Align­ment → Paragraph Composer checkbox and set Maximum word spacing to 100% (= Desired word spacing). In this case, the only limitation for balanci­ng word spacing in the consecu­tive lines is that shift­ing word(s) mustn’t re­sult in bigger word spacing, than before. Here the result is shifting the words “aimet I” (just like in the last justi­fied paragraph with Maximum word spacing = 250%). 

  3. 3. Set limited paragraph composer. In the previous para­graph, Set Maximum word spacing to 133%. Only the word “I” is shifted to the second line. 

  4. 4. ODF import/export. Save the previous test docu­ment and reload it using File → Reload. The document (containing the new loext:paragraph-composer para­graph property) keeps the paragraph composer setting, resulting in the more balanced word spacing in Writer. 

 

2026-04-12

 

This project was funded through the NGI0 Core Fund, a fund es­tablished by NLnet with financial support from the Euro­pean Commissions Next Generation Internet pro­gramme, un­der the aegis of DG Communi­cations Net­works, Content and Technology under grant agreement No 101092990. More infor­mation : https://nlnet.nl/project/LO-Bookproject