remove String struct

main
Matthew Butterick 5 years ago
parent 34c6f59f5e
commit 5736cc2e28

@ -15,17 +15,15 @@
(define/public (annotate x y w h options)
(hash-set*! options
'Type "Annot"
'Type 'Annot
'Rect (convert-rect x y w h)
'Border '(0 0 0))
(unless (equal? (hash-ref options 'Subtype #f) "Link")
(unless (eq? (hash-ref options 'Subtype #f) 'Link)
(hash-ref! options 'C
(λ ()
(send this normalize-color (or (hash-ref options 'color #f) '(0 0 0))))))
(hash-remove! options 'color)
(when (string? (hash-ref options 'Dest #f)) (hash-update! options 'Dest String))
(for ([(k v) (in-hash options)])
(hash-set! options (string->symbol (string-titlecase (symbol->string k))) v))
@ -36,9 +34,9 @@
(define/public (link x y w h url [options (mhasheq)])
(hash-set*! options
'Subtype "Link"
'A (make-ref (mhash 'S "URI"
'URI (String url))))
'Subtype 'Link
'A (make-ref (mhash 'S 'URI
'URI url)))
(send (hash-ref options 'A) end)
(annotate x y w h options))

@ -123,7 +123,7 @@
[(dict? v) (for/list ([(key val) (in-dict v)])
(cons key (shorten-val val)))]
[(and (bytes? v) (> (bytes-length v) 100))
(subbytes v 0 100)]
(subbytes v 0 100)]
[else v]))
(define (dict-compare arg1 arg2)
@ -143,6 +143,10 @@
(dict-compare v1 v2))
#true)))
(define-simple-check (check-headers-equal? ps1 ps2)
(equal? (peek-bytes 14 0 (open-input-file ps1))
(peek-bytes 14 0 (open-input-file ps2))))
(define-simple-check (check-pdfs-equal? ps1 ps2)
(dict-compare ps1 ps2))

@ -54,8 +54,8 @@
[else
(define color-space
(case (length color)
[(3) "DeviceRGB"]
[(4) "DeviceCMYK"]
[(3) 'DeviceRGB]
[(4) 'DeviceCMYK]
[else (raise-argument-error 'set-color "color of length 3 or 4" color)]))
(set-color-space color-space stroke)
@ -100,7 +100,7 @@
(match-define (list dictionary name)
(hash-ref! (get-field @opacity-registry this) key
(λ ()
(define dictionary (make-hasheq '((Type . "ExtGState"))))
(define dictionary (make-hasheq '((Type . ExtGState))))
(when fill-opacity
(hash-set! dictionary 'ca fill-opacity))
(when stroke-opacity
@ -108,7 +108,7 @@
(define ref-dict (make-ref dictionary))
(send ref-dict end)
(set! @opacity-count (add1 @opacity-count))
(list ref-dict (format "Gs~a" @opacity-count)))))
(list ref-dict (string->symbol (format "Gs~a" @opacity-count))))))
(hash-set! (send (send this page) ext_gstates) name dictionary)
(send this add-content (format "/~a gs" name))))))

@ -3,9 +3,6 @@
(provide (all-defined-out))
;; structs
(struct String (string) #:transparent)
;; for JPEG and PNG
(struct image (label width height obj) #:transparent #:mutable)

@ -36,8 +36,8 @@
(super-new)
(init-field [(@options options) (mhasheq)])
(field [@refs null]
[@root (make-ref (mhasheq 'Type "Catalog"
'Pages (make-ref (mhasheq 'Type "Pages"))))]
[@root (make-ref (mhasheq 'Type 'Catalog
'Pages (make-ref (mhasheq 'Type 'Pages))))]
;; initialize the metadata
[@info (mhasheq 'Producer "PITFALL"
'Creator "PITFALL"
@ -85,7 +85,7 @@
(define doc-info (make-ref))
(for ([(key val) (in-hash @info)])
(dict-set! doc-info key (if (string? val) (String val) val)))
(dict-set! doc-info key val))
(send doc-info end)
(for ([font (in-hash-values @font-families)])

@ -89,7 +89,7 @@ https://github.com/mbutterick/pdfkit/blob/master/lib/font/embedded.coffee
(define font-file (make-ref))
(when isCFF
(dict-set! font-file 'Subtype "CIDFontType0C"))
(dict-set! font-file 'Subtype 'CIDFontType0C))
(send* font-file [write (get-output-bytes (encode-to-port subset))] [end])
@ -111,11 +111,11 @@ https://github.com/mbutterick/pdfkit/blob/master/lib/font/embedded.coffee
(when (test-mode) (random-seed 0))
(define tag (list->string (for/list ([i (in-range 6)])
(integer->char (random 65 (+ 65 26))))))
(define name (string-append tag "+" (font-postscript-name font)))
(define name (string->symbol (string-append tag "+" (font-postscript-name font))))
(define bbox (font-bbox font))
(define descriptor (make-ref
(mhash
'Type "FontDescriptor"
'Type 'FontDescriptor
'FontName name
'Flags flags
'FontBBox (map (λ (x) (* scale x))
@ -132,13 +132,13 @@ https://github.com/mbutterick/pdfkit/blob/master/lib/font/embedded.coffee
(define descendant-font (make-ref
(mhash
'Type "Font"
'Subtype (string-append "CIDFontType" (if isCFF "0" "2"))
'Type 'Font
'Subtype (string->symbol (string-append "CIDFontType" (if isCFF "0" "2")))
'BaseFont name
'CIDSystemInfo
(mhash
'Registry (String "Adobe")
'Ordering (String "Identity")
'Registry "Adobe"
'Ordering "Identity"
'Supplement 0)
'FontDescriptor descriptor
'W (list 0 (for/list ([idx (in-range (length (hash-keys widths)))])
@ -146,10 +146,10 @@ https://github.com/mbutterick/pdfkit/blob/master/lib/font/embedded.coffee
(send descendant-font end)
(send* @dictionary
[set-key! 'Type "Font"]
[set-key! 'Subtype "Type0"]
[set-key! 'Type 'Font]
[set-key! 'Subtype 'Type0]
[set-key! 'BaseFont name]
[set-key! 'Encoding "Identity-H"]
[set-key! 'Encoding 'Identity-H]
[set-key! 'DescendantFonts (list descendant-font)]
[set-key! 'ToUnicode (toUnicodeCmap)])

@ -38,7 +38,7 @@
[(? values val) (set! @current-font val)]
[_ ; if not, load the font
(set! @font-count (add1 @font-count))
(define id (format "F~a" @font-count))
(define id (string->symbol (format "F~a" @font-count)))
(set! @current-font (PDFFont-open src family id))
;; check for existing font families with the same name already in the PDF
(match (hash-ref @font-families (get-field name @current-font) #f)

@ -97,7 +97,7 @@
[(and (string? src) (hash-ref @image-registry src #f))]
[else
(define new-image
(PDFImage-open src (format "I~a" (let () (set! @image-count (add1 @image-count)) @image-count))))
(PDFImage-open src (string->symbol (format "I~a" (let () (set! @image-count (add1 @image-count)) @image-count)))))
(when (string? src) (hash-set! @image-registry src new-image))
new-image]))))

@ -37,27 +37,27 @@ https://github.com/mbutterick/pdfkit/blob/master/lib/image/jpeg.coffee
[(@width width) (read-16bit-integer jpeg-ip)]
[(@channels channels) (read-byte jpeg-ip)]
[(@colorSpace colorSpace) (case @channels
[(1) "DeviceGray"]
[(3) "DeviceRGB"]
[(4) "DeviceCMYK"])]
[(1) 'DeviceGray]
[(3) 'DeviceRGB]
[(4) 'DeviceCMYK])]
[(@obj obj) #f])
(define/public (embed)
(unless @obj
(set! @obj (make-ref
(mhash
'Type "XObject"
'Subtype "Image"
'Type 'XObject
'Subtype 'Image
'BitsPerComponent @bits
'Width @width
'Height @height
'ColorSpace @colorSpace
'Filter "DCTDecode")))
'Filter 'DCTDecode)))
;; add extra decode params for CMYK images. By swapping the
;; min and max values from the default, we invert the colors. See
;; section 4.8.4 of the spec.
(when (equal? @colorSpace "DeviceCMYK")
(when (eq? @colorSpace 'DeviceCMYK)
(dict-set! @obj 'Decode '(1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0)))
(file-position @data 0)
(send* @obj [write @data]

@ -46,14 +46,12 @@
(define (convert object)
(let loop ([x object])
(cond
;; String literals are converted to the PDF name type
[(string? x) (string-append "/" x)]
;; symbols are used for convenience - convert to string
[(symbol? x) (loop (symbol->string x))]
;; String objects (structs) are converted to PDF strings (UTF-16)
[(String? x)
;; symbols are converted to the PDF dictionary key type
[(symbol? x) (string-append "/" (symbol->string x))]
;; String objects (structs) and string literals are converted to PDF strings (UTF-16)
[(string? x)
;; Escape characters as required by the spec
(define string (regexp-replace* escapableRe (String-string x) (λ (c) (hash-ref escapable c))))
(define string (regexp-replace* escapableRe x (λ (c) (hash-ref escapable c))))
;; Detect if this is a unicode string (= contains non-ascii chars)
(define contains-non-ascii? (for/or ([c (in-string string)])
(char>? c (integer->char 127))))
@ -78,14 +76,14 @@
(module+ test
(require rackunit)
(check-equal? (convert "foobar") "/foobar")
(check-equal? (convert (String "foobar")) "(foobar)")
(check-equal? (convert (String "öéÿ")) "(þÿ\u0000ö\u0000é\u0000ÿ)")
(check-equal? (convert (String "fôobár")) "(þÿ\u0000f\u0000ô\u0000o\u0000b\u0000á\u0000r)")
(check-equal? (convert 'foobar) "/foobar")
(check-equal? (convert "foobar") "(foobar)")
(check-equal? (convert "öéÿ") "(þÿ\u0000ö\u0000é\u0000ÿ)")
(check-equal? (convert "fôobár") "(þÿ\u0000f\u0000ô\u0000o\u0000b\u0000á\u0000r)")
(check-equal? (convert #"foobar") "<666f6f626172>")
(check-equal? (convert (seconds->date (quotient 1494483337320 1000) #f)) "(D:20170511061537Z)")
(check-equal? (convert (list "foobar" (String "öéÿ") #"foobar")) "[/foobar (þÿ\u0000ö\u0000é\u0000ÿ) <666f6f626172>]")
(check-true (let ([res (convert (hash "foo" 42 "bar" "fly"))])
(check-equal? (convert (list 'foobar "öéÿ" #"foobar")) "[/foobar (þÿ\u0000ö\u0000é\u0000ÿ) <666f6f626172>]")
(check-true (let ([res (convert (hash 'foo 42 'bar 'fly))])
(or (equal? res "<<\n/foo 42\n/bar /fly\n>>")
(equal? res "<<\n/bar /fly\n/foo 42\n>>"))))
(check-equal? (convert 1234.56789) "1234.56789"))

@ -12,9 +12,9 @@
(check-equal? (· p margins) (margin 72 72 72 72))
(check-equal? (· p height) 792.0)
(check-equal? (· p width) 612.0)
(check-equal? (· p resources ProcSet) '("PDF" "Text" "ImageB" "ImageC" "ImageI"))
(check-equal? (· p resources ProcSet) '(PDF Text ImageB ImageC ImageI))
(check-equal? (· p dictionary Type) "Page")
(check-equal? (· p dictionary Type) 'Page)
(check-equal? (· p dictionary MediaBox) '(0 0 612.0 792.0))
(check-true (is-a? (· p dictionary Contents) PDFReference))
(check-true (is-a? (· p dictionary Resources) PDFReference))

@ -20,7 +20,7 @@
[(@width width) (list-ref @dimensions (if (equal? @layout "portrait") 0 1))]
[(@height height) (list-ref @dimensions (if (equal? @layout "portrait") 1 0))]
[@content (make-ref)]
[(@resources resources) (make-ref (mhash 'ProcSet '("PDF" "Text" "ImageB" "ImageC" "ImageI")))]
[(@resources resources) (make-ref (mhash 'ProcSet '(PDF Text ImageB ImageC ImageI)))]
[(@margins margins)
(let ([margin-value (hash-ref @options 'margin #f)])
(if (number? margin-value)
@ -29,7 +29,7 @@
;; The page dictionary
[(@dictionary dictionary)
(make-ref
(mhash 'Type "Page"
(mhash 'Type 'Page
'Parent @page-parent
'MediaBox (list 0 0 @width @height)
'Contents @content

@ -42,6 +42,8 @@
(send doc end))
#:exists 'replace))
(when test?
#;(check-headers-equal? ps (this->control ps))
(check-pdfs-equal? ps (this->control ps))
(when pdfkit?
#;(check-headers-equal? ps (this->pdfkit-control ps))
(check-pdfs-equal? ps (this->pdfkit-control ps)))))

@ -30,12 +30,12 @@ https://github.com/mbutterick/pdfkit/blob/master/lib/image/png.coffee
(unless @obj
(set! @obj
(make-ref
(mhash 'Type "XObject"
'Subtype "Image"
(mhash 'Type 'XObject
'Subtype 'Image
'BitsPerComponent (hash-ref @image 'bits)
'Width @width
'Height @height
'Filter "FlateDecode")))
'Filter 'FlateDecode)))
(unless (hash-ref @image 'hasAlphaChannel #f)
(define params (make-ref
@ -53,8 +53,8 @@ https://github.com/mbutterick/pdfkit/blob/master/lib/image/png.coffee
(send* palette-ref [write (hash-ref @image 'palette)] [end])
;; build the color space array for the image
(dict-set! @obj 'Colorspace
(list "Indexed" "DeviceRGB" (sub1 (/ (bytes-length (hash-ref @image 'palette)) 3)) palette-ref))]
[else (dict-set! @obj 'ColorSpace "DeviceRGB")])
(list 'Indexed 'DeviceRGB (sub1 (/ (bytes-length (hash-ref @image 'palette)) 3)) palette-ref))]
[else (dict-set! @obj 'ColorSpace 'DeviceRGB)])
(cond
@ -77,13 +77,13 @@ https://github.com/mbutterick/pdfkit/blob/master/lib/image/png.coffee
(when @alpha-channel
(define sMask-ref
(make-ref
(mhash 'Type "XObject"
'Subtype "Image"
(mhash 'Type 'XObject
'Subtype 'Image
'Height @height
'Width @width
'BitsPerComponent 8
'Filter "FlateDecode"
'ColorSpace "DeviceGray"
'Filter 'FlateDecode
'ColorSpace 'DeviceGray
'Decode '(0 1))))
(send* sMask-ref [write @alpha-channel] [end])
(dict-set! @obj 'SMask sMask-ref))

@ -68,7 +68,7 @@
(cond
[(zero? (bytes-length bstr)) #false]
[(and (current-compress-streams?) (not (hash-ref @payload 'Filter #f)))
(hash-set! @payload 'Filter "FlateDecode")
(hash-set! @payload 'Filter 'FlateDecode)
(deflate bstr)]
[else bstr])))

@ -29,10 +29,10 @@
(define/override (embed)
(set-field! payload @dictionary
(mhash 'Type "Font"
'BaseFont name
'Subtype "Type1"
'Encoding "WinAnsiEncoding"))
(mhash 'Type 'Font
'BaseFont (string->symbol name)
'Subtype 'Type1
'Encoding 'WinAnsiEncoding))
(send @dictionary end))
(define/override (encode text [options #f])

Loading…
Cancel
Save