image progress

main
Matthew Butterick 7 years ago
parent e57ad924ca
commit f5e2b33bd8

@ -145,9 +145,11 @@ class PDFDocument extends stream.Readable
return this
_refEnd: (ref) ->
console.log(ref.id)
console.log(@_offsets)
@_offsets[ref.id - 1] = ref.offset
if --@_waiting is 0 and @_ended
@_finalize()
console.log("finalize") ; @_finalize()
@_ended = false
write: (filename, fn) ->
@ -171,26 +173,34 @@ class PDFDocument extends stream.Readable
'
end: ->
console.log("start document end")
console.log(@_offsets)
@flushPages()
@_info = @ref()
for key, val of @info
if typeof val is 'string'
val = new String val
@_info.data[key] = val
console.log(@_offsets)
@_info.end()
for name, font of @_fontFamilies
font.finalize()
console.log(@_offsets)
@_root.end()
console.log(@_offsets)
@_root.data.Pages.end()
console.log(@_offsets)
if @_waiting is 0
@_finalize()
console.log(@_offsets.length)
console.log("finalize2") ; @_finalize()
else
@_ended = true
console.log("ended is true") ; @_ended = true
_finalize: (fn) ->
# generate xref

@ -21,12 +21,12 @@ class PDFReference extends stream.Writable
@deflate = zlib.createDeflate()
@deflate.on 'data', (chunk) =>
console.log("got data event for ref " + @id + " from " + this.toString())
# console.log("got data event for ref " + @id + " from " + this.toString())
@chunks.push chunk
@data.Length += chunk.length
@deflate.on 'end', () =>
console.log("got end event for ref " + @id + " from " + this.toString())
#console.log("got end event for ref " + @id + " from " + this.toString())
@finalize()
_write: (chunk, encoding, callback) ->
@ -49,7 +49,7 @@ class PDFReference extends stream.Writable
super
console.log("end! " + @id)
console.log(@chunks)
# console.log(@chunks)
if @deflate
@deflate.end()
else
@ -58,8 +58,8 @@ class PDFReference extends stream.Writable
finalize: =>
console.log("finalize! " + @id)
console.log(@chunks)
#console.log("finalize! " + @id)
#console.log(@chunks)
@offset = @document._offset
@ -75,6 +75,7 @@ class PDFReference extends stream.Writable
@document._write '\nendstream'
@document._write 'endobj'
console.log(@id)
@document._refEnd(this)
toString: ->

