From 1f70b450a21af42bfa2cf6664468d555016e1273 Mon Sep 17 00:00:00 2001 From: Rudolf Biczok Date: Tue, 2 Jan 2024 12:00:59 +0100 Subject: [PATCH] Replace soft hyphen with visible hyphen if line break demands it (#1488) * Replace soft hyphen with visible hyphen if line break demands it * Add changelog entry for #457 * Add soft hyphen support in readme --- CHANGELOG.md | 1 + README.md | 2 +- lib/line_wrapper.js | 20 ++++++++++++++++-- .../text-spec-js-text-soft-hyphen-1-snap.png | Bin 0 -> 49466 bytes tests/visual/text.spec.js | 16 +++++++++++++- 5 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 tests/visual/__image_snapshots__/text-spec-js-text-soft-hyphen-1-snap.png diff --git a/CHANGELOG.md b/CHANGELOG.md index a24e10633..18884dc3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Add subset for PDF/UA - Fix for line breaks in list items (#1486) +- Fix for soft hyphen not being replaced by visible hyphen if necessary (#457) ### [v0.14.0] - 2023-11-09 diff --git a/README.md b/README.md index 7df2b50f9..10f74396a 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Installation uses the [npm](http://npmjs.org/) package manager. Just type the fo - Transformations - Linear and radial gradients - Text - - Line wrapping + - Line wrapping (with soft hyphen recognition) - Text alignments - Bulleted lists - Font embedding diff --git a/lib/line_wrapper.js b/lib/line_wrapper.js index b1e05a3e4..dfc019dca 100644 --- a/lib/line_wrapper.js +++ b/lib/line_wrapper.js @@ -1,6 +1,9 @@ import { EventEmitter } from 'events'; import LineBreaker from 'linebreak'; +const SOFT_HYPHEN = '\u00AD'; +const HYPHEN = '-'; + class LineWrapper extends EventEmitter { constructor(document, options) { super(); @@ -73,6 +76,13 @@ class LineWrapper extends EventEmitter { ); } + canFit(word, w) { + if (word[word.length - 1] != SOFT_HYPHEN) { + return w <= this.spaceLeft; + } + return w + this.wordWidth(HYPHEN) <= this.spaceLeft; + } + eachWord(text, fn) { // setup a unicode line breaker let bk; @@ -199,13 +209,13 @@ class LineWrapper extends EventEmitter { this.spaceLeft = this.lineWidth; } - if (w <= this.spaceLeft) { + if (this.canFit(word, w)) { buffer += word; textWidth += w; wc++; } - if (bk.required || w > this.spaceLeft) { + if (bk.required || !this.canFit(word, w)) { // if the user specified a max height and an ellipsis, and is about to pass the // max height and max columns after the next line, append the ellipsis const lh = this.document.currentLineHeight(true); @@ -246,6 +256,12 @@ class LineWrapper extends EventEmitter { this.emit('lastLine', options, this); } + // Previous entry is a soft hyphen - add visible hyphen. + if (buffer[buffer.length - 1] == SOFT_HYPHEN) { + buffer = buffer.slice(0, -1) + HYPHEN; + this.spaceLeft -= this.wordWidth(HYPHEN); + } + emitLine(); // if we've reached the edge of the page, diff --git a/tests/visual/__image_snapshots__/text-spec-js-text-soft-hyphen-1-snap.png b/tests/visual/__image_snapshots__/text-spec-js-text-soft-hyphen-1-snap.png new file mode 100644 index 0000000000000000000000000000000000000000..9aa8f946d74f5647d5a78647d912e47b715da585 GIT binary patch literal 49466 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 S`YVd}JZFZ<^cbU+`~DBSP^{Mg literal 0 HcmV?d00001 diff --git a/tests/visual/text.spec.js b/tests/visual/text.spec.js index e4e089dad..4c504df08 100644 --- a/tests/visual/text.spec.js +++ b/tests/visual/text.spec.js @@ -20,6 +20,20 @@ describe('text', function() { }); }); + test('soft hyphen', function() { + return runDocTest(function(doc) { + doc.font('tests/fonts/Roboto-Regular.ttf'); + doc.text( + 'Text with soft hyphen - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lo ip\u00ADsum', + { align: 'justify' } + ); + doc.text( + 'Text with soft hyphen on the edge - ttttestttestttestttestttestttestttestttestttestttestttes\u00ADtt\u00ADt', + { align: 'justify' } + ); + }); + }); + test('decoration', function() { return runDocTest(function(doc) { doc.font('tests/fonts/Roboto-Regular.ttf'); @@ -31,7 +45,7 @@ describe('text', function() { strike: true }); doc.text('Strike', 100, 160, { - underline:true, + underline: true, strike: true }); });