deflation seems to work
parent
c44aafe1e5
commit
fb613bb70e
@ -1,247 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.5
|
||||
|
||||
/*
|
||||
PDFDocument - represents an entire PDF document
|
||||
By Devon Govett
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var PDFDocument, PDFObject, PDFPage, PDFReference, fs, stream,
|
||||
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||||
hasProp = {}.hasOwnProperty;
|
||||
|
||||
stream = require('stream');
|
||||
|
||||
fs = require('fs');
|
||||
|
||||
PDFObject = require('./object');
|
||||
|
||||
PDFReference = require('./reference');
|
||||
|
||||
PDFPage = require('./page');
|
||||
|
||||
PDFDocument = (function(superClass) {
|
||||
var mixin;
|
||||
|
||||
extend(PDFDocument, superClass);
|
||||
|
||||
function PDFDocument(options1) {
|
||||
var key, ref1, ref2, val;
|
||||
this.options = options1 != null ? options1 : {};
|
||||
PDFDocument.__super__.constructor.apply(this, arguments);
|
||||
this.version = 1.3;
|
||||
this.compress = (ref1 = this.options.compress) != null ? ref1 : true;
|
||||
this._pageBuffer = [];
|
||||
this._pageBufferStart = 0;
|
||||
this._offsets = [];
|
||||
this._waiting = 0;
|
||||
this._ended = false;
|
||||
this._offset = 0;
|
||||
this._root = this.ref({
|
||||
Type: 'Catalog',
|
||||
Pages: this.ref({
|
||||
Type: 'Pages',
|
||||
Count: 0,
|
||||
Kids: []
|
||||
})
|
||||
});
|
||||
this.page = null;
|
||||
this.initColor();
|
||||
this.initVector();
|
||||
this.initFonts();
|
||||
this.initText();
|
||||
this.initImages();
|
||||
this.info = {
|
||||
Producer: 'PDFKit',
|
||||
Creator: 'PDFKit',
|
||||
CreationDate: new Date()
|
||||
};
|
||||
if (this.options.info) {
|
||||
ref2 = this.options.info;
|
||||
for (key in ref2) {
|
||||
val = ref2[key];
|
||||
this.info[key] = val;
|
||||
}
|
||||
}
|
||||
this._write("%PDF-" + this.version);
|
||||
this._write("%\xFF\xFF\xFF\xFF");
|
||||
if (this.options.autoFirstPage !== false) {
|
||||
this.addPage();
|
||||
}
|
||||
}
|
||||
|
||||
mixin = function(methods) {
|
||||
var method, name, results;
|
||||
results = [];
|
||||
for (name in methods) {
|
||||
method = methods[name];
|
||||
results.push(PDFDocument.prototype[name] = method);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
mixin(require('./mixins/color'));
|
||||
|
||||
mixin(require('./mixins/vector'));
|
||||
|
||||
mixin(require('./mixins/fonts'));
|
||||
|
||||
mixin(require('./mixins/text'));
|
||||
|
||||
mixin(require('./mixins/images'));
|
||||
|
||||
mixin(require('./mixins/annotations'));
|
||||
|
||||
PDFDocument.prototype.addPage = function(options) {
|
||||
var pages;
|
||||
if (options == null) {
|
||||
options = this.options;
|
||||
}
|
||||
if (!this.options.bufferPages) {
|
||||
this.flushPages();
|
||||
}
|
||||
this.page = new PDFPage(this, options);
|
||||
this._pageBuffer.push(this.page);
|
||||
pages = this._root.data.Pages.data;
|
||||
pages.Kids.push(this.page.dictionary);
|
||||
pages.Count++;
|
||||
this.x = this.page.margins.left;
|
||||
this.y = this.page.margins.top;
|
||||
this._ctm = [1, 0, 0, 1, 0, 0];
|
||||
this.transform(1, 0, 0, -1, 0, this.page.height);
|
||||
this.emit('pageAdded');
|
||||
return this;
|
||||
};
|
||||
|
||||
PDFDocument.prototype.bufferedPageRange = function() {
|
||||
return {
|
||||
start: this._pageBufferStart,
|
||||
count: this._pageBuffer.length
|
||||
};
|
||||
};
|
||||
|
||||
PDFDocument.prototype.switchToPage = function(n) {
|
||||
var page;
|
||||
if (!(page = this._pageBuffer[n - this._pageBufferStart])) {
|
||||
throw new Error("switchToPage(" + n + ") out of bounds, current buffer covers pages " + this._pageBufferStart + " to " + (this._pageBufferStart + this._pageBuffer.length - 1));
|
||||
}
|
||||
return this.page = page;
|
||||
};
|
||||
|
||||
PDFDocument.prototype.flushPages = function() {
|
||||
var i, len, page, pages;
|
||||
pages = this._pageBuffer;
|
||||
this._pageBuffer = [];
|
||||
this._pageBufferStart += pages.length;
|
||||
for (i = 0, len = pages.length; i < len; i++) {
|
||||
page = pages[i];
|
||||
page.end();
|
||||
}
|
||||
};
|
||||
|
||||
PDFDocument.prototype.ref = function(data) {
|
||||
var ref;
|
||||
ref = new PDFReference(this, this._offsets.length + 1, data);
|
||||
this._offsets.push(null);
|
||||
this._waiting++;
|
||||
return ref;
|
||||
};
|
||||
|
||||
PDFDocument.prototype._read = function() {};
|
||||
|
||||
PDFDocument.prototype._write = function(data) {
|
||||
if (!Buffer.isBuffer(data)) {
|
||||
data = new Buffer(data + '\n', 'binary');
|
||||
}
|
||||
this.push(data);
|
||||
return this._offset += data.length;
|
||||
};
|
||||
|
||||
PDFDocument.prototype.addContent = function(data) {
|
||||
this.page.write(data);
|
||||
return this;
|
||||
};
|
||||
|
||||
PDFDocument.prototype._refEnd = function(ref) {
|
||||
this._offsets[ref.id - 1] = ref.offset;
|
||||
if (--this._waiting === 0 && this._ended) {
|
||||
this._finalize();
|
||||
return this._ended = false;
|
||||
}
|
||||
};
|
||||
|
||||
PDFDocument.prototype.write = function(filename, fn) {
|
||||
var err;
|
||||
err = new Error('PDFDocument#write is deprecated, and will be removed in a future version of PDFKit. Please pipe the document into a Node stream.');
|
||||
console.warn(err.stack);
|
||||
this.pipe(fs.createWriteStream(filename));
|
||||
this.end();
|
||||
return this.once('end', fn);
|
||||
};
|
||||
|
||||
PDFDocument.prototype.output = function(fn) {
|
||||
throw new Error('PDFDocument#output is deprecated, and has been removed from PDFKit. Please pipe the document into a Node stream.');
|
||||
};
|
||||
|
||||
PDFDocument.prototype.end = function() {
|
||||
var font, key, name, ref1, ref2, val;
|
||||
this.flushPages();
|
||||
this._info = this.ref();
|
||||
ref1 = this.info;
|
||||
for (key in ref1) {
|
||||
val = ref1[key];
|
||||
if (typeof val === 'string') {
|
||||
val = new String(val);
|
||||
}
|
||||
this._info.data[key] = val;
|
||||
}
|
||||
this._info.end();
|
||||
ref2 = this._fontFamilies;
|
||||
for (name in ref2) {
|
||||
font = ref2[name];
|
||||
font.finalize();
|
||||
}
|
||||
this._root.end();
|
||||
this._root.data.Pages.end();
|
||||
if (this._waiting === 0) {
|
||||
return this._finalize();
|
||||
} else {
|
||||
return this._ended = true;
|
||||
}
|
||||
};
|
||||
|
||||
PDFDocument.prototype._finalize = function(fn) {
|
||||
var i, len, offset, ref1, xRefOffset;
|
||||
xRefOffset = this._offset;
|
||||
this._write("xref");
|
||||
this._write("0 " + (this._offsets.length + 1));
|
||||
this._write("0000000000 65535 f ");
|
||||
ref1 = this._offsets;
|
||||
for (i = 0, len = ref1.length; i < len; i++) {
|
||||
offset = ref1[i];
|
||||
offset = ('0000000000' + offset).slice(-10);
|
||||
this._write(offset + ' 00000 n ');
|
||||
}
|
||||
this._write('trailer');
|
||||
this._write(PDFObject.convert({
|
||||
Size: this._offsets.length + 1,
|
||||
Root: this._root,
|
||||
Info: this._info
|
||||
}));
|
||||
this._write('startxref');
|
||||
this._write("" + xRefOffset);
|
||||
this._write('%%EOF');
|
||||
return this.push(null);
|
||||
};
|
||||
|
||||
PDFDocument.prototype.toString = function() {
|
||||
return "[object PDFDocument]";
|
||||
};
|
||||
|
||||
return PDFDocument;
|
||||
|
||||
})(stream.Readable);
|
||||
|
||||
module.exports = PDFDocument;
|
||||
|
||||
}).call(this);
|
@ -1,117 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.5
|
||||
|
||||
/*
|
||||
PDFReference - represents a reference to another object in the PDF object heirarchy
|
||||
By Devon Govett
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var PDFObject, PDFReference, stream, zlib,
|
||||
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
||||
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||||
hasProp = {}.hasOwnProperty;
|
||||
|
||||
zlib = require('zlib');
|
||||
|
||||
stream = require('stream');
|
||||
|
||||
PDFReference = (function(superClass) {
|
||||
extend(PDFReference, superClass);
|
||||
|
||||
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 = false;
|
||||
this.uncompressedLength = 0;
|
||||
this.chunks = [];
|
||||
}
|
||||
|
||||
PDFReference.prototype.initDeflate = function() {
|
||||
this.data.Filter = 'FlateDecode';
|
||||
this.deflate = zlib.createDeflate();
|
||||
this.deflate.on('data', (function(_this) {
|
||||
return function(chunk) {
|
||||
console.log("got data event for ref " + _this.id + " from " + _this.toString());
|
||||
_this.chunks.push(chunk);
|
||||
return _this.data.Length += chunk.length;
|
||||
};
|
||||
})(this));
|
||||
return this.deflate.on('end', (function(_this) {
|
||||
return function() {
|
||||
console.log("got end event for ref " + _this.id + " from " + _this.toString());
|
||||
return _this.finalize();
|
||||
};
|
||||
})(this));
|
||||
};
|
||||
|
||||
PDFReference.prototype._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();
|
||||
}
|
||||
console.log("chunk = " + chunk);
|
||||
this.deflate.write(chunk);
|
||||
console.log("wrote chunk");
|
||||
} else {
|
||||
this.chunks.push(chunk);
|
||||
this.data.Length += chunk.length;
|
||||
}
|
||||
return callback();
|
||||
};
|
||||
|
||||
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");
|
||||
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.toString = function() {
|
||||
return this.id + " " + this.gen + " R";
|
||||
};
|
||||
|
||||
return PDFReference;
|
||||
|
||||
})(stream.Writable);
|
||||
|
||||
module.exports = PDFReference;
|
||||
|
||||
PDFObject = require('./object');
|
||||
|
||||
}).call(this);
|
@ -1,4 +1,3 @@
|
||||
#lang racket/base
|
||||
(provide (all-defined-out))
|
||||
(define test-mode (make-parameter #f))
|
||||
(define compression-enabled (make-parameter #f))
|
||||
(define test-mode (make-parameter #f))
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,10 @@
|
||||
PDFDocument = require 'pdfkit'
|
||||
fs = require 'fs'
|
||||
|
||||
# Create a new PDFDocument
|
||||
# uncompressed obj order: 5 4 3 6 2 1
|
||||
# compressed obj order: 5 4 6 2 1 3
|
||||
doc = new PDFDocument({compress: yes})
|
||||
doc.pipe(fs.createWriteStream('test0c.pdf'))
|
||||
|
||||
doc.end()
|
Binary file not shown.
@ -0,0 +1,10 @@
|
||||
#lang pitfall/pdftest
|
||||
(define-runtime-path this "test0crkt.pdf")
|
||||
|
||||
(check-true
|
||||
(let ()
|
||||
(define doc (make-object PDFDocument (hash 'compress #t)))
|
||||
(send doc pipe (open-output-file this #:exists 'replace))
|
||||
(send doc end)))
|
||||
|
||||
(check-copy-equal? this)
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,18 @@
|
||||
PDFDocument = require 'pdfkit'
|
||||
fs = require 'fs'
|
||||
|
||||
# Create a new PDFDocument
|
||||
doc = new PDFDocument({compress: no})
|
||||
doc.pipe(fs.createWriteStream('test1c.pdf'))
|
||||
|
||||
# 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.end()
|
@ -0,0 +1,22 @@
|
||||
#lang pitfall/pdftest
|
||||
(define-runtime-path this "test1crkt.pdf")
|
||||
|
||||
(check-true
|
||||
(let ([doc (make-object PDFDocument (hash 'compress #t))])
|
||||
(send doc pipe (open-output-file this #:exists 'replace))
|
||||
|
||||
;; Draw a triangle and a circle
|
||||
(send* doc
|
||||
[save]
|
||||
[moveTo 100 150]
|
||||
[lineTo 100 250]
|
||||
[lineTo 200 250]
|
||||
[fill "#FF3300"])
|
||||
|
||||
(send* doc
|
||||
[circle 280 200 50]
|
||||
[fill "#6600FF"])
|
||||
|
||||
(send doc end)))
|
||||
|
||||
(check-copy-equal? this)
|
@ -0,0 +1,77 @@
|
||||
#lang pitfall/pdftest
|
||||
(define-runtime-path this "test2crkt.pdf")
|
||||
|
||||
(check-true
|
||||
(let ([doc (make-object PDFDocument (hash 'compress #t))])
|
||||
(send doc pipe (open-output-file this #:exists 'replace))
|
||||
|
||||
;; curved path as bezier
|
||||
(send* doc
|
||||
[moveTo 0 20]
|
||||
[lineTo 100 160]
|
||||
[quadraticCurveTo 130 200 150 120]
|
||||
[bezierCurveTo 190 -40 200 200 300 150]
|
||||
[lineTo 400 90]
|
||||
[stroke])
|
||||
|
||||
(send* doc [translate 0 200])
|
||||
|
||||
;; triangle
|
||||
(send* doc
|
||||
[polygon '(100 0) '(50 100) '(150 100)]
|
||||
[stroke])
|
||||
|
||||
;; dashed circle
|
||||
(send* doc
|
||||
[save]
|
||||
[translate 200 0]
|
||||
[circle 100 50 50]
|
||||
[dash 5 (hash 'space 10)]
|
||||
[stroke]
|
||||
[restore])
|
||||
|
||||
;; filled circle
|
||||
(send* doc
|
||||
[save]
|
||||
[translate 400 0]
|
||||
[circle 100 50 50]
|
||||
[lineWidth 3]
|
||||
[fillOpacity 0.8]
|
||||
[fillAndStroke "red" "#900"]
|
||||
[restore])
|
||||
|
||||
(send* doc [translate 0 200])
|
||||
|
||||
;; these examples are easier to see with a large line width
|
||||
(send* doc [lineWidth 25])
|
||||
|
||||
;; line cap settings
|
||||
(send* doc [lineCap 'butt]
|
||||
[moveTo 50 20]
|
||||
[lineTo 100 20]
|
||||
[stroke]
|
||||
[lineCap 'round]
|
||||
[moveTo 150 20]
|
||||
[lineTo 200 20]
|
||||
[stroke])
|
||||
|
||||
;; square line cap shown with a circle instead of a line so you can see it
|
||||
(send* doc [lineCap 'square]
|
||||
[moveTo 250 20]
|
||||
[circle 275 30 15]
|
||||
[stroke])
|
||||
|
||||
;; line join settings
|
||||
(send* doc [lineJoin 'miter]
|
||||
[rect 50 100 50 50]
|
||||
[stroke]
|
||||
[lineJoin 'round]
|
||||
[rect 150 100 50 50]
|
||||
[stroke]
|
||||
[lineJoin 'bevel]
|
||||
[rect 250 100 50 50]
|
||||
[stroke])
|
||||
|
||||
(send doc end)))
|
||||
|
||||
(check-copy-equal? this)
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,10 @@
|
||||
#lang pitfall/pdftest
|
||||
(define-runtime-path this "test3crkt.pdf")
|
||||
|
||||
(check-true
|
||||
(let ([doc (make-object PDFDocument (hash 'compress #t))])
|
||||
(send doc pipe (open-output-file this #:exists 'replace))
|
||||
(send doc text "Hello world")
|
||||
(send doc end)))
|
||||
|
||||
(check-copy-equal? this)
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,68 @@
|
||||
#lang pitfall/pdftest
|
||||
(define-runtime-path this "test4crkt.pdf")
|
||||
|
||||
(check-true
|
||||
(let ([doc (make-object PDFDocument (hash 'compress #t))])
|
||||
(send doc pipe (open-output-file this #:exists 'replace))
|
||||
|
||||
(send* doc
|
||||
[font "Courier-Bold"]
|
||||
[fontSize 10]
|
||||
[text "Hello"]
|
||||
[translate -30 30]
|
||||
[font "Courier-BoldOblique"]
|
||||
[fontSize 11]
|
||||
[text "Hello"]
|
||||
[translate -30 30]
|
||||
[font "Courier-Oblique"]
|
||||
[fontSize 12]
|
||||
[text "Hello"]
|
||||
[translate -30 30]
|
||||
[font "Courier"]
|
||||
[fontSize 14]
|
||||
[text "Hello"]
|
||||
[translate -30 30]
|
||||
[font "Helvetica-Bold"]
|
||||
[fontSize 16]
|
||||
[text "Hello"]
|
||||
[translate -30 30]
|
||||
[font "Helvetica-BoldOblique"]
|
||||
[fontSize 18]
|
||||
[text "Hello"]
|
||||
[translate -30 30]
|
||||
[font "Helvetica-Oblique"]
|
||||
[fontSize 20]
|
||||
[text "Hello"]
|
||||
[translate -30 30]
|
||||
[font "Helvetica"]
|
||||
[fontSize 22]
|
||||
[text "Hello"]
|
||||
[translate -30 30]
|
||||
[font "Symbol"]
|
||||
[fontSize 24]
|
||||
[text "Hello"]
|
||||
[translate -30 30]
|
||||
[font "Times-Bold"]
|
||||
[fontSize 26]
|
||||
[text "Hello"]
|
||||
[translate -30 30]
|
||||
[font "Times-BoldItalic"]
|
||||
[fontSize 28]
|
||||
[text "Hello"]
|
||||
[translate -30 30]
|
||||
[font "Times-Italic"]
|
||||
[fontSize 30]
|
||||
[text "Hello"]
|
||||
[translate -30 30]
|
||||
[font "Times-Roman"]
|
||||
[fontSize 32]
|
||||
[text "Hello"]
|
||||
[translate -30 30]
|
||||
[font "ZapfDingbats"]
|
||||
[fontSize 34]
|
||||
[text "Hello"])
|
||||
|
||||
|
||||
(send doc end)))
|
||||
|
||||
(check-copy-equal? this)
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,20 @@
|
||||
#lang pitfall/pdftest
|
||||
(define-runtime-path this "test5crkt.pdf")
|
||||
|
||||
(check-true
|
||||
(let ([doc (make-object PDFDocument (hash 'compress #t))])
|
||||
(send doc pipe (open-output-file this #:exists 'replace))
|
||||
|
||||
;; # Set the font, draw some text, and embed an image
|
||||
(send* doc
|
||||
[font "Times-Italic"]
|
||||
[fontSize 25]
|
||||
[text "Some text with an embedded font!" 100 100 (hash 'lineBreak #f)]
|
||||
[image "assets/test.png" 100 160 (hash 'width 412)]
|
||||
[image "assets/test.jpeg" 190 400 (hash 'height 300)]
|
||||
)
|
||||
|
||||
|
||||
(send doc end)))
|
||||
|
||||
;(check-copy-equal? this)
|
Loading…
Reference in New Issue