main
Matthew Butterick 6 years ago
parent 7870e8aad3
commit 33f0c6443b

@ -5,6 +5,7 @@
racket/class
racket/format
racket/contract
racket/generator
racket/list
sugar/unstable/class
sugar/unstable/js
@ -32,12 +33,15 @@
[_pageBuffer null]
[_offsets (mhasheqv)] ; The PDF object store
[_ended #f]
[_root (ref this
(mhash 'Type "Catalog"
'Pages (ref this
(mhash 'Type "Pages"
'Count 0
'Kids empty))))] ; top object
[ref-gen (generator ()
(let loop ([refid 1])
(hash-set! _offsets refid 'missing-ref-offset)
(yield refid)
(loop (add1 refid))))]
[_root (ref (mhasheq 'Type "Catalog"
'Pages (ref (mhasheq 'Type "Pages"
'Count 0
'Kids empty))))] ; top object
[page #f] ; The current page
[x 0]
[y 0]
@ -57,10 +61,12 @@
(· this initText)
(· this initImages)
(define/public (ref [payload (mhash)])
(make-object PDFReference this (ref-gen) payload))
(as-methods
addPage
flushPages
ref
write
addContent
_refEnd
@ -68,7 +74,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" (current-pdf-version))) ; PDF version
@ -110,17 +116,6 @@
(for-each (λ (p) (· p end)) pb)
(set-field! _pageBuffer this empty))
;; every js function argument is 'undefined' by default
;; so even a function defined without default values
;; can be called without arguments
(define/contract (ref this [payload (mhash)])
(() (hash?) . ->*m . (is-a?/c PDFReference))
(define next-refid (add1 (length (hash-keys (· this _offsets)))))
(hash-set! (· this _offsets) next-refid 'missing-ref-offset)
(make-object PDFReference this next-refid payload))
(define/contract (write this x)
((or/c string? bytes?) . ->m . any/c)
(define bstr (if (not (bytes? x))
@ -158,17 +153,17 @@
#;(report* (· this _offsets))
(flushPages this)
(define _info (ref this))
(define _info (send this ref))
(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))
@ -189,12 +184,12 @@
(let ([missing-offsets (for/list ([offset (in-list this-offsets)]
[idx (in-list this-idxs)]
#:unless (number? offset))
idx)])
idx)])
(unless (empty? missing-offsets)
(raise-argument-error 'document:end "numerical offsets" missing-offsets)))
(for ([offset (in-list this-offsets)]
[idx (in-list this-idxs)])
(this-write @string-append{@(~r offset #:min-width 10 #:pad-string "0") 00000 n }))
(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))

@ -20,7 +20,7 @@
(hash-ref page-sizes (string-upcase size)))]
[width (list-ref dimensions (if (equal? layout "portrait") 0 1))]
[height (list-ref dimensions (if (equal? layout "portrait") 1 0))]
[content (· document ref)]
[content (send document ref)]
;; Initialize the Font, XObject, and ExtGState dictionaries
[resources (send document ref (mhash 'ProcSet '("PDF" "Text" "ImageB" "ImageC" "ImageI")))]
[margins

Loading…
Cancel
Save