next: add `write` for reference

main
Matthew Butterick 8 years ago
parent 76bbcce9f9
commit c5eb57009e

@ -4,9 +4,11 @@
(provide PDFDocument)
(require "reference.rkt" "struct.rkt" "object.rkt" "page.rkt" "helper.rkt")
(require "mixins/vector.rkt")
(define PDFDocument
(class object% ; actually is an instance of readable.Stream, which is an input port
;; actually is an instance of readable.Stream, which is an input port
(class (vector-mixin object%)
(init-field [(@options options) (mhash)])
(let ([output-file (hash-ref @options 'out "outrkt.pdf")])
(super-new))
@ -32,10 +34,10 @@
(field [(@_root _root) (@ref
(mhash 'Type "Catalog"
'Pages (@ref
(mhash 'Type "Pages"
'Count 0
'Kids empty))))])
'Pages (@ref
(mhash 'Type "Pages"
'Count 0
'Kids empty))))])
;; The current page
(field [(@page page) #f])
@ -43,12 +45,11 @@
;; other fields, hoisted from below (why is this necessary?)
(field [(@x x) 0])
(field [(@y y) 0])
(field [(@_ctm _ctm) null])
;; todo
;; Initialize mixins
#;(@initColor)
#;(@initVector)
(· this initVector)
#;(@initFonts)
#;(@initText)
#;(@initImages)
@ -82,6 +83,7 @@
;; todo
;; Load mixins
;; (in racket this is handled automatically in the class decl)
;mixin require './mixins/color'
;mixin require './mixins/vector'
;mixin require './mixins/fonts'
@ -97,7 +99,7 @@
(@flushPages))
;; create a page object
(define @page (make-object PDFPage this options))
(set! @page (make-object PDFPage this options))
(push! @_pageBuffer @page)
;; add the page to the object store
(define pages (· @_root data Pages data))
@ -109,8 +111,8 @@
(set! @y (· @page margins top))
;; flip PDF coordinate system so that the origin is in
;; the top left rather than the bottom left
(set! @_ctm '(1 0 0 1 0 0))
#;(@transform 1 0 0 -1 0 (· @page height)) ; comes from vector mixin
(set-field! _ctm this '(1 0 0 1 0 0))
(send this transform 1 0 0 -1 0 (· @page height))
#;(@emit "pageAdded") ; from eventemitter interface
this
@ -145,9 +147,13 @@
(newBuffer (string-append data "\n"))
data)])
(@push data)
(report @byte-strings)
(+= @_offset (buffer-length data))))
(public [@addContent addContent])
(define (@addContent data)
(send @page write data)
this)
(field [op #f])
(define/public (pipe port)
(set! op port))
@ -183,15 +189,15 @@
(@_write "0000000000 65535 f ")
(for ([offset (in-list @_offsets)])
(@_write (string-append
(~r (or offset (random 17)) #;debug #:min-width 10 #:pad-string "0")
(~r (or offset #xdead) #;debug #:min-width 10 #:pad-string "0")
" 00000 n ")))
;; trailer
(@_write "trailer")
;; todo: make `PDFObject:convert` a static method
(@_write (send (make-object PDFObject) convert
(mhash 'Size (add1 (length @_offsets))
'Root @_root
'Info @_info)))
'Root @_root
'Info @_info)))
(@_write "startxref")
(@_write (number->string xRefOffset))
@ -201,15 +207,15 @@
;; in node you (@push null) which signals to the stream
;; to copy to its output port
;; here we'll do it manually
(copy-port (open-input-bytes
(apply bytes-append (reverse @byte-strings)))
op)
(copy-port (open-input-bytes (apply bytes-append (reverse @byte-strings))) op)
(close-output-port op))))
(define doc (new PDFDocument))
(module+ test
(require rackunit)
(send doc pipe (open-output-file "testrkt0.pdf" #:exists 'replace))
(check-equal? (send doc end) 'done))
(require rackunit racket/file)
(define ob (open-output-bytes))
(send doc pipe ob)
(check-equal? (send doc end) 'done)
(check-equal? (get-output-bytes ob) (file->bytes "demo.pdf")))

@ -1,4 +1,5 @@
#lang racket/base
(require sugar/debug)
(require racket/class "helper.rkt")
(provide PDFPage)
@ -58,8 +59,20 @@
'Contents @content
'Resources @resources))])
(define/public (end)
'nothing) ;; temp
(public [@maxY maxY])
(define (@maxY)
(- @height (· @margins bottom)))
(public [@write write])
(define (@write chunk)
(void)
#;(send @content write chunk)) ; resume here
(public [@end end])
(define (@end)
(send @dictionary end)
(send @resources end)
(send @content end))
))

Loading…
Cancel
Save