diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cc639c0..c478dbd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Update fontkit to 2.0 - Update linebreak to 1.1 - Add support for spot colors +- Fix sets tab order to "Structure" when a document is tagged - Fix measuring text when OpenType features are passed in to .text() ### [v0.15.2] - 2024-12-15 diff --git a/examples/kitchen-sink-accessible.pdf b/examples/kitchen-sink-accessible.pdf index c8ebca72..002f9b52 100644 Binary files a/examples/kitchen-sink-accessible.pdf and b/examples/kitchen-sink-accessible.pdf differ diff --git a/lib/mixins/markings.js b/lib/mixins/markings.js index 589b7889..6a445368 100644 --- a/lib/mixins/markings.js +++ b/lib/mixins/markings.js @@ -138,6 +138,10 @@ export default { return this._root.data.MarkInfo; }, + hasMarkInfoDictionary() { + return !!this._root.data.MarkInfo; + }, + getStructTreeRoot() { if (!this._root.data.StructTreeRoot) { this._root.data.StructTreeRoot = this.ref({ diff --git a/lib/page.js b/lib/page.js index a9064d10..d3f1837a 100644 --- a/lib/page.js +++ b/lib/page.js @@ -155,7 +155,15 @@ class PDFPage { return this.content.write(chunk); } + // Set tab order if document is tagged for accessibility. + _setTabOrder() { + if (!this.dictionary.Tabs && this.document.hasMarkInfoDictionary()) { + this.dictionary.data.Tabs = 'S'; + } + } + end() { + this._setTabOrder(); this.dictionary.end(); this.resources.data.ColorSpace = this.resources.data.ColorSpace || {}; for (let color of Object.values(this.document.spotColors)) { diff --git a/tests/unit/markings.spec.js b/tests/unit/markings.spec.js index 845372f9..1fe81b8b 100644 --- a/tests/unit/markings.spec.js +++ b/tests/unit/markings.spec.js @@ -623,6 +623,47 @@ EMC `(My Title)`, `endobj` ]); + expect(docData).toContainChunk([ + `10 0 obj`, + /\/Tabs \/S/, + `endobj` + ]); + }); + }); + + describe('untagged document', () => { + test('taborder not set for unmarked content', () => { + document = new PDFDocument({ + info: { + CreationDate: new Date(Date.UTC(2018, 1, 1)), + Title: "My Title" + }, + displayTitle: true, + compress: false, + pdfVersion: '1.5', + tagged: false, + lang: 'en-AU' + }); + + const docData = logData(document); + + document.end(); + + expect(docData).toContainChunk([ + `3 0 obj`, + /\/Lang \(en-AU\)/, + `endobj` + ]); + expect(docData).not.toContainChunk([ + `3 0 obj`, + /\/MarkInfo 5 0 R/, + `endobj` + ]); + expect(docData).not.toContainChunk([ + `10 0 obj`, + /\/Tabs \/S/, + `endobj` + ]); }); });