Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into bump-deps
Browse files Browse the repository at this point in the history
liborm85 committed Dec 15, 2024
2 parents 0fe3b5a + 76caaa6 commit 2f19e92
Showing 22 changed files with 150 additions and 32 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
## pdfkit changelog

### [v0.15.2] - 2024-12-15

- Fix index not counting when rendering ordered lists (#1517)
- Fix PDF/A3 compliance of attachments
- Fix CIDSet generation only for PDF/A1 subset
- Fix missing acroform font dictionary
- Fix modify time comparison check equality embedded files

### [v0.15.1] - 2024-10-30

- Fix browserify transform sRGB_IEC61966_2_1.icc file
1 change: 1 addition & 0 deletions docs/attachments.md
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ There are a few other options for `doc.file`:
* `hidden` - if true, do not show file in the list of embedded files
* `creationDate` - override the date and time the file was created
* `modifiedDate` - override the date and time the file was last updated
* `relationship` - relationship between the PDF document and its attached file. Can be 'Alternative', 'Data', 'Source', 'Supplement' or 'Unspecified'.

If you are attaching a file from your file system, creationDate and modifiedDate will be set to the source file's creationDate and modifiedDate.

Binary file modified examples/attachment.pdf
Binary file not shown.
Binary file modified examples/form.pdf
Binary file not shown.
Binary file modified examples/kitchen-sink-accessible.pdf
Binary file not shown.
Binary file modified examples/kitchen-sink.pdf
Binary file not shown.
Binary file modified examples/text-link.pdf
Binary file not shown.
2 changes: 1 addition & 1 deletion lib/font/embedded.js
Original file line number Diff line number Diff line change
@@ -180,7 +180,7 @@ class EmbeddedFont extends PDFFont {
descriptor.data.FontFile2 = fontFile;
}

if (this.document.subset) {
if (this.document.subset && this.document.subset === 1) {
const CIDSet = Buffer.from('FFFFFFFFC0', 'hex');
const CIDSetRef = this.document.ref();
CIDSetRef.write(CIDSet);
2 changes: 1 addition & 1 deletion lib/mixins/acroform.js
Original file line number Diff line number Diff line change
@@ -328,7 +328,7 @@ export default {

_resolveFont(options) {
// add current font to document-level AcroForm dict if necessary
if (this._acroform.fonts[this._font.id] === null) {
if (this._acroform.fonts[this._font.id] == null) {
this._acroform.fonts[this._font.id] = this._font.ref();
}

13 changes: 12 additions & 1 deletion lib/mixins/attachments.js
Original file line number Diff line number Diff line change
@@ -12,10 +12,12 @@ export default {
* * options.hidden: if true, do not add attachment to EmbeddedFiles dictionary. Useful for file attachment annotations
* * options.creationDate: override creation date
* * options.modifiedDate: override modified date
* * options.relationship: Relationship between the PDF document and its attached file. Can be 'Alternative', 'Data', 'Source', 'Supplement' or 'Unspecified'.
* @returns filespec reference
*/
file(src, options = {}) {
options.name = options.name || src;
options.relationship = options.relationship || 'Unspecified';

const refBody = {
Type: 'EmbeddedFile',
@@ -85,6 +87,7 @@ export default {
// add filespec for embedded file
const fileSpecBody = {
Type: 'Filespec',
AFRelationship: options.relationship,
F: new String(options.name),
EF: { F: ref },
UF: new String(options.name)
@@ -99,6 +102,13 @@ export default {
this.addNamedEmbeddedFile(options.name, filespec);
}

// Add file to the catalogue to be PDF/A3 compliant
if (this._root.data.AF) {
this._root.data.AF.push(filespec);
} else {
this._root.data.AF = [filespec];
}

return filespec;
}
};
@@ -110,6 +120,7 @@ function isEqual(a, b) {
a.Params.CheckSum.toString() === b.Params.CheckSum.toString() &&
a.Params.Size === b.Params.Size &&
a.Params.CreationDate.getTime() === b.Params.CreationDate.getTime() &&
a.Params.ModDate.getTime() === b.Params.ModDate.getTime()
((a.Params.ModDate === undefined && b.Params.ModDate === undefined) ||
a.Params.ModDate.getTime() === b.Params.ModDate.getTime())
);
}
5 changes: 2 additions & 3 deletions lib/mixins/text.js
Original file line number Diff line number Diff line change
@@ -153,12 +153,11 @@ export default {
}
};

const drawListItem = function(listItem) {
const drawListItem = function(listItem, i) {
wrapper = new LineWrapper(this, options);
wrapper.on('line', this._line);

level = 1;
let i = 0;
wrapper.once('firstLine', () => {
let item, itemType, labelType, bodyType;
if (options.structParent) {
@@ -225,7 +224,7 @@ export default {


for (let i = 0; i < items.length; i++) {
drawListItem.call(this, items[i]);
drawListItem.call(this, items[i], i);
}

return this;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
"document",
"vector"
],
"version": "0.15.1",
"version": "0.15.2",
"homepage": "http://pdfkit.org/",
"author": {
"name": "Devon Govett",
6 changes: 4 additions & 2 deletions tests/unit/attachments.spec.js
Original file line number Diff line number Diff line change
@@ -54,6 +54,7 @@ describe('file', () => {
`9 0 obj`,
`<<
/Type /Filespec
/AFRelationship /Unspecified
/F (file.txt)
/EF <<
/F 8 0 R
@@ -112,6 +113,7 @@ describe('file', () => {
`9 0 obj`,
`<<
/Type /Filespec
/AFRelationship /Unspecified
/F (file.txt)
/EF <<
/F 8 0 R
@@ -212,9 +214,9 @@ describe('file', () => {
document.end();

const numFiles = docData.filter((str) => typeof str === 'string' && str.startsWith('<<\n/Type /EmbeddedFile\n'))

expect(numFiles.length).toEqual(1)

expect(docData).toContainChunk([
`2 0 obj`,
`<<
4 changes: 2 additions & 2 deletions tests/unit/document.spec.js
Original file line number Diff line number Diff line change
@@ -54,12 +54,12 @@ describe('PDFDocument', () => {
doc.end();

let catalog = data[data.length-28];

expect(catalog).toContain('/Metadata');
});

test('metadata is NOT present for PDF 1.3', () => {
let doc = new PDFDocument({pdfVersion: '1.3'});
let doc = new PDFDocument({pdfVersion: '1.3'});
const data = logData(doc);
doc.end();

37 changes: 30 additions & 7 deletions tests/unit/pdfa1.spec.js
Original file line number Diff line number Diff line change
@@ -2,14 +2,14 @@ import PDFDocument from '../../lib/document';
import { logData, joinTokens } from './helpers';

describe('PDF/A-1', () => {

test('metadata is present', () => {
let options = {
autoFirstPage: false,
pdfVersion: '1.4',
subset: 'PDF/A-1'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
expect(data).toContainChunk([
@@ -36,7 +36,7 @@ describe('PDF/A-1', () => {
pdfVersion: '1.4',
subset: 'PDF/A-1'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
expect(data).toContainChunk(expected);
@@ -48,7 +48,7 @@ describe('PDF/A-1', () => {
pdfVersion: '1.4',
subset: 'PDF/A-1'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
let metadata = Buffer.from(data[27]).toString();
@@ -63,7 +63,7 @@ describe('PDF/A-1', () => {
pdfVersion: '1.4',
subset: 'PDF/A-1b'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
let metadata = Buffer.from(data[27]).toString();
@@ -77,12 +77,35 @@ describe('PDF/A-1', () => {
pdfVersion: '1.4',
subset: 'PDF/A-1a'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
let metadata = Buffer.from(data[27]).toString();

expect(metadata).toContain('pdfaid:conformance>A');
});


test('font data contains CIDSet', () => {
let options = {
autoFirstPage: false,
pdfVersion: '1.4',
subset: 'PDF/A-1a'
};
let doc = new PDFDocument(options);
const data = logData(doc);
doc.addPage();
doc.registerFont('Roboto', 'tests/fonts/Roboto-Regular.ttf');
doc.font('Roboto');
doc.text('Text');
doc.end();

let fontDescriptor = data.find((v) => {
return v.includes('/Type /FontDescriptor');
});

expect(fontDescriptor).not.toBeUndefined();

expect(fontDescriptor).toContain('/CIDSet');
});

});
37 changes: 30 additions & 7 deletions tests/unit/pdfa2.spec.js
Original file line number Diff line number Diff line change
@@ -2,14 +2,14 @@ import PDFDocument from '../../lib/document';
import { logData, joinTokens } from './helpers';

describe('PDF/A-2', () => {

test('metadata is present', () => {
let options = {
autoFirstPage: false,
pdfVersion: '1.7',
subset: 'PDF/A-2'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
expect(data).toContainChunk([
@@ -36,7 +36,7 @@ describe('PDF/A-2', () => {
pdfVersion: '1.7',
subset: 'PDF/A-2'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
expect(data).toContainChunk(expected);
@@ -48,7 +48,7 @@ describe('PDF/A-2', () => {
pdfVersion: '1.7',
subset: 'PDF/A-2'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
let metadata = Buffer.from(data[27]).toString();
@@ -63,7 +63,7 @@ describe('PDF/A-2', () => {
pdfVersion: '1.7',
subset: 'PDF/A-2b'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
let metadata = Buffer.from(data[27]).toString();
@@ -77,12 +77,35 @@ describe('PDF/A-2', () => {
pdfVersion: '1.7',
subset: 'PDF/A-2a'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
let metadata = Buffer.from(data[27]).toString();

expect(metadata).toContain('pdfaid:conformance>A');
});


test('font data NOT contains CIDSet', () => {
let options = {
autoFirstPage: false,
pdfVersion: '1.4',
subset: 'PDF/A-2a'
};
let doc = new PDFDocument(options);
const data = logData(doc);
doc.addPage();
doc.registerFont('Roboto', 'tests/fonts/Roboto-Regular.ttf');
doc.font('Roboto');
doc.text('Text');
doc.end();

let fontDescriptor = data.find((v) => {
return v.includes('/Type /FontDescriptor');
});

expect(fontDescriptor).not.toBeUndefined();

expect(fontDescriptor).not.toContain('/CIDSet');
});

});
37 changes: 30 additions & 7 deletions tests/unit/pdfa3.spec.js
Original file line number Diff line number Diff line change
@@ -2,14 +2,14 @@ import PDFDocument from '../../lib/document';
import { logData, joinTokens } from './helpers';

describe('PDF/A-3', () => {

test('metadata is present', () => {
let options = {
autoFirstPage: false,
pdfVersion: '1.7',
subset: 'PDF/A-3'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
expect(data).toContainChunk([
@@ -36,7 +36,7 @@ describe('PDF/A-3', () => {
pdfVersion: '1.7',
subset: 'PDF/A-3'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
expect(data).toContainChunk(expected);
@@ -48,7 +48,7 @@ describe('PDF/A-3', () => {
pdfVersion: '1.7',
subset: 'PDF/A-3'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
let metadata = Buffer.from(data[27]).toString();
@@ -63,7 +63,7 @@ describe('PDF/A-3', () => {
pdfVersion: '1.7',
subset: 'PDF/A-3b'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
let metadata = Buffer.from(data[27]).toString();
@@ -77,12 +77,35 @@ describe('PDF/A-3', () => {
pdfVersion: '1.7',
subset: 'PDF/A-3a'
};
let doc = new PDFDocument(options);
let doc = new PDFDocument(options);
const data = logData(doc);
doc.end();
let metadata = Buffer.from(data[27]).toString();

expect(metadata).toContain('pdfaid:conformance>A');
});


test('font data NOT contains CIDSet', () => {
let options = {
autoFirstPage: false,
pdfVersion: '1.4',
subset: 'PDF/A-3a'
};
let doc = new PDFDocument(options);
const data = logData(doc);
doc.addPage();
doc.registerFont('Roboto', 'tests/fonts/Roboto-Regular.ttf');
doc.font('Roboto');
doc.text('Text');
doc.end();

let fontDescriptor = data.find((v) => {
return v.includes('/Type /FontDescriptor');
});

expect(fontDescriptor).not.toBeUndefined();

expect(fontDescriptor).not.toContain('/CIDSet');
});

});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions tests/visual/text.spec.js
Original file line number Diff line number Diff line change
@@ -62,6 +62,34 @@ describe('text', function() {
return runDocTest(function(doc) {
doc.font('tests/fonts/Roboto-Regular.ttf');
doc.list(['Foo\nBar', 'Foo\rBar', 'Foo\r\nBar'], [100, 150]);
});
});

test('list (numbered)', function() {
return runDocTest(function(doc) {
doc.font('tests/fonts/Roboto-Regular.ttf');
doc.fillColor('#000').list(['One', 'Two', 'Three'], 100, 150, {listType: 'numbered'});
});
});

test('list (lettered)', function() {
return runDocTest(function(doc) {
doc.font('tests/fonts/Roboto-Regular.ttf');
doc.fillColor('#000').list(['One', 'Two', 'Three'], 100, 150, {listType: 'lettered'});
});
});

test('list with sub-list (unordered)', function() {
return runDocTest(function(doc) {
doc.font('tests/fonts/Roboto-Regular.ttf');
doc.fillColor('#000').list(['One', ['One.One', 'One.Two'], 'Three'], 100, 150);
})
})

test('list with sub-list (ordered)', function() {
return runDocTest(function(doc) {
doc.font('tests/fonts/Roboto-Regular.ttf');
doc.fillColor('#000').list(['One', ['One.One', 'One.Two'], 'Three'], 100, 150, {listType: 'numbered'});
})
})
});

0 comments on commit 2f19e92

Please sign in to comment.