You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.5 KiB
Racket
135 lines
3.5 KiB
Racket
#lang br
|
|
(require racket/draw)
|
|
(provide PDFDocument)
|
|
|
|
(define PDFDocument
|
|
(class pdf-dc%
|
|
(init-field [options (hasheq)])
|
|
(let ([output-file (hash-ref options 'out "outrkt.pdf")])
|
|
(super-new [interactive #f]
|
|
[parent #f]
|
|
[use-paper-bbox #f]
|
|
[as-eps #f]
|
|
[width #f]
|
|
[height #f]
|
|
[output (open-output-file output-file #:exists 'replace)]))
|
|
|
|
;; PDF version
|
|
(field [version 1.3])
|
|
|
|
;; Whether streams should be compressed
|
|
(field [compress (hash-ref options 'compress #t)])
|
|
|
|
(define _pageBuffer null)
|
|
(define _pageBufferStart 0)
|
|
|
|
;; The PDF object store
|
|
(define _offsets null)
|
|
(define _waiting 0)
|
|
(define _ended #f)
|
|
(define _offset 0)
|
|
|
|
(define _root (ref
|
|
(hasheq 'Type 'Catalog'
|
|
'Pages (ref
|
|
(hasheq 'Type 'Pages'
|
|
'Count 0
|
|
'Kids empty)))))
|
|
|
|
;; The current page
|
|
(field [page #f])
|
|
|
|
;; todo
|
|
;; Initialize mixins
|
|
#;(initColor)
|
|
#;(initVector)
|
|
#;(initFonts)
|
|
#;(initText)
|
|
#;(initImages)
|
|
|
|
;; Initialize the metadata
|
|
(field [info (hasheq
|
|
'Producer 'PitfallKit'
|
|
'Creator 'PitfallKit'
|
|
'CreationDate (seconds->date (current-seconds)))])
|
|
|
|
(when (hash-ref options 'info #f)
|
|
(for ([(key val) (in-hash (hash-ref options 'info))])
|
|
(hash-set! info key val)))
|
|
|
|
;; Write the header
|
|
;; PDF version
|
|
(_write (format "%PDF-#{~a}" version))
|
|
|
|
(_write (format "%~a~a~a~a" #xFF #xFF #xFF #xFF))
|
|
|
|
;; Add the first page
|
|
#;(unless (not (hash-ref options 'autoFirstPage #t))
|
|
(addPage)) ; todo
|
|
|
|
;; todo
|
|
;;mixin = (methods) =>
|
|
;;for name, method of methods
|
|
;;this::[name] = method
|
|
|
|
;; todo
|
|
;; Load mixins
|
|
;mixin require './mixins/color'
|
|
;mixin require './mixins/vector'
|
|
;mixin require './mixins/fonts'
|
|
;mixin require './mixins/text'
|
|
;mixin require './mixins/images'
|
|
;mixin require './mixins/annotations'
|
|
|
|
(field [x 0])
|
|
(field [y 0])
|
|
(define _ctm null)
|
|
(define/public (addPage [options options])
|
|
;; end the current page if needed
|
|
(unless (hash-ref options 'bufferPages #f)
|
|
(flushPages))
|
|
|
|
;; create a page object
|
|
(define page 42) ; todo new PDFPage(this, options)
|
|
(push! _pageBuffer page)
|
|
|
|
;; add the page to the object store
|
|
(define pages (make-hasheq)) ; todo @_root.data.Pages.data
|
|
(hash-update! pages 'Kids (λ (val) (cons 42 val)) null) ; todo @page.dictionary
|
|
(hash-update! pages 'Count add1 0)
|
|
|
|
;; reset x and y coordinates
|
|
(set! x 42) ;; todo @page.margins.left
|
|
(set! y 42) ;; todo @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) ;; todo
|
|
|
|
;; @emit('pageAdded') ;; todo
|
|
|
|
this)
|
|
|
|
(define/public (flushPages)
|
|
42) ; temp
|
|
|
|
(define/public (ref . xs)
|
|
42) ; temp
|
|
|
|
(define/public (_write . xs)
|
|
42) ; temp
|
|
|
|
(define (end-doc) 'done) ; tempo
|
|
(override end-doc)
|
|
|
|
(define _info #f)
|
|
(define/public (end)
|
|
(flushPages)
|
|
(end-doc)))) ; temp
|
|
|
|
|
|
(define doc (make-object PDFDocument (hasheq 'out "testrkt0.pdf")))
|
|
(module+ test
|
|
(require rackunit)
|
|
(check-equal? (send doc end) 'done)) |