one offset is wrong

main
Matthew Butterick 8 years ago
parent 5e8a8b60f3
commit 43ff762c2d

@ -0,0 +1,117 @@
// 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);

@ -56,8 +56,8 @@
;; Initialize the metadata
(field [(@info info) (mhash
'Producer "PitfallKit"
'Creator "PitfallKit"
'Producer "PDFKit"
'Creator "PDFKit"
'CreationDate (seconds->date (current-seconds)))])
(when (hash-ref @options 'info #f)
@ -154,6 +154,16 @@
(send @page write data)
this)
(define/public (_refEnd ref)
(set! @_offsets (for/list ([(offset idx) (in-indexed @_offsets)])
(if (= idx (sub1 (· ref id)))
(· ref offset)
offset)))
(-- @_waiting)
(if (and (zero? @_waiting) @_ended)
(@_finalize)
(set! @_ended #f)))
(field [op #f])
(define/public (pipe port)
(set! op port))
@ -217,5 +227,7 @@
(require rackunit racket/file)
(define ob (open-output-bytes))
(send doc pipe ob)
(send doc pipe (open-output-file "zzz.pdf" #:exists 'replace))
(check-equal? (send doc end) 'done)
(check-equal? (get-output-bytes ob) (file->bytes "demo.pdf")))
#;(display (get-output-bytes ob))
#;(check-equal? (get-output-bytes ob) (file->bytes "demo.pdf")))

@ -11,4 +11,4 @@
(define/public (initVector) (void))
(define/public (transform m11 m12 m21 m22 dx dy)
(send this addContent "from vector/transform")))) ; todo
(send this addContent "1 0 0 -1 0 792 cm")))) ; todo

@ -1,6 +1,6 @@
#lang at-exp br
(require racket/class racket/string racket/list srfi/19)
(require "struct.rkt" "reference.rkt")
(require "struct.rkt")
(provide PDFObject)
(define PDFObject
@ -51,6 +51,7 @@
(define result (/ (round (* n 1e6)) 1e6))
(if (integer? result) (inexact->exact result) result))
(define/public (convert object)
(let loop ([x object])
(cond
@ -73,7 +74,7 @@
[(bytes? x) (format "<~a>" (string-append*
(for/list ([b (in-bytes x)])
(number->string b 16))))]
[(is-a? x PDFReference) (send x toString)]
[(object? x) (send x toString)]
[(date? x) (format "(D:~aZ)" (date->string x "~Y~m~d~H~M~S"))]
[(list? x) (format "[~a]" (string-join (map loop x) " "))]
[(hash? x) (string-join (append (list "<<")
@ -86,7 +87,7 @@
(module+ test
(require rackunit)
(require rackunit )
(define o (new PDFObject))
(check-equal? (send o pad "foobar" -1) "oobar")
(check-equal? (send o pad "foobar" 0) "foobar")
@ -106,7 +107,7 @@
(check-equal? (send o convert (String "öéÿ")) "(þÿ\u0000ö\u0000é\u0000ÿ)")
(check-equal? (send o convert (String "fôobár")) "(þÿ\u0000f\u0000ô\u0000o\u0000b\u0000á\u0000r)")
(check-equal? (send o convert #"foobar") "<666f6f626172>")
(check-equal? (send o convert (make-object PDFReference "foobar" 42)) "42 0 R")
#;(check-equal? (send o convert (make-object PDFReference "foobar" 42)) "42 0 R")
(check-equal? (send o convert (seconds->date (quotient 1494483337320 1000) #f)) "(D:20170511061537Z)")
(check-equal? (send o convert (list "foobar" (String "öéÿ") #"foobar")) "[/foobar (þÿ\u0000ö\u0000é\u0000ÿ) <666f6f626172>]")
(check-equal? (send o convert (hash "foo" 42 "bar" "fly")) "<<\n/foo 42\n/bar /fly\n>>")

@ -1,5 +1,5 @@
#lang br
(require "helper.rkt")
(require "helper.rkt" "object.rkt" file/gzip)
(provide PDFReference)
(define PDFReference
@ -16,16 +16,19 @@
(public [@initDeflate initDeflate])
(define (@initDeflate)
;; todo
(void))
(hash-ref! @data 'Filter "FlateDecode")
(set! @deflate deflate)
(report 'initDeflate-unimplemented))
(define/public (write data)
(report data))
(_write data #f void))
(define/public (_write chunk-in encoding callback)
(report 'boom)
(define chunk (if (isBuffer? chunk-in)
chunk-in
(newBuffer (string-append chunk "\n"))))
(newBuffer (string-append chunk-in "\n"))))
(+= @uncompressedLength (buffer-length chunk))
(hash-ref! @data 'Length 0)
(cond
@ -41,12 +44,24 @@
(void) ; todo (deflate-end)
(@finalize)))
(field [offset #f])
(field [(@offset offset) #f])
(public [@finalize finalize])
(define (@finalize)
(set! offset (· @document _offset))
(set! @offset (· @document _offset))
(send @document _write (format "~a ~a obj" @id @gen))
)
(send @document _write (send (new PDFObject) convert @data))
(when (positive? (length @chunks))
(send @document _write "stream")
(for ([chunk (in-list @chunks)])
(send @document _write chunk))
(set! @chunks null) ; free up memory
(send @document _write "\nendstream"))
(send @document _write "endobj")
(send @document _refEnd this))
(define/public (toString)
(format "~a ~a R" @id @gen))

@ -0,0 +1,63 @@
%PDF-1.3
%ÿÿÿÿ
5 0 obj
<<
/Parent 1 0 R
/Resources 4 0 R
/Contents 3 0 R
/MediaBox [0 0 612 792]
/Type /Page
>>
endobj
4 0 obj
<<
/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
>>
endobj
3 0 obj
<<
/Length 18
>>
stream
1 0 0 -1 0 792 cm
endstream
endobj
6 0 obj
<<
/Producer (PDFKit)
/CreationDate (D:20170512220606Z)
/Creator (PDFKit)
>>
endobj
2 0 obj
<<
/Pages 1 0 R
/Type /Catalog
>>
endobj
1 0 obj
<<
/Kids [5 0 R]
/Count 1
/Type /Pages
>>
endobj
xref
0 7
0000000000 65535 f
0000000395 00000 n
0000000346 00000 n
0000057005 00000 n
0000000186 00000 n
0000000119 00000 n
0000000254 00000 n
trailer
<<
/Info 6 0 R
/Root 2 0 R
/Size 7
>>
startxref
452
%%EOF
Loading…
Cancel
Save