Skip to content
This repository has been archived by the owner on Apr 12, 2021. It is now read-only.

replaced all new Buffer with Buffer.alloc and Buffer.from #9

Open
wants to merge 52 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
f91bdd6
Features/outline (#831)
theBenForce Jun 22, 2018
56c7deb
Fix linewrapper ellipsis inifinite loop (#779)
Ketler13 Jun 29, 2018
7839a41
Long running loop fix (#796)
Mike-Koder Jun 29, 2018
93061f3
Fix bug with \n translation (#797)
Mike-Koder Jun 29, 2018
2567227
Allows the text continue feature to work when the starting string is …
pretzelfisch Jun 29, 2018
6e72e0f
Fix build config
diegomura Nov 23, 2018
83f5f72
Convert to EcmaScript (ES6+) (#859)
blikblum Nov 29, 2018
b3c2790
Add initial reference spec
blikblum Dec 17, 2018
6f0d5ff
Merge pull request #883 from blikblum/add-reference-unit-test
blikblum Dec 17, 2018
f5b6ddd
Add PDF security features with ES6
zesik Dec 6, 2018
2ef9d7d
Allow customization of randomizer
zesik Dec 16, 2018
870260c
Add tests for security features and update snapshots
zesik Dec 16, 2018
678148a
Downgrade dependency version to avoid fs operation
zesik Dec 16, 2018
6398cca
Update readme and docs
zesik Dec 16, 2018
2651a74
Organize permissions in option to an object
zesik Dec 17, 2018
c400dfa
Add unit tests for trailer
zesik Dec 18, 2018
d5d8e3c
Merge pull request #820 from zesik/master
blikblum Dec 19, 2018
5274136
Complete coffee -> JS conversion of docs
blikblum Dec 17, 2018
aec971f
Rename docs files, removing the coffee sufix
blikblum Dec 19, 2018
e595a8e
Convert coffeescript code in README.md
blikblum Dec 19, 2018
3eae185
Remove coffee-script dependency
blikblum Dec 20, 2018
c09cd64
Merge pull request #884 from blikblum/cleanup-docs
blikblum Dec 20, 2018
883983a
Import test dependencies directly from src through babel-jest. Adapt …
blikblum Dec 20, 2018
5f125f7
Mock PDFSecurity methods in tests to ensure same output accross diffe…
blikblum Dec 20, 2018
8bf29c5
Update saved snapshots
blikblum Dec 20, 2018
a1156fb
Move integration tests into a separated directory and add script to r…
blikblum Dec 20, 2018
6488c53
Use sync version of zlib deflate method to compress png images
blikblum Dec 21, 2018
fe8632b
Add png-benchmark demo
blikblum Dec 21, 2018
56d4327
Merge pull request #886 from blikblum/improve-tests
blikblum Dec 21, 2018
4e90b87
Remove setTimeout call in PDFReference.finalize
blikblum Dec 21, 2018
52c3b45
Use property getter to define PDFPage lazy dictionaries
blikblum Dec 21, 2018
f2208a7
Add png unit tests
blikblum Dec 22, 2018
acef5e0
Merge pull request #887 from blikblum/remove-reference-timeout
blikblum Dec 23, 2018
8f1bb8c
Merge pull request #888 from blikblum/simplify-pdfpage
blikblum Dec 23, 2018
eb60ed1
Merge pull request #889 from blikblum/png-sync
blikblum Dec 23, 2018
faad6e8
Fix defining Mask for grayscale transparent PNG files
blikblum Dec 23, 2018
7c6134a
Add new png tests
blikblum Dec 23, 2018
ffdda49
Fix grayscale PNG images with alpha channel
blikblum Dec 23, 2018
acbeceb
Use a loop to copy png image data instead of Buffer.copy
blikblum Dec 23, 2018
2955161
Merge pull request #891 from blikblum/fix-grayscale-png
blikblum Dec 24, 2018
b7edc73
Fix 16bit png files with alpha channel
blikblum Dec 24, 2018
dfb5f93
Avoid code duplication in copy image data routine
blikblum Dec 24, 2018
b83371e
Merge pull request #893 from blikblum/fix-16bit-alpha
blikblum Dec 24, 2018
ea7927c
Remove outdated Gratipay reference (#896)
ryjones Dec 26, 2018
147ebfd
Rename src to lib (compatible to fork)
diegomura Dec 28, 2018
87bdaef
Merge branch 'master' of github.com:foliojs/pdfkit into fork
diegomura Dec 28, 2018
5f42512
Apply changes needed for react-pdf
diegomura Dec 29, 2018
b1a15b2
Remove deprecated methods from document
diegomura Dec 29, 2018
eda7bc5
Resolve conflicts with foliojs master
diegomura Dec 29, 2018
ec35445
Add browser check for PDF images
diegomura Dec 29, 2018
49f2c5c
Restore page margins constant
diegomura Dec 29, 2018
5cbed93
replaced all new Buffer with Buffer.alloc and Buffer.from
May 14, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"presets": [["env", {"modules": false, "targets": {"node": "6.10"}}]],
"env": {
"test": {
"presets": [["env", {"targets": {"node": "6.10"}}]]
}
}
}
3 changes: 3 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "eslint:recommended"
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ demo/bundle.js
!demo/browser.html
dist
*.b64.afm
.vscode
coverage
7 changes: 7 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@ demo/
lib/
docs/
playground/
.vscode/
coverage/
tests/
index.js
index.html
yarn.lock
rollup.config.js
.eslintrc
113 changes: 57 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@

A JavaScript PDF generation library for Node and the browser.

[![](https://img.shields.io/gratipay/devongovett.svg)](https://gratipay.com/devongovett)

## Description

PDFKit is a PDF document generation library for Node and the browser that makes creating complex, multi-page, printable documents easy.
It's written in CoffeeScript, but you can choose to use the API in plain 'ol JavaScript if you like. The API embraces
chainability, and includes both low level functions as well as abstractions for higher level functionality. The PDFKit API
PDFKit is a PDF document generation library for Node and the browser that makes creating complex, multi-page, printable documents easy.
It's written in CoffeeScript, but you can choose to use the API in plain 'ol JavaScript if you like. The API embraces
chainability, and includes both low level functions as well as abstractions for higher level functionality. The PDFKit API
is designed to be simple, so generating complex documents is often as simple as a few function calls.

Check out some of the [documentation and examples](http://pdfkit.org/docs/getting_started.html) to see for yourself!
Expand Down Expand Up @@ -48,72 +46,74 @@ Installation uses the [npm](http://npmjs.org/) package manager. Just type the f
* Highlights
* Underlines
* etc.

* Outlines
* PDF security
* Encryption
* Access privileges (printing, copying, modifying, annotating, form filling, content accessibility, document assembly)

## Coming soon!

* Patterns fills
* Outlines
* PDF Security
* Higher level APIs for creating tables and laying out content
* More performance optimizations
* Even more awesomeness, perhaps written by you! Please fork this repository and send me pull requests.

## Example

```coffeescript
PDFDocument = require 'pdfkit'
```javascript
const PDFDocument = require('pdfkit');

# Create a document
doc = new PDFDocument
// Create a document
const doc = new PDFDocument;

# Pipe its output somewhere, like to a file or HTTP response
# See below for browser usage
doc.pipe fs.createWriteStream('output.pdf')
// Pipe its output somewhere, like to a file or HTTP response
// See below for browser usage
doc.pipe(fs.createWriteStream('output.pdf'));

# Embed a font, set the font size, and render some text
// Embed a font, set the font size, and render some text
doc.font('fonts/PalatinoBold.ttf')
.fontSize(25)
.text('Some text with an embedded font!', 100, 100)
.text('Some text with an embedded font!', 100, 100);

# Add an image, constrain it to a given size, and center it vertically and horizontally
// Add an image, constrain it to a given size, and center it vertically and horizontally
doc.image('path/to/image.png', {
fit: [250, 300],
align: 'center',
valign: 'center'
});

# Add another page
// Add another page
doc.addPage()
.fontSize(25)
.text('Here is some vector graphics...', 100, 100)
.text('Here is some vector graphics...', 100, 100);

# Draw a triangle
// Draw a triangle
doc.save()
.moveTo(100, 150)
.lineTo(100, 250)
.lineTo(200, 250)
.fill("#FF3300")
.fill("#FF3300");

# Apply some transforms and render an SVG path with the 'even-odd' fill rule
// Apply some transforms and render an SVG path with the 'even-odd' fill rule
doc.scale(0.6)
.translate(470, -380)
.path('M 250,75 L 323,301 131,161 369,161 177,301 z')
.fill('red', 'even-odd')
.restore()
.restore();

# Add some text with annotations
// Add some text with annotations
doc.addPage()
.fillColor("blue")
.text('Here is a link!', 100, 100)
.underline(100, 100, 160, 27, color: "#0000FF")
.link(100, 100, 160, 27, 'http://google.com/')
.underline(100, 100, 160, 27, {color: "#0000FF"})
.link(100, 100, 160, 27, 'http://google.com/');

# Finalize PDF file
doc.end()
// Finalize PDF file
doc.end();
```
[The PDF output from this example](http://pdfkit.org/demo/out.pdf) (with a few additions) shows the power of PDFKit — producing
complex documents with a very small amount of code. For more, see the `demo` folder and the

[The PDF output from this example](http://pdfkit.org/demo/out.pdf) (with a few additions) shows the power of PDFKit — producing
complex documents with a very small amount of code. For more, see the `demo` folder and the
[PDFKit programming guide](http://pdfkit.org/docs/getting_started.html).

## Browser Usage
Expand All @@ -122,44 +122,45 @@ There are two ways to use PDFKit in the browser. The first is to use [Browserif
which is a Node module packager for the browser with the familiar `require` syntax. The second is to use
a prebuilt version of PDFKit, which you can [download from Github](https://github.com/devongovett/pdfkit/releases).

In addition to PDFKit, you'll need somewhere to stream the output to. HTML5 has a
In addition to PDFKit, you'll need somewhere to stream the output to. HTML5 has a
[Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object which can be used to store binary data, and
get URLs to this data in order to display PDF output inside an iframe, or upload to a server, etc. In order to
get URLs to this data in order to display PDF output inside an iframe, or upload to a server, etc. In order to
get a Blob from the output of PDFKit, you can use the [blob-stream](https://github.com/devongovett/blob-stream)
module.

The following example uses Browserify to load `PDFKit` and `blob-stream`, but if you're not using Browserify,
The following example uses Browserify to load `PDFKit` and `blob-stream`, but if you're not using Browserify,
you can load them in whatever way you'd like (e.g. script tags).

```coffeescript
# require dependencies
PDFDocument = require 'pdfkit'
blobStream = require 'blob-stream'
```javascript
// require dependencies
const PDFDocument = require('pdfkit');
const blobStream = require('blob-stream');

# create a document the same way as above
doc = new PDFDocument
// create a document the same way as above
const doc = new PDFDocument;

# pipe the document to a blob
stream = doc.pipe(blobStream())
// pipe the document to a blob
const stream = doc.pipe(blobStream());

# add your content to the document here, as usual
// add your content to the document here, as usual

# get a blob when you're done
doc.end()
stream.on 'finish', ->
# get a blob you can do whatever you like with
blob = stream.toBlob('application/pdf')
// get a blob when you're done
doc.end();
stream.on('finish', function() {
// get a blob you can do whatever you like with
const blob = stream.toBlob('application/pdf');

# or get a blob URL for display in the browser
url = stream.toBlobURL('application/pdf')
iframe.src = url
// or get a blob URL for display in the browser
const url = stream.toBlobURL('application/pdf');
iframe.src = url;
});
```

You can see an interactive in-browser demo of PDFKit [here](http://pdfkit.org/demo/browser.html).

Note that in order to Browserify a project using PDFKit, you need to install the `brfs` module with npm,
which is used to load built-in font data into the package. It is listed as a `devDependency` in
PDFKit's `package.json`, so it isn't installed by default for Node users.
Note that in order to Browserify a project using PDFKit, you need to install the `brfs` module with npm,
which is used to load built-in font data into the package. It is listed as a `devDependency` in
PDFKit's `package.json`, so it isn't installed by default for Node users.
If you forget to install it, Browserify will print an error message.

## Documentation
Expand Down
Binary file added demo/out.pdf
Binary file not shown.
33 changes: 33 additions & 0 deletions demo/png-benchmark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const PDFDocument = require('../');
const fs = require('fs');

const doc = new PDFDocument();

// files with alpha channel -> uses zlib.deflate
const files = [
'test.png',
'test3.png'
];

const filesData = files.map(fileName => {
return fs.readFileSync(`images/${fileName}`);
});

const iterationCount = 100;

console.time('png-bench')

for (let i = 0; i < iterationCount; i++) {
filesData.forEach(data => {
doc.image(data)
doc.addPage()
})
}

doc.on('data', () => {})

doc.on('end', () => {
console.timeEnd('png-bench');
});

doc.end();
80 changes: 80 additions & 0 deletions demo/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
var PDFDocument = require('../');
var tiger = require('./tiger');
var fs = require('fs');

// Create a new PDFDocument
var doc = new PDFDocument;

doc.pipe(fs.createWriteStream('out.pdf'));

// Set some meta data
doc.info['Title'] = 'Test Document';

doc.info['Author'] = 'Devon Govett';

// Register a font name for use later
doc.registerFont('Palatino', 'fonts/PalatinoBold.ttf');

// Set the font, draw some text, and embed an image
doc.font('Palatino').fontSize(25).text('Some text with an embedded font!', 100, 100).fontSize(18).text('PNG and JPEG images:').image('images/test.png', 100, 160, {
width: 412
}).image('images/test.jpeg', 190, 400, {
height: 300
});

// Add another page
doc.addPage().fontSize(25).text('Here is some vector graphics...', 100, 100);

// Draw a triangle and a circle
doc.save().moveTo(100, 150).lineTo(100, 250).lineTo(200, 250).fill("#FF3300");

doc.circle(280, 200, 50).fill("#6600FF");

doc.scale(0.6).translate(470, -380).path('M 250,75 L 323,301 131,161 369,161 177,301 z').fill('red', 'even-odd').restore(); // render an SVG path // fill using the even-odd winding rule

var loremIpsum = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam in suscipit purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus nec hendrerit felis. Morbi aliquam facilisis risus eu lacinia. Sed eu leo in turpis fringilla hendrerit. Ut nec accumsan nisl. Suspendisse rhoncus nisl posuere tortor tempus et dapibus elit porta. Cras leo neque, elementum a rhoncus ut, vestibulum non nibh. Phasellus pretium justo turpis. Etiam vulputate, odio vitae tincidunt ultricies, eros odio dapibus nisi, ut tincidunt lacus arcu eu elit. Aenean velit erat, vehicula eget lacinia ut, dignissim non tellus. Aliquam nec lacus mi, sed vestibulum nunc. Suspendisse potenti. Curabitur vitae sem turpis. Vestibulum sed neque eget dolor dapibus porttitor at sit amet sem. Fusce a turpis lorem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;\nMauris at ante tellus. Vestibulum a metus lectus. Praesent tempor purus a lacus blandit eget gravida ante hendrerit. Cras et eros metus. Sed commodo malesuada eros, vitae interdum augue semper quis. Fusce id magna nunc. Curabitur sollicitudin placerat semper. Cras et mi neque, a dignissim risus. Nulla venenatis porta lacus, vel rhoncus lectus tempor vitae. Duis sagittis venenatis rutrum. Curabitur tempor massa tortor.';

// Draw some text wrapped to 412 points wide
doc.text('And here is some wrapped text...', 100, 300).font('Helvetica', 13).moveDown().text(loremIpsum, { // move down 1 line
width: 412,
align: 'justify',
indent: 30,
paragraphGap: 5
});

// Add another page, and set the font back
doc.addPage().font('Palatino', 25).text('Rendering some SVG paths...', 100, 100).translate(220, 300);

var i, len, part;
// Render each path that makes up the tiger image
for (i = 0, len = tiger.length; i < len; i++) {
part = tiger[i];
doc.save();
doc.path(part.path); // render an SVG path
if (part['stroke-width']) {
doc.lineWidth(part['stroke-width']);
}
if (part.fill !== 'none' && part.stroke !== 'none') {
doc.fillAndStroke(part.fill, part.stroke);
} else {
if (part.fill !== 'none') {
doc.fill(part.fill);
}
if (part.stroke !== 'none') {
doc.stroke(part.stroke);
}
}
doc.restore();
}

// Add some text with annotations
doc.addPage().fillColor("blue").text('Here is a link!', 100, 100, {
link: 'http://google.com/',
underline: true
});


// Add a list with a font loaded from a TrueType collection file
doc.fillColor('#000').font('fonts/Chalkboard.ttc', 'Chalkboard', 16).list(['One', 'Two', 'Three'], 100, 150);

doc.end();
22 changes: 22 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# PDFKit Guide

The PDFKit guide can be read a number of ways. The first is online at [pdfkit.org](http://pdfkit.org/).
You can also read the guide in PDF form, in this directory or [online](http://pdfkit.org/docs/guide.pdf).

Both the website and the PDF guide are generated from the Literate CoffeeScript (runnable Markdown) files
in this directory. The examples are actually run when generating the PDF in order to show the results inline.
The `generate.js` file in this directory is actually quite short. It parses the markdown files into a
tree structure using [markdown-js](https://github.com/evilstreak/markdown-js), syntax highlights the code
examples using [codemirror](https://github.com/marijnh/codemirror), compiles and runs the code examples and puts the results
inline, and generates the PDF using PDFKit. You can read the generator script source code to get a feeling for
how you might do something slightly more complex than the guide itself shows.

The markdown syntax used is pretty much standard, with a couple tweaks.

1. Code example output is references using the image notation, using the alt text as the example number starting from
zero in the current file, and the title as the example output height. E.g. `![x](name "height")`.

2. Page breaks are added before `h1` and `h2`s, unless there are two in a row. `h3` is treated the same as `h2` but
can be used to avoid this in the case you need multiple `h2`s on the same page.

3. The horizontal rule syntax (`* * *`) denotes an explicit page break
Loading