From 5736cc2e28d6709300a5ae90efefda306291a45c Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Tue, 25 Dec 2018 16:08:59 -0800 Subject: [PATCH] remove String struct --- pitfall/pitfall/annotations.rkt | 12 +++++------- pitfall/pitfall/check-pdf.rkt | 6 +++++- pitfall/pitfall/color.rkt | 8 ++++---- pitfall/pitfall/core.rkt | 3 --- pitfall/pitfall/document.rkt | 6 +++--- pitfall/pitfall/embedded.rkt | 20 ++++++++++---------- pitfall/pitfall/fonts.rkt | 2 +- pitfall/pitfall/images.rkt | 2 +- pitfall/pitfall/jpeg.rkt | 14 +++++++------- pitfall/pitfall/object.rkt | 24 +++++++++++------------- pitfall/pitfall/page-test.rkt | 4 ++-- pitfall/pitfall/page.rkt | 4 ++-- pitfall/pitfall/pdftest.rkt | 2 ++ pitfall/pitfall/png.rkt | 18 +++++++++--------- pitfall/pitfall/reference.rkt | 2 +- pitfall/pitfall/standard-font.rkt | 8 ++++---- 16 files changed, 67 insertions(+), 68 deletions(-) diff --git a/pitfall/pitfall/annotations.rkt b/pitfall/pitfall/annotations.rkt index a45026bc..16d0803e 100644 --- a/pitfall/pitfall/annotations.rkt +++ b/pitfall/pitfall/annotations.rkt @@ -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)) diff --git a/pitfall/pitfall/check-pdf.rkt b/pitfall/pitfall/check-pdf.rkt index 69abfd0e..d1c7e501 100644 --- a/pitfall/pitfall/check-pdf.rkt +++ b/pitfall/pitfall/check-pdf.rkt @@ -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)) diff --git a/pitfall/pitfall/color.rkt b/pitfall/pitfall/color.rkt index 351244e2..a7c4b34c 100644 --- a/pitfall/pitfall/color.rkt +++ b/pitfall/pitfall/color.rkt @@ -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)))))) diff --git a/pitfall/pitfall/core.rkt b/pitfall/pitfall/core.rkt index 6860abab..1fa3e2a0 100644 --- a/pitfall/pitfall/core.rkt +++ b/pitfall/pitfall/core.rkt @@ -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) diff --git a/pitfall/pitfall/document.rkt b/pitfall/pitfall/document.rkt index fc5d96f7..499d44fe 100644 --- a/pitfall/pitfall/document.rkt +++ b/pitfall/pitfall/document.rkt @@ -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)]) diff --git a/pitfall/pitfall/embedded.rkt b/pitfall/pitfall/embedded.rkt index d495c19f..750ad522 100644 --- a/pitfall/pitfall/embedded.rkt +++ b/pitfall/pitfall/embedded.rkt @@ -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)]) diff --git a/pitfall/pitfall/fonts.rkt b/pitfall/pitfall/fonts.rkt index 3b24ef97..ba2872bd 100644 --- a/pitfall/pitfall/fonts.rkt +++ b/pitfall/pitfall/fonts.rkt @@ -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) diff --git a/pitfall/pitfall/images.rkt b/pitfall/pitfall/images.rkt index 560fdd87..9648ca23 100644 --- a/pitfall/pitfall/images.rkt +++ b/pitfall/pitfall/images.rkt @@ -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])))) diff --git a/pitfall/pitfall/jpeg.rkt b/pitfall/pitfall/jpeg.rkt index b4a5062d..1babad47 100644 --- a/pitfall/pitfall/jpeg.rkt +++ b/pitfall/pitfall/jpeg.rkt @@ -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] diff --git a/pitfall/pitfall/object.rkt b/pitfall/pitfall/object.rkt index 205125a5..000108da 100644 --- a/pitfall/pitfall/object.rkt +++ b/pitfall/pitfall/object.rkt @@ -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")) diff --git a/pitfall/pitfall/page-test.rkt b/pitfall/pitfall/page-test.rkt index 48e48bf2..bd1e275b 100644 --- a/pitfall/pitfall/page-test.rkt +++ b/pitfall/pitfall/page-test.rkt @@ -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)) diff --git a/pitfall/pitfall/page.rkt b/pitfall/pitfall/page.rkt index 7d84bdad..87ed3e60 100644 --- a/pitfall/pitfall/page.rkt +++ b/pitfall/pitfall/page.rkt @@ -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 diff --git a/pitfall/pitfall/pdftest.rkt b/pitfall/pitfall/pdftest.rkt index 9d1bbb4c..220dded7 100644 --- a/pitfall/pitfall/pdftest.rkt +++ b/pitfall/pitfall/pdftest.rkt @@ -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))))) diff --git a/pitfall/pitfall/png.rkt b/pitfall/pitfall/png.rkt index 6298e5db..267e68aa 100644 --- a/pitfall/pitfall/png.rkt +++ b/pitfall/pitfall/png.rkt @@ -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)) diff --git a/pitfall/pitfall/reference.rkt b/pitfall/pitfall/reference.rkt index 087e88cf..4a251796 100644 --- a/pitfall/pitfall/reference.rkt +++ b/pitfall/pitfall/reference.rkt @@ -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]))) diff --git a/pitfall/pitfall/standard-font.rkt b/pitfall/pitfall/standard-font.rkt index a3f9b2c6..2bb7cd67 100644 --- a/pitfall/pitfall/standard-font.rkt +++ b/pitfall/pitfall/standard-font.rkt @@ -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])