diff --git a/CHANGELOG.md b/CHANGELOG.md index a2611873..7548a9e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Fix bundlers and file tracers packing the ESM copies of the standard font metrics instead of the CommonJS ones the Node build actually loads, which left `Cannot find module` errors for every standard font at runtime, by resolving the internal `#standard-fonts/*` mapping to a single file under all conditions - Fix `doc.file()` throwing when the same in-memory attachment is embedded twice under one name, because the creation and modified dates the deduplication check compares are absent for sources that are not read from disk +- Fix `doc.text()` throwing `unsupported number: NaN` when `lineBreak: false` is combined with `underline`, `strike`, `link` or `goTo`, because the rendered width was computed from the line wrapper's measurements, which are never produced when wrapping is disabled ### [v0.20.1] - 2026-08-23 diff --git a/lib/mixins/text.js b/lib/mixins/text.js index f83d8ba7..df74a1f8 100644 --- a/lib/mixins/text.js +++ b/lib/mixins/text.js @@ -524,9 +524,15 @@ export default { } // calculate the actual rendered width of the string after word and character spacing + // the wrapper supplies textWidth and wordCount; measure them directly when it did not run + const measuredWidth = + options.textWidth ?? + this.widthOfString(text, options) - characterSpacing * (text.length - 1); + const measuredWordCount = + options.wordCount ?? (text.trim() ? text.trim().split(/\s+/).length : 0); const renderedWidth = - options.textWidth + - wordSpacing * (options.wordCount - 1) + + measuredWidth + + wordSpacing * (measuredWordCount - 1) + characterSpacing * (text.length - 1); // create link annotations if the link option is given diff --git a/tests/unit/text.spec.js b/tests/unit/text.spec.js index 69cdb3b4..6609ab9b 100644 --- a/tests/unit/text.spec.js +++ b/tests/unit/text.spec.js @@ -201,6 +201,23 @@ Q expect(docData).toContainText({ text: 'text with null x' }); }); + + test.each([ + ['underline', { underline: true }], + ['strike', { strike: true }], + ['link', { link: 'http://example.com/' }], + ['goTo', { goTo: 'anchor' }], + ])('with lineBreak false and %s', (_name, extraOptions) => { + const docData = logData(document); + + document.text('no line break', 50, 50, { + lineBreak: false, + ...extraOptions, + }); + document.end(); + + expect(docData).toContainText({ text: 'no line break' }); + }); }); describe('text with structure parent links', () => {