@ -52,7 +52,7 @@
end)
(for ([(key val) (in-hash (hash-ref options 'info (hash)))]) ; if no 'info key, nothing will be copied from (hash)
(hash-set! info key val))
(hash-set! info key val))
;; Write the header
(write this (format "%PDF-~a" pdf-version)) ; PDF version
@ -127,10 +127,8 @@
(define/contract (_refEnd this ref)
((is-a?/c PDFReference) . ->m . void?)
(hash-set! (· this _offsets) (· ref id) (· ref offset))
(if (and (not (offsets-missing? this)) (· this _ended))
(· this _finalize)
(set-field! _ended this #f)))
(report* (· ref id) (· this _offsets))
(hash-set! (· this _offsets) (· ref id) (· ref offset)))
(define/contract (pipe this port)
@ -140,48 +138,54 @@
(define/contract (end this) ; called from source file to finish doc
(->m void?)
(report* 'start-end)
(report* (· this _offsets))
(flushPages this)
(define _info (ref this))
(for ([(key val) (in-hash (· this info))])
;; upgrade string literal to String struct
(hash-set! (· _info payload) key (if (string? val) (String val) val)))
;; upgrade string literal to String struct
(hash-set! (· _info payload) key (if (string? val) (String val) val)))
(report* (· this _offsets))
(· _info end)
(for ([font (in-hash-values (· this _fontFamilies))])
(· font finalize))
(· font finalize))
(report* (· this _offsets))
(· this _root end)
(report* (· this _offsets))
(· this _root payload Pages end)
(cond
[(offsets-missing? this) (set-field! _ended this #t)]
[else
;; generate xref
(define xref-offset (· this _offset))
(with-method ([this-write (this write)])
(define this-offsets (map cdr (sort (hash->list (· this _offsets)) < #:key car))) ; sort by refid
(this-write "xref")
(this-write (format "0 ~a" (add1 (length this-offsets))))
(this-write "0000000000 65535 f ")
(for ([offset (in-list this-offsets)])
(this-write @string-append{@(~r offset #:min-width 10 #:pad-string "0") 00000 n }))
(this-write "trailer") ;; trailer
(this-write (convert
(mhash 'Size (add1 (length this-offsets))
'Root (· this _root)
'Info _info)))
(this-write "startxref")
(this-write (number xref-offset))
(this-write "%%EOF"))
(report* (· this _offsets))
;; generate xref
(define xref-offset (· this _offset))
(with-method ([this-write (this write)])
(define this-offsets (map cdr (sort (hash->list (· this _offsets)) < #:key car))) ; sort by refid
(this-write "xref")
(this-write (format "0 ~a" (add1 (length this-offsets))))
(this-write "0000000000 65535 f ")
(for ([offset (in-list this-offsets)])
(this-write @string-append{@(~r offset #:min-width 10 #:pad-string "0") 00000 n }))
(this-write "trailer") ;; trailer
(this-write (convert
(mhash 'Size (add1 (length this-offsets))
'Root (· this _root)
'Info _info)))
(this-write "startxref")
(this-write (number xref-offset))
(this-write "%%EOF"))
;; end the stream
;; in node you (@push null) which signals to the stream
;; to copy to its output port
;; here we'll do it manually
(define this-output-port (· this output-port))
(copy-port (open-input-bytes
(apply bytes-append (reverse (· this byte-strings)))) this-output-port)
(close-output-port this-output-port)]))
;; end the stream
;; in node you (@push null) which signals to the stream
;; to copy to its output port
;; here we'll do it manually
(define this-output-port (· this output-port))
(copy-port (open-input-bytes
(apply bytes-append (reverse (· this byte-strings)))) this-output-port)
(close-output-port this-output-port))

@ -13,7 +13,8 @@
[document #f]) ; for `embed`
(as-methods
embed))
embed
finalize))
(define png-grayscale 1)
@ -27,7 +28,7 @@
(send (· this document) ref
(mhash 'Type "XObject"
'Subtype "Image"
'BitsPerComponent: (· this image get-depth)
'BitsPerComponent (· this image get-depth)
'Width (· this width)
'Height (· this height)
'Filter "FlateDecode")))
@ -35,9 +36,7 @@
(define params (mhash))
(unless (· this image has-alpha-channel?)
(set! params (send (· this document) ref (mhash 'Predictor 15
'Colors (· this image get-depth)
;; or maybe
#;(if (· this image is-color?)
'Colors (if (· this image is-color?)
png-color
png-grayscale)
'BitsPerComponent (· this image get-depth)
@ -47,8 +46,14 @@
(hash-set! (· this obj payload) 'DecodeParms params)
(send params end)
(send this finalize)
#;(error 'stop-in-png:embed)))
(define (finalize this)
;; add the actual image data
(send (· this obj) end (· this imgData)))
#;(module+ test
(define data (file->bytes "test/assets/test.png"))
(define bm (make-object bitmap% (open-input-bytes data) 'png))

@ -21,13 +21,16 @@
(define got-byte-strings? pair?)
(define/contract (end this)
(->m void?)
(define/contract (end this [chunk #f])
(() ((or/c string? isBuffer?)) . ->*m . void?)
(when chunk
(send this write chunk))
(report* 'end! (· this id))
(define bstrs-to-write
(let ([current-bstrs (reverse (· this byte-strings))])
(if (and (compress-streams?)
(not (hash-ref (· this payload) 'Filter #f))
(if (and (or (compress-streams?)
(equal? (hash-ref (· this payload) 'Filter #f) "FlateDecode"))
(got-byte-strings? current-bstrs))
(let ([deflated-chunk (deflate (apply bytes-append current-bstrs))])
(hash-set! (· this payload) 'Filter "FlateDecode")
@ -49,7 +52,8 @@
(doc_write bstr))
(doc_write "\nendstream"))
(doc_write "endobj"))
(report (· this id))
(send this-doc _refEnd this))

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

@ -6,16 +6,15 @@ make = (doc) ->
doc.font('Times-Italic')
.fontSize(25)
.text('Some text with an embedded font!', 100, 100, lineBreak: no)
.image('assets/test.png', 100, 160, width: 412)
.image('assets/test.jpeg', 190, 400, height: 300)
.image('death.png', 100, 160, width: 412)
doc.end()
doc = new PDFDocument({compress: no})
doc.pipe(fs.createWriteStream('test5.pdf'))
make doc
doc = new PDFDocument({compress: yes})
doc.pipe(fs.createWriteStream('test5c.pdf'))
make doc
#doc = new PDFDocument({compress: yes})
#doc.pipe(fs.createWriteStream('test5c.pdf'))
#make doc

Binary file not shown.

@ -5,7 +5,7 @@
[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 "death.png" 100 160 (hash 'width 412)]
#;[image "assets/test.jpeg" 190 400 (hash 'height 300)]))
(define-runtime-path this "test5rkt.pdf")

Binary file not shown.

Binary file not shown.
Loading…
Cancel
Save