From 967b33aef509e9c5f8ff743b23bb68e02d4e3666 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Mon, 15 May 2017 10:48:20 -0700 Subject: [PATCH] start test2 --- pitfall/pitfall/test/node_modules/pdfkit | 2 +- pitfall/pitfall/test/outrkt.pdf | 0 pitfall/pitfall/test/test1.pdf | 58 ++---- pitfall/pitfall/test/test2.coffee | 70 ++++++++ pitfall/pitfall/test/test2.pdf | 165 ++++++++++++++++++ pitfall/pitfall/test/test2.rkt | 89 ++++++++++ .../{test0-uncompressed.pdf => test2rkt.pdf} | 41 +++-- pitfall/pitfall/vector.rkt | 42 ++++- 8 files changed, 406 insertions(+), 61 deletions(-) delete mode 100644 pitfall/pitfall/test/outrkt.pdf create mode 100644 pitfall/pitfall/test/test2.coffee create mode 100644 pitfall/pitfall/test/test2.pdf create mode 100644 pitfall/pitfall/test/test2.rkt rename pitfall/pitfall/test/{test0-uncompressed.pdf => test2rkt.pdf} (66%) diff --git a/pitfall/pitfall/test/node_modules/pdfkit b/pitfall/pitfall/test/node_modules/pdfkit index 8312a5c1..80d95f25 120000 --- a/pitfall/pitfall/test/node_modules/pdfkit +++ b/pitfall/pitfall/test/node_modules/pdfkit @@ -1 +1 @@ -../../../../../../usr/local/lib/node_modules/pdfkit \ No newline at end of file +../../../../../../../usr/local/lib/node_modules/pdfkit \ No newline at end of file diff --git a/pitfall/pitfall/test/outrkt.pdf b/pitfall/pitfall/test/outrkt.pdf deleted file mode 100644 index e69de29b..00000000 diff --git a/pitfall/pitfall/test/test1.pdf b/pitfall/pitfall/test/test1.pdf index d1aaa358..d0d18255 100644 --- a/pitfall/pitfall/test/test1.pdf +++ b/pitfall/pitfall/test/test1.pdf @@ -1,11 +1,5 @@ %PDF-1.3 %ÿÿÿÿ -6 0 obj -<< -/Type /ExtGState -/ca 1 ->> -endobj 5 0 obj << /Type /Page @@ -18,43 +12,28 @@ endobj 4 0 obj << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] -/ExtGState << -/Gs1 6 0 R ->> >> endobj 3 0 obj << -/Length 294 +/Length 90 >> stream 1 0 0 -1 0 792 cm -q -100 150 m -100 250 l -200 250 l -/DeviceRGB cs -1 0.2 0 scn -/Gs1 gs -f -230 200 m -230 172.385763 252.385763 150 280 150 c -307.614237 150 330 172.385763 330 200 c -330 227.614237 307.614237 250 280 250 c -252.385763 250 230 227.614237 230 200 c -h -/DeviceRGB cs -0.4 0 1 scn -/Gs1 gs -f +0 20 m +100 160 l +130 200 150 120 v +190 -40 200 200 300 150 c +400 90 l +S endstream endobj -7 0 obj +6 0 obj << /Producer (PDFKit) /Creator (PDFKit) -/CreationDate (D:20170514013102Z) +/CreationDate (D:20170515171502Z) >> endobj 2 0 obj @@ -71,21 +50,20 @@ endobj >> endobj xref -0 8 +0 7 0000000000 65535 f -0000000744 00000 n -0000000695 00000 n -0000000258 00000 n -0000000163 00000 n -0000000059 00000 n +0000000467 00000 n +0000000418 00000 n +0000000186 00000 n +0000000119 00000 n 0000000015 00000 n -0000000603 00000 n +0000000326 00000 n trailer << -/Size 8 +/Size 7 /Root 2 0 R -/Info 7 0 R +/Info 6 0 R >> startxref -801 +524 %%EOF diff --git a/pitfall/pitfall/test/test2.coffee b/pitfall/pitfall/test/test2.coffee new file mode 100644 index 00000000..b30d8338 --- /dev/null +++ b/pitfall/pitfall/test/test2.coffee @@ -0,0 +1,70 @@ +PDFDocument = require 'pdfkit' +fs = require 'fs' + +# Create a new PDFDocument +doc = new PDFDocument({compress: no}) +doc.pipe(fs.createWriteStream('test2.pdf')) + +doc.moveTo(0, 20) + .lineTo(100, 160) + .quadraticCurveTo(130, 200, 150, 120) + .bezierCurveTo(190, -40, 200, 200, 300, 150) # draw a bezier curve + .lineTo(400, 90) # draw another line + .stroke() # stroke the path + +doc.translate(0, 200) + +doc.path('M 0,20 L 100,160 Q 130,200 150,120 C 190,-40 200,200 300,150 L 400,90').stroke() + +doc.translate(0, 200) + +doc.polygon [100, 0], [50, 100], [150, 100] +doc.stroke() + +doc.save() +doc.translate(200, 0) +doc.circle(100, 50, 50) + .dash(5, space: 10) + .stroke() +doc.restore() + +doc.save() +doc.translate(400, 0) +doc.circle(100, 50, 50) + .lineWidth(3) + .fillOpacity(0.8) + .fillAndStroke("red", "#900") +doc.restore() + +doc.translate(0, 200) + + +# these examples are easier to see with a large line width +doc.lineWidth(25) +# line cap settings +doc.lineCap('butt') + .moveTo(50, 20) + .lineTo(100, 20) + .stroke() +doc.lineCap('round') + .moveTo(150, 20) + .lineTo(200, 20) + .stroke() +# square line cap shown with a circle instead of a line so you can see it +doc.lineCap('square') + .moveTo(250, 20) + .circle(275, 30, 15) + .stroke() +# line join settings +doc.lineJoin('miter') + .rect(50, 100, 50, 50) + .stroke() +doc.lineJoin('round') + .rect(150, 100, 50, 50) + .stroke() +doc.lineJoin('bevel') + .rect(250, 100, 50, 50) + .stroke() + + +doc.end() \ No newline at end of file diff --git a/pitfall/pitfall/test/test2.pdf b/pitfall/pitfall/test/test2.pdf new file mode 100644 index 00000000..724076a9 --- /dev/null +++ b/pitfall/pitfall/test/test2.pdf @@ -0,0 +1,165 @@ +%PDF-1.3 +%ÿÿÿÿ +6 0 obj +<< +/Type /ExtGState +/ca 0.8 +>> +endobj +7 0 obj +<< +/Type /ExtGState +/ca 1 +>> +endobj +8 0 obj +<< +/Type /ExtGState +/CA 1 +>> +endobj +5 0 obj +<< +/Type /Page +/Parent 1 0 R +/MediaBox [0 0 612 792] +/Contents 3 0 R +/Resources 4 0 R +>> +endobj +4 0 obj +<< +/ProcSet [/PDF /Text /ImageB /ImageC /ImageI] +/ExtGState << +/Gs1 6 0 R +/Gs2 7 0 R +/Gs3 8 0 R +>> +>> +endobj +3 0 obj +<< +/Length 979 +>> +stream +1 0 0 -1 0 792 cm +0 20 m +100 160 l +130 200 150 120 v +190 -40 200 200 300 150 c +400 90 l +S +1 0 0 1 0 200 cm +0 20 m +100 160 l +130 200 150 120 v +190 -40 200 200 300 150 c +400 90 l +S +1 0 0 1 0 200 cm +100 0 m +50 100 l +150 100 l +h +S +q +1 0 0 1 200 0 cm +50 50 m +50 22.385763 72.385763 0 100 0 c +127.614237 0 150 22.385763 150 50 c +150 77.614237 127.614237 100 100 100 c +72.385763 100 50 77.614237 50 50 c +h +[5 10] 0 d +S +Q +q +1 0 0 1 400 0 cm +50 50 m +50 22.385763 72.385763 0 100 0 c +127.614237 0 150 22.385763 150 50 c +150 77.614237 127.614237 100 100 100 c +72.385763 100 50 77.614237 50 50 c +h +3 w +/Gs1 gs +/DeviceRGB cs +1 0 0 scn +/Gs2 gs +/DeviceRGB CS +0.6 0 0 SCN +/Gs3 gs +B +Q +1 0 0 1 0 200 cm +25 w +0 J +50 20 m +100 20 l +S +1 J +150 20 m +200 20 l +S +2 J +250 20 m +260 30 m +260 21.715729 266.715729 15 275 15 c +283.284271 15 290 21.715729 290 30 c +290 38.284271 283.284271 45 275 45 c +266.715729 45 260 38.284271 260 30 c +h +S +0 j +50 100 50 50 re +S +1 j +150 100 50 50 re +S +2 j +250 100 50 50 re +S + +endstream +endobj +9 0 obj +<< +/Producer (PDFKit) +/Creator (PDFKit) +/CreationDate (D:20170515173303Z) +>> +endobj +2 0 obj +<< +/Type /Catalog +/Pages 1 0 R +>> +endobj +1 0 obj +<< +/Type /Pages +/Count 1 +/Kids [5 0 R] +>> +endobj +xref +0 10 +0000000000 65535 f +0000001541 00000 n +0000001492 00000 n +0000000370 00000 n +0000000253 00000 n +0000000149 00000 n +0000000015 00000 n +0000000061 00000 n +0000000105 00000 n +0000001400 00000 n +trailer +<< +/Size 10 +/Root 2 0 R +/Info 9 0 R +>> +startxref +1598 +%%EOF diff --git a/pitfall/pitfall/test/test2.rkt b/pitfall/pitfall/test/test2.rkt new file mode 100644 index 00000000..709733a8 --- /dev/null +++ b/pitfall/pitfall/test/test2.rkt @@ -0,0 +1,89 @@ +#lang pitfall/pdftest +(define-runtime-path this "test2rkt.pdf") + +(check-true + (let ([doc (new PDFDocument)]) + (send doc pipe (open-output-file this #:exists 'replace)) + + ;; curved path as bezier + (send* doc + [moveTo 0 20] + [lineTo 100 160] + [quadraticCurveTo 130 200 150 120] + [bezierCurveTo 190 -40 200 200 300 150] + [lineTo 400 90] + [stroke]) + + (send* doc [translate 0 200]) + + + ;; curved path as svg path + (send* doc + [path "M 020 L 100160 Q 130200 150120 C 190-40 200200 300150 L 40090"] + [stroke]) + + + (send* doc + [translate 0 200]) + #| + + ;; triangle + (send* doc + [polygon [100 0] [50 100] [150 100]] + [stroke]) + + ;; dashed circle + (send* doc + [save] + [translate 200 0] + [circle 100 50 50] + [dash 5 (hash 'space 10)] + [stroke] + [restore]) + + ;; filled circle + (send* doc + [save] + [translate 400 0] + [circle 100 50 50] + [lineWidth 3] + [fillOpacity 0 [8]] + [fillAndStroke "red" "#900"] + [restore]) + + (send* doc [translate 0 200]) + + ;; these examples are easier to see with a large line width + (send* doc [lineWidth 25]) + + ;; line cap settings + (send* doc [lineCap 'butt] + [moveTo 50 20] + [lineTo 100 20] + [stroke] + [lineCap 'round] + [moveTo 150 20] + [lineTo 200 20] + [stroke]) + + ;; square line cap shown with a circle instead of a line so you can see it + (send* doc [lineCap 'square] + [moveTo 250 20] + [circle 275 30 15] + [stroke]) + + ;; line join settings + (send* doc [lineJoin 'miter] + [rect 50 100 50 50] + [stroke] + [lineJoin 'round] + [rect 150 100 50 50] + [stroke] + [lineJoin 'bevel] + [rect 250 100 50 50] + [stroke]) + |# + + (send doc end))) + +;(check-copy-equal? this) \ No newline at end of file diff --git a/pitfall/pitfall/test/test0-uncompressed.pdf b/pitfall/pitfall/test/test2rkt.pdf similarity index 66% rename from pitfall/pitfall/test/test0-uncompressed.pdf rename to pitfall/pitfall/test/test2rkt.pdf index 416a5610..0cb194f0 100644 --- a/pitfall/pitfall/test/test0-uncompressed.pdf +++ b/pitfall/pitfall/test/test2rkt.pdf @@ -2,11 +2,11 @@ %ÿÿÿÿ 5 0 obj << -/Type /Page /Parent 1 0 R -/MediaBox [0 0 612 792] -/Contents 3 0 R /Resources 4 0 R +/Contents 3 0 R +/MediaBox [0 0 612 792] +/Type /Page >> endobj 4 0 obj @@ -16,48 +16,57 @@ endobj endobj 3 0 obj << -/Length 18 +/Length 126 >> stream 1 0 0 -1 0 792 cm +0 20 m +100 160 l +130 200 150 120 v +190 -40 200 200 300 150 c +400 90 l +S +1 0 0 1 0 200 cm +S +1 0 0 1 0 200 cm endstream endobj 6 0 obj << -/Producer (PDFKit) -/Creator (PDFKit) -/CreationDate (D:20170513030718Z) +/CreationDate (D:19700101000000Z) +/Creator (PitfallKit) +/Producer (PitfallKit) >> endobj 2 0 obj << -/Type /Catalog /Pages 1 0 R +/Type /Catalog >> endobj 1 0 obj << -/Type /Pages -/Count 1 /Kids [5 0 R] +/Count 1 +/Type /Pages >> endobj xref 0 7 0000000000 65535 f -0000000395 00000 n -0000000346 00000 n +0000000512 00000 n +0000000463 00000 n 0000000186 00000 n 0000000119 00000 n 0000000015 00000 n -0000000254 00000 n +0000000363 00000 n trailer << -/Size 7 -/Root 2 0 R /Info 6 0 R +/Root 2 0 R +/Size 7 >> startxref -452 +569 %%EOF diff --git a/pitfall/pitfall/vector.rkt b/pitfall/pitfall/vector.rkt index 65639cce..3bb936db 100644 --- a/pitfall/pitfall/vector.rkt +++ b/pitfall/pitfall/vector.rkt @@ -14,29 +14,33 @@ lineTo moveTo bezierCurveTo + quadraticCurveTo ellipse circle + path _windingRule fill + stroke transform translate - scale) - (define/public (path pth) this) ;; SVGPath.apply this, path ; todo - )) + scale))) (define default-ctm-value '(1 0 0 1 0 0)) + (define/contract (initVector this) (->m void?) (set-field! _ctm this default-ctm-value) (set-field! _ctmStack this null)) + (define/contract (save this) (->m object?) (push-field! _ctmStack this (· this _ctm)) (send this addContent "q")) + (define/contract (restore this) (->m object?) (set-field! _ctm this (if (pair? (· this _ctmStack)) @@ -44,22 +48,32 @@ default-ctm-value)) (send this addContent "Q")) + (define/contract (closePath this) (->m object?) (send this addContent "h")) + (define/contract (moveTo this x y) (number? number? . ->m . object?) (send this addContent (format "~a ~a m" x y))) + (define/contract (lineTo this x y) (number? number? . ->m . object?) (send this addContent (format "~a ~a l" x y))) + (define/contract (bezierCurveTo this cp1x cp1y cp2x cp2y x y) (number? number? number? number? number? number? . ->m . object?) (send this addContent (format "~a c" (string-join (map number (list cp1x cp1y cp2x cp2y x y)) " ")))) + +(define/contract (quadraticCurveTo this cpx cpy x y) + (number? number? number? number . ->m . object?) + (send this addContent (format "~a v" (string-join (map number (list cpx cpy x y)) " ")))) + + (define/contract (ellipse this x y r1 [r2 r1]) ((number? number? number?) (number?) . ->*m . object?) ;; based on http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas/2173084#2173084 @@ -80,14 +94,23 @@ (bezierCurveTo this (- xm ox) ye x (+ ym oy) x ym) (closePath this)) + (define/contract (circle this x y radius) (number? number? number? . ->m . object?) (ellipse this x y radius)) + +(define/contract (path this path-data) + (string? . ->m . object?) + ;(parse-svg-path this path-data) + this) + + (define/contract (_windingRule rule) ((or/c string? #f) . -> . string?) (if (and (string? rule) (regexp-match #rx"^even-?odd$" rule)) "*" "")) + (define/contract (fill this color [rule #f]) ((color-string?) ((or/c string? #f)) . ->*m . object?) (when (regexp-match #rx"^(even-?odd)|(non-?zero)$" color) @@ -96,11 +119,19 @@ (when color (send this fillColor color)) ;; fillColor method is from color mixin (send this addContent (format "f~a" (_windingRule rule)))) + +(define/contract (stroke this [color #f]) + (() ((or/c color-string? #f)) . ->*m . object?) + (when color (send this strokeColor color)) + (send this addContent "S")) + + (define tm/c (list/c number? number? number? number? number? number?)) (define/contract (make-transform-string ctm) (tm/c . -> . string?) (format "~a cm" (string-join (map number ctm) " "))) + (define/contract (combine-transforms m-transform n-transform) (tm/c tm/c . -> . tm/c) (match-define (list m11 m12 m21 m22 mdx mdy) m-transform) @@ -112,15 +143,18 @@ (+ (* n11 mdx) (* n21 mdy) ndx) (+ (* n12 mdx) (* n22 mdy) ndy))) + (define/contract (transform this m11 m12 m21 m22 mdx mdy) (number? number? number? number? number? number? . ->m . object?) (define new-ctm (list m11 m12 m21 m22 mdx mdy)) (set-field! _ctm this (combine-transforms (· this _ctm) new-ctm)) (send this addContent (make-transform-string new-ctm))) + (define/contract (translate this x y) (number? number? . ->m . object?) - (transform this (list 1 0 0 1 x y))) + (transform this 1 0 0 1 x y)) + (define/contract scale (case->m