function ReadableState(options, stream) { options = options || {}; // object stream flag. Used to make read(n) ignore n and to // make all the buffer merging and length checks go away this.objectMode = !!options.objectMode; if (stream instanceof Stream.Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; // the point at which it stops calling _read() to fill the buffer // Note: 0 is a valid value, means "don't call _read preemptively ever" var hwm = options.highWaterMark; var defaultHwm = this.objectMode ? 16 : 16 * 1024; this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; // cast to ints. this.highWaterMark = ~~this.highWaterMark; // A linked list is used to store data chunks instead of an array because the // linked list can remove elements from the beginning faster than // array.shift() this.buffer = new BufferList(); this.length = 0; this.pipes = null; this.pipesCount = 0; this.flowing = null; this.ended = false; this.endEmitted = false; this.reading = false; // a flag to be able to tell if the onwrite cb is called immediately, // or on a later tick. We set this to true at first, because any // actions that shouldn't happen until "later" should generally also // not happen before the first write call. this.sync = true; // whenever we return null, then we set a flag to say // that we're awaiting a 'readable' event emission. this.needReadable = false; this.emittedReadable = false; this.readableListening = false; this.resumeScheduled = false; // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. // Everything else in the universe uses 'utf8', though. this.defaultEncoding = options.defaultEncoding || 'utf8'; // when piping, we only care about 'readable' events that happen // after read()ing all the bytes and not getting any pushback. this.ranOut = false; // the number of writers that are awaiting a drain event in .pipe()s this.awaitDrain = 0; // if true, a maybeReadMore has been scheduled this.readingMore = false; this.decoder = null; this.encoding = null; if (options.encoding) { if (!StringDecoder) StringDecoder = require('string_decoder').StringDecoder; this.decoder = new StringDecoder(options.encoding); this.encoding = options.encoding; } }
n/a
function fromList(n, state) { // nothing buffered if (state.length === 0) return null; var ret; if (state.objectMode) ret = state.buffer.shift(); else if (!n || n >= state.length) { // read it all, truncate the list if (state.decoder) ret = state.buffer.join(''); else if (state.buffer.length === 1) ret = state.buffer.head.data; else ret = state.buffer.concat(state.length); state.buffer.clear(); } else { // read part of list ret = fromListPartial(n, state.buffer, state.decoder); } return ret; }
n/a
function Data(data) { this.data = data != null ? data : []; this.pos = 0; this.length = this.data.length; }
n/a
function PDFFont() { throw new Error('Cannot construct a PDFFont directly.'); }
...
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')
# 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)
# Add another page
doc.addPage()
.fontSize(25)
.text('Here is some vector graphics...', 100, 100)
...
function PDFImage() {}
n/a
function LineWrapper(document, options) { var ref; this.document = document; this.indent = options.indent || 0; this.characterSpacing = options.characterSpacing || 0; this.wordSpacing = options.wordSpacing === 0; this.columns = options.columns || 1; this.columnGap = (ref = options.columnGap) != null ? ref : 18; this.lineWidth = (options.width - (this.columnGap * (this.columns - 1))) / this.columns; this.spaceLeft = this.lineWidth; this.startX = this.document.x; this.startY = this.document.y; this.column = 1; this.ellipsis = options.ellipsis; this.continuedX = 0; this.features = options.features; if (options.height != null) { this.height = options.height; this.maxY = this.startY + options.height; } else { this.maxY = this.document.page.maxY(); } this.on('firstLine', (function(_this) { return function(options) { var indent; indent = _this.continuedX || _this.indent; _this.document.x += indent; _this.lineWidth -= indent; return _this.once('line', function() { _this.document.x -= indent; _this.lineWidth += indent; if (options.continued && !_this.continuedX) { _this.continuedX = _this.indent; } if (!options.continued) { return _this.continuedX = 0; } }); }; })(this)); this.on('lastLine', (function(_this) { return function(options) { var align; align = options.align; if (align === 'justify') { options.align = 'left'; } _this.lastLine = true; return _this.once('line', function() { _this.document.y += options.paragraphGap || 0; options.align = align; return _this.lastLine = false; }); }; })(this)); }
n/a
function PDFObject() {}
n/a
function PDFPage(document, options) { var dimensions; this.document = document; if (options == null) { options = {}; } this.size = options.size || 'letter'; this.layout = options.layout || 'portrait'; if (typeof options.margin === 'number') { this.margins = { top: options.margin, left: options.margin, bottom: options.margin, right: options.margin }; } else { this.margins = options.margins || DEFAULT_MARGINS; } dimensions = Array.isArray(this.size) ? this.size : SIZES[this.size.toUpperCase()]; this.width = dimensions[this.layout === 'portrait' ? 0 : 1]; this.height = dimensions[this.layout === 'portrait' ? 1 : 0]; this.content = this.document.ref(); this.resources = this.document.ref({ ProcSet: ['PDF', 'Text', 'ImageB', 'ImageC', 'ImageI'] }); Object.defineProperties(this, { fonts: { get: (function(_this) { return function() { var base; return (base = _this.resources.data).Font != null ? base.Font : base.Font = {}; }; })(this) }, xobjects: { get: (function(_this) { return function() { var base; return (base = _this.resources.data).XObject != null ? base.XObject : base.XObject = {}; }; })(this) }, ext_gstates: { get: (function(_this) { return function() { var base; return (base = _this.resources.data).ExtGState != null ? base.ExtGState : base.ExtGState = {}; }; })(this) }, patterns: { get: (function(_this) { return function() { var base; return (base = _this.resources.data).Pattern != null ? base.Pattern : base.Pattern = {}; }; })(this) }, annotations: { get: (function(_this) { return function() { var base; return (base = _this.dictionary.data).Annots != null ? base.Annots : base.Annots = []; }; })(this) } }); this.dictionary = this.document.ref({ Type: 'Page', Parent: this.document._root.data.Pages, MediaBox: [0, 0, this.width, this.height], Contents: this.content, Resources: this.resources }); }
n/a
function SVGPath() {}
...
.lineTo(100, 250)
.lineTo(200, 250)
.fill("#FF3300")
# 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()
# Add some text with annotations
doc.addPage()
.fillColor("blue")
.text('Here is a link!', 100, 100)
...
function PDFReference(document, id, data) { this.document = document; this.id = id; this.data = data != null ? data : {}; this.finalize = bind(this.finalize, this); PDFReference.__super__.constructor.call(this, { decodeStrings: false }); this.gen = 0; this.deflate = null; this.compress = this.document.compress && !this.data.Filter; this.uncompressedLength = 0; this.chunks = []; }
n/a
function Stream() { EE.call(this); }
n/a
function Data(data) { this.data = data != null ? data : []; this.pos = 0; this.length = this.data.length; }
n/a
byteAt = function (index) { return this.data[index]; }
n/a
read = function (bytes) { var buf, i, j, ref; buf = []; for (i = j = 0, ref = bytes; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) { buf.push(this.readByte()); } return buf; }
n/a
readBool = function () { return !!this.readByte(); }
n/a
readByte = function () { return this.data[this.pos++]; }
...
};
Data.prototype.byteAt = function(index) {
return this.data[index];
};
Data.prototype.readBool = function() {
return !!this.readByte();
};
Data.prototype.writeBool = function(val) {
return this.writeByte(val ? 1 : 0);
};
Data.prototype.readUInt32 = function() {
...
readInt = function () { return this.readInt32(); }
n/a
readInt16 = function () { var int; int = this.readUInt16(); if (int >= 0x8000) { return int - 0x10000; } else { return int; } }
...
Data.prototype.stringAt = function(pos, length) {
this.pos = pos;
return this.readString(length);
};
Data.prototype.readShort = function() {
return this.readInt16();
};
Data.prototype.writeShort = function(val) {
return this.writeInt16(val);
};
Data.prototype.readLongLong = function() {
...
readInt32 = function () { var int; int = this.readUInt32(); if (int >= 0x80000000) { return int - 0x100000000; } else { return int; } }
...
this.writeByte((low >> 24) & 0xff);
this.writeByte((low >> 16) & 0xff);
this.writeByte((low >> 8) & 0xff);
return this.writeByte(low & 0xff);
};
Data.prototype.readInt = function() {
return this.readInt32();
};
Data.prototype.writeInt = function(val) {
return this.writeInt32(val);
};
Data.prototype.slice = function(start, end) {
...
readLongLong = function () { var b1, b2, b3, b4, b5, b6, b7, b8; b1 = this.readByte(); b2 = this.readByte(); b3 = this.readByte(); b4 = this.readByte(); b5 = this.readByte(); b6 = this.readByte(); b7 = this.readByte(); b8 = this.readByte(); if (b1 & 0x80) { return ((b1 ^ 0xff) * 0x100000000000000 + (b2 ^ 0xff) * 0x1000000000000 + (b3 ^ 0xff) * 0x10000000000 + (b4 ^ 0xff) * 0x100000000 + (b5 ^ 0xff) * 0x1000000 + (b6 ^ 0xff) * 0x10000 + (b7 ^ 0xff) * 0x100 + (b8 ^ 0xff) + 1) * -1; } return b1 * 0x100000000000000 + b2 * 0x1000000000000 + b3 * 0x10000000000 + b4 * 0x100000000 + b5 * 0x1000000 + b6 * 0x10000 + b7 * 0x100 + b8; }
n/a
readShort = function () { return this.readInt16(); }
n/a
readString = function (length) { var i, j, ref, ret; ret = []; for (i = j = 0, ref = length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) { ret[i] = String.fromCharCode(this.readByte()); } return ret.join(''); }
...
results.push(this.writeByte(val.charCodeAt(i)));
}
return results;
};
Data.prototype.stringAt = function(pos, length) {
this.pos = pos;
return this.readString(length);
};
Data.prototype.readShort = function() {
return this.readInt16();
};
Data.prototype.writeShort = function(val) {
...
readUInt16 = function () { var b1, b2; b1 = this.readByte() << 8; b2 = this.readByte(); return b1 | b2; }
...
Data.prototype.writeUInt16 = function(val) {
this.writeByte((val >> 8) & 0xff);
return this.writeByte(val & 0xff);
};
Data.prototype.readInt16 = function() {
var int;
int = this.readUInt16();
if (int >= 0x8000) {
return int - 0x10000;
} else {
return int;
}
};
...
readUInt32 = function () { var b1, b2, b3, b4; b1 = this.readByte() * 0x1000000; b2 = this.readByte() << 16; b3 = this.readByte() << 8; b4 = this.readByte(); return b1 + b2 + b3 + b4; }
...
this.writeByte((val >> 16) & 0xff);
this.writeByte((val >> 8) & 0xff);
return this.writeByte(val & 0xff);
};
Data.prototype.readInt32 = function() {
var int;
int = this.readUInt32();
if (int >= 0x80000000) {
return int - 0x100000000;
} else {
return int;
}
};
...
slice = function (start, end) { return this.data.slice(start, end); }
...
};
Data.prototype.writeInt = function(val) {
return this.writeInt32(val);
};
Data.prototype.slice = function(start, end) {
return this.data.slice(start, end);
};
Data.prototype.read = function(bytes) {
var buf, i, j, ref;
buf = [];
for (i = j = 0, ref = bytes; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
buf.push(this.readByte());
...
stringAt = function (pos, length) { this.pos = pos; return this.readString(length); }
n/a
write = function (bytes) { var byte, j, len, results; results = []; for (j = 0, len = bytes.length; j < len; j++) { byte = bytes[j]; results.push(this.writeByte(byte)); } return results; }
...
}
PDFPage.prototype.maxY = function() {
return this.height - this.margins.bottom;
};
PDFPage.prototype.write = function(chunk) {
return this.content.write(chunk);
};
PDFPage.prototype.end = function() {
this.dictionary.end();
this.resources.end();
return this.content.end();
};
...
writeBool = function (val) { return this.writeByte(val ? 1 : 0); }
n/a
writeByte = function (byte) { return this.data[this.pos++] = byte; }
...
};
Data.prototype.readBool = function() {
return !!this.readByte();
};
Data.prototype.writeBool = function(val) {
return this.writeByte(val ? 1 : 0);
};
Data.prototype.readUInt32 = function() {
var b1, b2, b3, b4;
b1 = this.readByte() * 0x1000000;
b2 = this.readByte() << 16;
b3 = this.readByte() << 8;
...
writeInt = function (val) { return this.writeInt32(val); }
n/a
writeInt16 = function (val) { if (val < 0) { val += 0x10000; } return this.writeUInt16(val); }
...
};
Data.prototype.readShort = function() {
return this.readInt16();
};
Data.prototype.writeShort = function(val) {
return this.writeInt16(val);
};
Data.prototype.readLongLong = function() {
var b1, b2, b3, b4, b5, b6, b7, b8;
b1 = this.readByte();
b2 = this.readByte();
b3 = this.readByte();
...
writeInt32 = function (val) { if (val < 0) { val += 0x100000000; } return this.writeUInt32(val); }
...
};
Data.prototype.readInt = function() {
return this.readInt32();
};
Data.prototype.writeInt = function(val) {
return this.writeInt32(val);
};
Data.prototype.slice = function(start, end) {
return this.data.slice(start, end);
};
Data.prototype.read = function(bytes) {
...
writeLongLong = function (val) { var high, low; high = Math.floor(val / 0x100000000); low = val & 0xffffffff; this.writeByte((high >> 24) & 0xff); this.writeByte((high >> 16) & 0xff); this.writeByte((high >> 8) & 0xff); this.writeByte(high & 0xff); this.writeByte((low >> 24) & 0xff); this.writeByte((low >> 16) & 0xff); this.writeByte((low >> 8) & 0xff); return this.writeByte(low & 0xff); }
n/a
writeShort = function (val) { return this.writeInt16(val); }
n/a
writeString = function (val) { var i, j, ref, results; results = []; for (i = j = 0, ref = val.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) { results.push(this.writeByte(val.charCodeAt(i))); } return results; }
n/a
writeUInt16 = function (val) { this.writeByte((val >> 8) & 0xff); return this.writeByte(val & 0xff); }
...
}
};
Data.prototype.writeInt16 = function(val) {
if (val < 0) {
val += 0x10000;
}
return this.writeUInt16(val);
};
Data.prototype.readString = function(length) {
var i, j, ref, ret;
ret = [];
for (i = j = 0, ref = length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
ret[i] = String.fromCharCode(this.readByte());
...
writeUInt32 = function (val) { this.writeByte((val >>> 24) & 0xff); this.writeByte((val >> 16) & 0xff); this.writeByte((val >> 8) & 0xff); return this.writeByte(val & 0xff); }
...
}
};
Data.prototype.writeInt32 = function(val) {
if (val < 0) {
val += 0x100000000;
}
return this.writeUInt32(val);
};
Data.prototype.readUInt16 = function() {
var b1, b2;
b1 = this.readByte() << 8;
b2 = this.readByte();
return b1 | b2;
...
function PDFFont() { throw new Error('Cannot construct a PDFFont directly.'); }
...
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')
# 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)
# Add another page
doc.addPage()
.fontSize(25)
.text('Here is some vector graphics...', 100, 100)
...
open = function (document, src, family, id) { var font; if (typeof src === 'string') { if (StandardFont.isStandardFont(src)) { return new StandardFont(document, src, id); } font = fontkit.openSync(src, family); } else if (Buffer.isBuffer(src)) { font = fontkit.create(src, family); } else if (src instanceof Uint8Array) { font = fontkit.create(new Buffer(src), family); } else if (src instanceof ArrayBuffer) { font = fontkit.create(new Buffer(new Uint8Array(src)), family); } if (font == null) { throw new Error('Not a supported font format or standard PDF font.'); } return new EmbeddedFont(document, font, id); }
n/a
embed = function () { throw new Error('Must be implemented by subclasses'); }
...
return this.dictionary != null ? this.dictionary : this.dictionary = this.document.ref();
};
PDFFont.prototype.finalize = function() {
if (this.embedded || (this.dictionary == null)) {
return;
}
this.embed();
return this.embedded = true;
};
PDFFont.prototype.embed = function() {
throw new Error('Must be implemented by subclasses');
};
...
encode = function (text) { throw new Error('Must be implemented by subclasses'); }
n/a
finalize = function () { if (this.embedded || (this.dictionary == null)) { return; } this.embed(); return this.embedded = true; }
...
};
PDFReference.prototype.end = function(chunk) {
PDFReference.__super__.end.apply(this, arguments);
if (this.deflate) {
return this.deflate.end();
} else {
return this.finalize();
}
};
PDFReference.prototype.finalize = function() {
var chunk, i, len, ref;
this.offset = this.document._offset;
this.document._write(this.id + " " + this.gen + " obj");
...
lineHeight = function (size, includeGap) { var gap; if (includeGap == null) { includeGap = false; } gap = includeGap ? this.lineGap : 0; return (this.ascender + gap - this.descender) / 1000 * size; }
n/a
ref = function () { return this.dictionary != null ? this.dictionary : this.dictionary = this.document.ref(); }
...
};
PDFFont.prototype.widthOfString = function(text) {
throw new Error('Must be implemented by subclasses');
};
PDFFont.prototype.ref = function() {
return this.dictionary != null ? this.dictionary : this.dictionary = this.document.ref();
};
PDFFont.prototype.finalize = function() {
if (this.embedded || (this.dictionary == null)) {
return;
}
this.embed();
...
widthOfString = function (text) { throw new Error('Must be implemented by subclasses'); }
...
return _this.lastLine = false;
});
};
})(this));
}
LineWrapper.prototype.wordWidth = function(word) {
return this.document.widthOfString(word, this) + this.characterSpacing + this.wordSpacing
;
};
LineWrapper.prototype.eachWord = function(text, fn) {
var bk, breaker, fbk, l, last, lbk, shouldContinue, w, word, wordWidths;
breaker = new LineBreaker(text);
last = null;
wordWidths = Object.create(null);
...
function PDFGradient(doc) { this.doc = doc; this.stops = []; this.embedded = false; this.transform = [1, 0, 0, 1, 0, 0]; this._colorSpace = 'DeviceRGB'; }
n/a
function PDFLinearGradient(doc, x1, y1, x2, y2) { this.doc = doc; this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; PDFLinearGradient.__super__.constructor.apply(this, arguments); }
n/a
function PDFRadialGradient(doc, x1, y1, r1, x2, y2, r2) { this.doc = doc; this.x1 = x1; this.y1 = y1; this.r1 = r1; this.x2 = x2; this.y2 = y2; this.r2 = r2; PDFRadialGradient.__super__.constructor.apply(this, arguments); }
n/a
function PDFImage() {}
n/a
open = function (src, label) { var data, match; if (Buffer.isBuffer(src)) { data = src; } else if (src instanceof ArrayBuffer) { data = new Buffer(new Uint8Array(src)); } else { if (match = /^data:.+;base64,(.*)$/.exec(src)) { data = new Buffer(match[1], 'base64'); } else { data = fs.readFileSync(src); if (!data) { return; } } } if (data[0] === 0xff && data[1] === 0xd8) { return new JPEG(data, label); } else if (data[0] === 0x89 && data.toString('ascii', 1, 4) === 'PNG') { return new PNG(data, label); } else { throw new Error('Unknown image format.'); } }
n/a
function LineWrapper(document, options) { var ref; this.document = document; this.indent = options.indent || 0; this.characterSpacing = options.characterSpacing || 0; this.wordSpacing = options.wordSpacing === 0; this.columns = options.columns || 1; this.columnGap = (ref = options.columnGap) != null ? ref : 18; this.lineWidth = (options.width - (this.columnGap * (this.columns - 1))) / this.columns; this.spaceLeft = this.lineWidth; this.startX = this.document.x; this.startY = this.document.y; this.column = 1; this.ellipsis = options.ellipsis; this.continuedX = 0; this.features = options.features; if (options.height != null) { this.height = options.height; this.maxY = this.startY + options.height; } else { this.maxY = this.document.page.maxY(); } this.on('firstLine', (function(_this) { return function(options) { var indent; indent = _this.continuedX || _this.indent; _this.document.x += indent; _this.lineWidth -= indent; return _this.once('line', function() { _this.document.x -= indent; _this.lineWidth += indent; if (options.continued && !_this.continuedX) { _this.continuedX = _this.indent; } if (!options.continued) { return _this.continuedX = 0; } }); }; })(this)); this.on('lastLine', (function(_this) { return function(options) { var align; align = options.align; if (align === 'justify') { options.align = 'left'; } _this.lastLine = true; return _this.once('line', function() { _this.document.y += options.paragraphGap || 0; options.align = align; return _this.lastLine = false; }); }; })(this)); }
n/a
function EventEmitter() { EventEmitter.init.call(this); }
n/a
init = function () { this.domain = null; if (EventEmitter.usingDomains) { // if there is an active domain, then attach to it. domain = domain || require('domain'); if (domain.active && !(this instanceof domain.Domain)) { this.domain = domain.active; } } if (!this._events || this._events === Object.getPrototypeOf(this)._events) { this._events = new EventHandlers(); this._eventsCount = 0; } this._maxListeners = this._maxListeners || undefined; }
n/a
listenerCount = function (emitter, type) { if (typeof emitter.listenerCount === 'function') { return emitter.listenerCount(type); } else { return listenerCount.call(emitter, type); } }
n/a
function LineWrapper(document, options) { var ref; this.document = document; this.indent = options.indent || 0; this.characterSpacing = options.characterSpacing || 0; this.wordSpacing = options.wordSpacing === 0; this.columns = options.columns || 1; this.columnGap = (ref = options.columnGap) != null ? ref : 18; this.lineWidth = (options.width - (this.columnGap * (this.columns - 1))) / this.columns; this.spaceLeft = this.lineWidth; this.startX = this.document.x; this.startY = this.document.y; this.column = 1; this.ellipsis = options.ellipsis; this.continuedX = 0; this.features = options.features; if (options.height != null) { this.height = options.height; this.maxY = this.startY + options.height; } else { this.maxY = this.document.page.maxY(); } this.on('firstLine', (function(_this) { return function(options) { var indent; indent = _this.continuedX || _this.indent; _this.document.x += indent; _this.lineWidth -= indent; return _this.once('line', function() { _this.document.x -= indent; _this.lineWidth += indent; if (options.continued && !_this.continuedX) { _this.continuedX = _this.indent; } if (!options.continued) { return _this.continuedX = 0; } }); }; })(this)); this.on('lastLine', (function(_this) { return function(options) { var align; align = options.align; if (align === 'justify') { options.align = 'left'; } _this.lastLine = true; return _this.once('line', function() { _this.document.y += options.paragraphGap || 0; options.align = align; return _this.lastLine = false; }); }; })(this)); }
n/a
eachWord = function (text, fn) { var bk, breaker, fbk, l, last, lbk, shouldContinue, w, word, wordWidths; breaker = new LineBreaker(text); last = null; wordWidths = Object.create(null); while (bk = breaker.nextBreak()) { word = text.slice((last != null ? last.position : void 0) || 0, bk.position); w = wordWidths[word] != null ? wordWidths[word] : wordWidths[word] = this.wordWidth(word); if (w > this.lineWidth + this.continuedX) { lbk = last; fbk = {}; while (word.length) { l = word.length; while (w > this.spaceLeft) { w = this.wordWidth(word.slice(0, --l)); } fbk.required = l < word.length; shouldContinue = fn(word.slice(0, l), w, fbk, lbk); lbk = { required: false }; word = word.slice(l); w = this.wordWidth(word); if (shouldContinue === false) { break; } } } else { shouldContinue = fn(word, w, bk, last); } if (shouldContinue === false) { break; } last = bk; } }
...
options.lineWidth = _this.lineWidth;
y = _this.document.y;
_this.emit('line', buffer, options, _this);
return lc++;
};
})(this);
this.emit('sectionStart', options, this);
this.eachWord(text, (function(_this) {
return function(word, w, bk, last) {
var lh, shouldContinue;
if ((last == null) || last.required) {
_this.emit('firstLine', options, _this);
_this.spaceLeft = _this.lineWidth;
}
if (w <= _this.spaceLeft) {
...
nextSection = function (options) { var ref; this.emit('sectionEnd', options, this); if (++this.column > this.columns) { if (this.height != null) { return false; } this.document.addPage(); this.column = 1; this.startY = this.document.page.margins.top; this.maxY = this.document.page.maxY(); this.document.x = this.startX; if (this.document._fillColor) { (ref = this.document).fillColor.apply(ref, this.document._fillColor); } this.emit('pageBreak', options, this); } else { this.document.x += this.lineWidth + this.columnGap; this.document.y = this.startY; this.emit('columnBreak', options, this); } this.emit('sectionStart', options, this); return true; }
...
this.wordSpacing = options.wordSpacing;
}
if (options.ellipsis != null) {
this.ellipsis = options.ellipsis;
}
nextY = this.document.y + this.document.currentLineHeight(true);
if (this.document.y > this.maxY || nextY > this.maxY) {
this.nextSection();
}
buffer = '';
textWidth = 0;
wc = 0;
lc = 0;
y = this.document.y;
emitLine = (function(_this) {
...
wordWidth = function (word) { return this.document.widthOfString(word, this) + this.characterSpacing + this.wordSpacing; }
...
LineWrapper.prototype.eachWord = function(text, fn) {
var bk, breaker, fbk, l, last, lbk, shouldContinue, w, word, wordWidths;
breaker = new LineBreaker(text);
last = null;
wordWidths = Object.create(null);
while (bk = breaker.nextBreak()) {
word = text.slice((last != null ? last.position : void 0) || 0, bk.position);
w = wordWidths[word] != null ? wordWidths[word] : wordWidths[word] = this.wordWidth(
word);
if (w > this.lineWidth + this.continuedX) {
lbk = last;
fbk = {};
while (word.length) {
l = word.length;
while (w > this.spaceLeft) {
w = this.wordWidth(word.slice(0, --l));
...
wrap = function (text, options) { var buffer, emitLine, lc, nextY, textWidth, wc, y; if (options.indent != null) { this.indent = options.indent; } if (options.characterSpacing != null) { this.characterSpacing = options.characterSpacing; } if (options.wordSpacing != null) { this.wordSpacing = options.wordSpacing; } if (options.ellipsis != null) { this.ellipsis = options.ellipsis; } nextY = this.document.y + this.document.currentLineHeight(true); if (this.document.y > this.maxY || nextY > this.maxY) { this.nextSection(); } buffer = ''; textWidth = 0; wc = 0; lc = 0; y = this.document.y; emitLine = (function(_this) { return function() { options.textWidth = textWidth + _this.wordSpacing * (wc - 1); options.wordCount = wc; options.lineWidth = _this.lineWidth; y = _this.document.y; _this.emit('line', buffer, options, _this); return lc++; }; })(this); this.emit('sectionStart', options, this); this.eachWord(text, (function(_this) { return function(word, w, bk, last) { var lh, shouldContinue; if ((last == null) || last.required) { _this.emit('firstLine', options, _this); _this.spaceLeft = _this.lineWidth; } if (w <= _this.spaceLeft) { buffer += word; textWidth += w; wc++; } if (bk.required || w > _this.spaceLeft) { if (bk.required) { _this.emit('lastLine', options, _this); } lh = _this.document.currentLineHeight(true); if ((_this.height != null) && _this.ellipsis && _this.document.y + lh * 2 > _this.maxY && _this.column >= _this.columns) { if (_this.ellipsis === true) { _this.ellipsis = '…'; } buffer = buffer.replace(/\s+$/, ''); textWidth = _this.wordWidth(buffer + _this.ellipsis); while (textWidth > _this.lineWidth) { buffer = buffer.slice(0, -1).replace(/\s+$/, ''); textWidth = _this.wordWidth(buffer + _this.ellipsis); } buffer = buffer + _this.ellipsis; } emitLine(); if (_this.document.y + lh > _this.maxY) { shouldContinue = _this.nextSection(); if (!shouldContinue) { wc = 0; buffer = ''; return false; } } if (bk.required) { if (w > _this.spaceLeft) { buffer = word; textWidth = w; wc = 1; emitLine(); } _this.spaceLeft = _this.lineWidth; buffer = ''; textWidth = 0; return wc = 0; } else { _this.spaceLeft = _this.lineWidth - w; buffer = word; textWidth = w; return wc = 1; } } else { return _this.spaceLeft -= w; } }; })(this)); if (wc > 0) { this.emit('lastLine', options, this); emitLine(); } this.emit('sectionEnd', options, this); if (options.continued === true) { if (lc > 1) { this.continuedX = 0; } this.continuedX += options.textWidth; return this.document.y = y; } else { return this.document.x = this.startX; } }
n/a
function PDFObject() {}
n/a
convert = function (object) { var e, i, isUnicode, items, j, key, out, ref, string, val; if (typeof object === 'string') { return '/' + object; } else if (object instanceof String) { string = object.replace(escapableRe, function(c) { return escapable[c]; }); isUnicode = false; for (i = j = 0, ref = string.length; j < ref; i = j += 1) { if (string.charCodeAt(i) > 0x7f) { isUnicode = true; break; } } if (isUnicode) { string = swapBytes(new Buffer('\ufeff' + string, 'utf16le')).toString('binary'); } return '(' + string + ')'; } else if (Buffer.isBuffer(object)) { return '<' + object.toString('hex') + '>'; } else if (object instanceof PDFReference) { return object.toString(); } else if (object instanceof Date) { return '(D:' + pad(object.getUTCFullYear(), 4) + pad(object.getUTCMonth() + 1, 2) + pad(object.getUTCDate(), 2) + pad(object .getUTCHours(), 2) + pad(object.getUTCMinutes(), 2) + pad(object.getUTCSeconds(), 2) + 'Z)'; } else if (Array.isArray(object)) { items = ((function() { var k, len, results; results = []; for (k = 0, len = object.length; k < len; k++) { e = object[k]; results.push(PDFObject.convert(e)); } return results; })()).join(' '); return '[' + items + ']'; } else if ({}.toString.call(object) === '[object Object]') { out = ['<<']; for (key in object) { val = object[key]; out.push('/' + key + ' ' + PDFObject.convert(val)); } out.push('>>'); return out.join('\n'); } else { return '' + object; } }
...
return '(D:' + pad(object.getUTCFullYear(), 4) + pad(object.getUTCMonth() + 1, 2) + pad(object.getUTCDate(), 2) + pad
(object.getUTCHours(), 2) + pad(object.getUTCMinutes(), 2) + pad(object.getUTCSeconds(), 2) + 'Z)';
} else if (Array.isArray(object)) {
items = ((function() {
var k, len, results;
results = [];
for (k = 0, len = object.length; k < len; k++) {
e = object[k];
results.push(PDFObject.convert(e));
}
return results;
})()).join(' ');
return '[' + items + ']';
} else if ({}.toString.call(object) === '[object Object]') {
out = ['<<'];
for (key in object) {
...
function PDFPage(document, options) { var dimensions; this.document = document; if (options == null) { options = {}; } this.size = options.size || 'letter'; this.layout = options.layout || 'portrait'; if (typeof options.margin === 'number') { this.margins = { top: options.margin, left: options.margin, bottom: options.margin, right: options.margin }; } else { this.margins = options.margins || DEFAULT_MARGINS; } dimensions = Array.isArray(this.size) ? this.size : SIZES[this.size.toUpperCase()]; this.width = dimensions[this.layout === 'portrait' ? 0 : 1]; this.height = dimensions[this.layout === 'portrait' ? 1 : 0]; this.content = this.document.ref(); this.resources = this.document.ref({ ProcSet: ['PDF', 'Text', 'ImageB', 'ImageC', 'ImageI'] }); Object.defineProperties(this, { fonts: { get: (function(_this) { return function() { var base; return (base = _this.resources.data).Font != null ? base.Font : base.Font = {}; }; })(this) }, xobjects: { get: (function(_this) { return function() { var base; return (base = _this.resources.data).XObject != null ? base.XObject : base.XObject = {}; }; })(this) }, ext_gstates: { get: (function(_this) { return function() { var base; return (base = _this.resources.data).ExtGState != null ? base.ExtGState : base.ExtGState = {}; }; })(this) }, patterns: { get: (function(_this) { return function() { var base; return (base = _this.resources.data).Pattern != null ? base.Pattern : base.Pattern = {}; }; })(this) }, annotations: { get: (function(_this) { return function() { var base; return (base = _this.dictionary.data).Annots != null ? base.Annots : base.Annots = []; }; })(this) } }); this.dictionary = this.document.ref({ Type: 'Page', Parent: this.document._root.data.Pages, MediaBox: [0, 0, this.width, this.height], Contents: this.content, Resources: this.resources }); }
n/a
end = function () { this.dictionary.end(); this.resources.end(); return this.content.end(); }
...
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/')
# 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
[PDFKit programming guide](http://pdfkit.org/docs/getting_started.html).
## Browser Usage
...
maxY = function () { return this.height - this.margins.bottom; }
...
this.ellipsis = options.ellipsis;
this.continuedX = 0;
this.features = options.features;
if (options.height != null) {
this.height = options.height;
this.maxY = this.startY + options.height;
} else {
this.maxY = this.document.page.maxY();
}
this.on('firstLine', (function(_this) {
return function(options) {
var indent;
indent = _this.continuedX || _this.indent;
_this.document.x += indent;
_this.lineWidth -= indent;
...
write = function (chunk) { return this.content.write(chunk); }
...
}
PDFPage.prototype.maxY = function() {
return this.height - this.margins.bottom;
};
PDFPage.prototype.write = function(chunk) {
return this.content.write(chunk);
};
PDFPage.prototype.end = function() {
this.dictionary.end();
this.resources.end();
return this.content.end();
};
...
function SVGPath() {}
...
.lineTo(100, 250)
.lineTo(200, 250)
.fill("#FF3300")
# 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()
# Add some text with annotations
doc.addPage()
.fillColor("blue")
.text('Here is a link!', 100, 100)
...
apply = function (doc, path) { var commands; commands = parse(path); return apply(commands, doc); }
...
function PDFLinearGradient(doc, x1, y1, x2, y2) {
this.doc = doc;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
PDFLinearGradient.__super__.constructor.apply(this, arguments);
}
PDFLinearGradient.prototype.shader = function(fn) {
return this.doc.ref({
ShadingType: 2,
ColorSpace: this._colorSpace,
Coords: [this.x1, this.y1, this.x2, this.y2],
...
function PDFReference(document, id, data) { this.document = document; this.id = id; this.data = data != null ? data : {}; this.finalize = bind(this.finalize, this); PDFReference.__super__.constructor.call(this, { decodeStrings: false }); this.gen = 0; this.deflate = null; this.compress = this.document.compress && !this.data.Filter; this.uncompressedLength = 0; this.chunks = []; }
n/a
function WritableState(options, stream) { options = options || {}; // object stream flag to indicate whether or not this stream // contains buffers or objects. this.objectMode = !!options.objectMode; if (stream instanceof Stream.Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; // the point at which write() starts returning false // Note: 0 is a valid value, means that we always return false if // the entire buffer is not flushed immediately on write() var hwm = options.highWaterMark; var defaultHwm = this.objectMode ? 16 : 16 * 1024; this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; // cast to ints. this.highWaterMark = ~~this.highWaterMark; // drain event flag. this.needDrain = false; // at the start of calling end() this.ending = false; // when end() has been called, and returned this.ended = false; // when 'finish' is emitted this.finished = false; // should we decode strings into buffers before passing to _write? // this is here so that some node-core streams can optimize string // handling at a lower level. var noDecode = options.decodeStrings === false; this.decodeStrings = !noDecode; // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. // Everything else in the universe uses 'utf8', though. this.defaultEncoding = options.defaultEncoding || 'utf8'; // not an actual buffer we keep track of, but a measurement // of how much we're waiting to get pushed to some underlying // socket or file. this.length = 0; // a flag to see when we're in the middle of a write. this.writing = false; // when true all writes will be buffered until .uncork() call this.corked = 0; // a flag to be able to tell if the onwrite cb is called immediately, // or on a later tick. We set this to true at first, because any // actions that shouldn't happen until "later" should generally also // not happen before the first write call. this.sync = true; // a flag to know if we're processing previously buffered items, which // may call the _write() callback in the same tick, so that we don't // end up in an overlapped onwrite situation. this.bufferProcessing = false; // the callback that's passed to _write(chunk,cb) this.onwrite = function(er) { onwrite(stream, er); }; // the callback that the user supplies to write(chunk,encoding,cb) this.writecb = null; // the amount that is being written when _write is called. this.writelen = 0; this.bufferedRequest = null; this.lastBufferedRequest = null; // number of pending user-supplied write callbacks // this must be 0 before 'finish' can be emitted this.pendingcb = 0; // emit prefinish if the only thing we're waiting for is _write cbs // This is relevant for synchronous Transform streams this.prefinished = false; // True if the error was already emitted and should not be thrown again this.errorEmitted = false; // count buffered requests this.bufferedRequestCount = 0; // allocate the first CorkedRequest, there is always // one allocated and free to use, and we maintain at most two this.corkedRequestsFree = new CorkedRequest(this); }
n/a
function Stream() { EE.call(this); }
n/a
_write = function (chunk, encoding, callback) { var base; if (!Buffer.isBuffer(chunk)) { chunk = new Buffer(chunk + '\n', 'binary'); } this.uncompressedLength += chunk.length; if ((base = this.data).Length == null) { base.Length = 0; } if (this.compress) { if (!this.deflate) { this.initDeflate(); } this.deflate.write(chunk); } else { this.chunks.push(chunk); this.data.Length += chunk.length; } return callback(); }
...
return this.finalize();
}
};
PDFReference.prototype.finalize = function() {
var chunk, i, len, ref;
this.offset = this.document._offset;
this.document._write(this.id + " " + this.gen + " obj");
this.document._write(PDFObject.convert(this.data));
if (this.chunks.length) {
this.document._write('stream');
ref = this.chunks;
for (i = 0, len = ref.length; i < len; i++) {
chunk = ref[i];
this.document._write(chunk);
...
function PDFReference(document, id, data) { this.document = document; this.id = id; this.data = data != null ? data : {}; this.finalize = bind(this.finalize, this); PDFReference.__super__.constructor.call(this, { decodeStrings: false }); this.gen = 0; this.deflate = null; this.compress = this.document.compress && !this.data.Filter; this.uncompressedLength = 0; this.chunks = []; }
n/a
end = function (chunk) { PDFReference.__super__.end.apply(this, arguments); if (this.deflate) { return this.deflate.end(); } else { return this.finalize(); } }
...
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/')
# 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
[PDFKit programming guide](http://pdfkit.org/docs/getting_started.html).
## Browser Usage
...
finalize = function () { var chunk, i, len, ref; this.offset = this.document._offset; this.document._write(this.id + " " + this.gen + " obj"); this.document._write(PDFObject.convert(this.data)); if (this.chunks.length) { this.document._write('stream'); ref = this.chunks; for (i = 0, len = ref.length; i < len; i++) { chunk = ref[i]; this.document._write(chunk); } this.chunks.length = 0; this.document._write('\nendstream'); } this.document._write('endobj'); return this.document._refEnd(this); }
...
};
PDFReference.prototype.end = function(chunk) {
PDFReference.__super__.end.apply(this, arguments);
if (this.deflate) {
return this.deflate.end();
} else {
return this.finalize();
}
};
PDFReference.prototype.finalize = function() {
var chunk, i, len, ref;
this.offset = this.document._offset;
this.document._write(this.id + " " + this.gen + " obj");
...
initDeflate = function () { this.data.Filter = 'FlateDecode'; this.deflate = zlib.createDeflate(); this.deflate.on('data', (function(_this) { return function(chunk) { _this.chunks.push(chunk); return _this.data.Length += chunk.length; }; })(this)); return this.deflate.on('end', this.finalize); }
...
}
this.uncompressedLength += chunk.length;
if ((base = this.data).Length == null) {
base.Length = 0;
}
if (this.compress) {
if (!this.deflate) {
this.initDeflate();
}
this.deflate.write(chunk);
} else {
this.chunks.push(chunk);
this.data.Length += chunk.length;
}
return callback();
...
toString = function () { return this.id + " " + this.gen + " R"; }
...
if (!data) {
return;
}
}
}
if (data[0] === 0xff && data[1] === 0xd8) {
return new JPEG(data, label);
} else if (data[0] === 0x89 && data.toString('ascii', 1, 4) ===
x27;PNG') {
return new PNG(data, label);
} else {
throw new Error('Unknown image format.');
}
};
return PDFImage;
...