Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
You can edit this page using
wiki syntax
for markup.
Article contents:
== pdf [[toc:]] === Description A library for PDF generation. === Author Marc Battyani and Bruce Butterfield === Maintainer [[/users/ivan-raikov|Ivan Raikov]] === Repository This egg is hosted on the CHICKEN Subversion repository: [[https://anonymous@code.call-cc.org/svn/chicken-eggs/release/6/pdf|https://anonymous@code.call-cc.org/svn/chicken-eggs/release/6/pdf]] If you want to check out the source code repository of this egg and you are not familiar with Subversion, see [[/egg-svn-checkout|this page]]. === Requirements srfi-1, regex, format === Documentation A PDF document under construction is a record of type {{doc}}, created by {{build-doc}}. The content of a page content is a record of type {{page-context}}, created by {{build-page-context}}. Both are passed as arguments to the PDF operators described below, so independent documents can be built in the same program without interfering with each other. Each document is created for a specific PDF version, {{"1.3"}} or {{"1.4"}}. A {{"1.3"}} document (the default) only allows core PDF functionality. A {{"1.4"}} document additionally allows PDF 1.4 features, such as alpha transparency. See {{build-doc}}. ==== Building documents ===== build-doc <procedure>(build-doc [COMPRESS-STREAMS? [PDF-VERSION]])</procedure> Creates and returns a new, empty document. {{COMPRESS-STREAMS?}} (default {{#t}}) sets whether streams are compressed when the document is written. {{PDF-VERSION}} (default {{"1.3"}}) must be {{"1.3"}} or {{"1.4"}}; it sets the document's PDF version, and determines whether PDF 1.4 features such as alpha transparency (see {{build-ext-gstate}}) can be used. Signals an error if {{PDF-VERSION}} is neither. ===== with-document <macro>(with-document (DOC [COMPRESS-STREAMS? [PDF-VERSION]]) BODY ...)</macro> Binds {{DOC}} to a new document (as {{build-doc}}) for {{BODY}}, and evaluates to the finished document. ===== with-document-to-file <macro>(with-document-to-file (DOC [COMPRESS-STREAMS? [PDF-VERSION]]) FILENAME BODY ...)</macro> Like {{with-document}}, but writes the finished document to {{FILENAME}} (as {{write-document}}) instead of returning it. ===== write-document <procedure>(write-document DOC FILE [VERSION] [TRAILER-EXTRA])</procedure> Writes {{DOC}} to {{FILE}}. {{VERSION}} (default: {{DOC}}'s own PDF version, set by {{build-doc}}) is the PDF version string written to the file header; it can be overridden here independently of {{DOC}}'s version. {{TRAILER-EXTRA}} (default {{""}}) is raw text appended to the trailer dictionary, after {{/Root}}. ===== doc-compress-streams? <procedure>(doc-compress-streams? DOC)</procedure> <procedure>(doc-compress-streams?-set! DOC BOOLEAN)</procedure> Reads or sets whether {{DOC}}'s streams are compressed. ===== doc-pdf-version <procedure>(doc-pdf-version DOC)</procedure> <procedure>(doc-pdf-version-set! DOC VERSION)</procedure> Reads or sets {{DOC}}'s PDF version ({{"1.3"}} or {{"1.4"}}), as set by {{build-doc}}. ==== Building pages ===== build-page-context <procedure>(build-page-context PORT [WIDTH] [HEIGHT])</procedure> Creates and returns a new page context wrapping the output port {{PORT}}, for a page of {{WIDTH}} by {{HEIGHT}} points (defaulting to 612 by 792, i.e. US Letter). ===== with-page <macro>(with-page DOC (PAGE [WIDTH HEIGHT]) BODY ...)</macro> Binds {{PAGE}} to a new page context for {{BODY}} to draw into, then adds the finished page to {{DOC}}. {{WIDTH}} and {{HEIGHT}} default to the standard page size. ===== page-context-port <procedure>(page-context-port PAGE)</procedure> Returns the output port {{PAGE}} draws into. ===== page-width <procedure>(page-width PAGE)</procedure> <procedure>(page-height PAGE)</procedure> Return {{PAGE}}'s width or height, in points. ===== in-text-mode <macro>(in-text-mode PAGE BODY ...)</macro> Wraps {{BODY}} in a PDF text object ({{BT}}/{{ET}}) on {{PAGE}}. Text must be drawn inside {{in-text-mode}}. ===== with-graphics-state <macro>(with-graphics-state PAGE BODY ...)</macro> Saves {{PAGE}}'s graphics state, runs {{BODY}}, then restores it ({{q}}/{{Q}}). Any change {{BODY}} makes -- to color, line width, the clip region, the coordinate system, alpha, and so on -- is undone once {{BODY}} finishes. ===== with-clip <macro>(with-clip PAGE (CLIP-FORM ...) BODY ...)</macro> <macro>(with-clip PAGE even-odd (CLIP-FORM ...) BODY ...)</macro> Restricts drawing in {{BODY}} to the region enclosed by the path built by {{CLIP-FORM ...}} (a sequence of path construction operators, such as {{basic-rect}} or {{move-to}}/{{line-to}}). The region is determined by the nonzero-winding rule, or by the even-odd rule if the literal symbol {{even-odd}} is given as the second argument. Since {{with-clip}} is built on {{with-graphics-state}}, the clip region -- and any other state {{BODY}} changes -- is undone once {{BODY}} finishes. ==== Object model Lower-level procedures for constructing PDF objects directly, e.g. from a library building on top of {{pdf}}. ===== build-font <procedure>(build-font DOC BASE-FONT)</procedure> Adds a font named {{BASE-FONT}} (e.g. {{"Helvetica"}}) to {{DOC}} and returns it. ===== register-font <procedure>(register-font DOC FONT-OBJ [PREFIX])</procedure> Registers an already-built font dictionary object {{FONT-OBJ}} (see {{build-indirect-obj}} and {{build-dictionary}}) in {{DOC}}: assigns it a resource name starting with {{PREFIX}} (default {{"/CLF"}}, the same prefix {{build-font}} uses) and records it so every page's {{/Font}} resource includes it. Returns {{FONT-OBJ}}. {{build-font}} is written in terms of {{register-font}}. Call {{register-font}} directly when building a font dictionary by hand, e.g. for a font type {{build-font}} does not support. ===== font-name <procedure>(font-name FONT)</procedure> Returns the resource name {{FONT}} was assigned (for use with {{set-font}}), as a string, e.g. {{"/CLF1"}}. ===== build-ext-gstate <procedure>(build-ext-gstate DOC [FILL-ALPHA [STROKE-ALPHA [BLEND-MODE]]])</procedure> Adds a PDF 1.4 ExtGState resource to {{DOC}} and returns it, for controlling alpha transparency and blend mode in later drawing (see {{set-ext-gstate}}). {{FILL-ALPHA}} and {{STROKE-ALPHA}}, if given, are constant alpha values from {{0.0}} (fully transparent) to {{1.0}} (fully opaque), applied to fill and stroke operations respectively. {{BLEND-MODE}}, if given, is a blend mode name, e.g. {{"Multiply"}}. Signals an error unless {{DOC}} was created with PDF version {{"1.4"}} (see {{build-doc}}), since ExtGState is a PDF 1.4 feature, not part of core PDF 1.3. ===== ext-gstate-name <procedure>(ext-gstate-name EXT-GSTATE)</procedure> Returns the resource name {{EXT-GSTATE}} was assigned (for use with {{set-ext-gstate}}), as a string, e.g. {{"/GS1"}}. ===== build-indirect-obj <procedure>(build-indirect-obj DOC CONTENT [REGISTER?])</procedure> Wraps {{CONTENT}} (a dictionary or stream) as an indirect object with a freshly assigned object number, and, unless {{REGISTER?}} is {{#f}}, registers it in {{DOC}} to be written out. Returns the indirect object. ===== build-dictionary <procedure>(build-dictionary VALUES)</procedure> Returns a PDF dictionary object from {{VALUES}}, an alist of {{("/Key" . value)}} pairs. ===== build-pdf-stream <procedure>(build-pdf-stream CONTENT [EXTRA] [FORCE-UNCOMPRESSED?])</procedure> Returns a PDF stream object holding {{CONTENT}} (a string of raw bytes). {{EXTRA}} is an alist of additional dictionary entries for the stream. If {{FORCE-UNCOMPRESSED?}} is true, the stream is never compressed, regardless of {{DOC}}'s compression setting. ===== add-dictionary-item <procedure>(add-dictionary-item DICT NAME VALUE)</procedure> Adds {{NAME}}/{{VALUE}} to dictionary {{DICT}}. ===== get-obj-ref <procedure>(get-obj-ref OBJ)</procedure> Returns the PDF indirect reference (e.g. {{"3 0 R"}}) for indirect object {{OBJ}}. ===== doc-catalog <procedure>(doc-catalog DOC)</procedure> Returns {{DOC}}'s {{/Catalog}} indirect object. ===== indirect-obj-content <procedure>(indirect-obj-content OBJ)</procedure> Returns the dictionary or stream wrapped by indirect object {{OBJ}}. ===== unit-size <procedure>(unit-size)</procedure> Returns the number of points per inch (72). ==== Text operators Each operator below writes to {{PAGE}}'s content stream and must be called inside {{in-text-mode}} (except {{set-font}}, which may be called anywhere on the page). ; {{(set-font PAGE FONT-NAME SIZE)}} : selects a font and size ({{Tf}}) ; {{(move-to-next-line PAGE)}} : moves to the start of the next line ({{T*}}) ; {{(draw-text PAGE STR)}} : draws {{STR}} at the current position ({{Tj}}) ; {{(move-text PAGE DX DY)}} : moves the text position by ({{DX}}, {{DY}}) ({{Td}}) ; {{(draw-text-on-next-line PAGE STR)}} : moves to the next line and draws {{STR}} ({{'}}) ; {{(set-text-rendering-mode PAGE MODE)}} : sets the text rendering mode ({{Tr}}) ; {{(set-char-spacing PAGE SPACE)}} : sets extra character spacing ({{Tc}}) ; {{(set-text-x-scale PAGE SCALE)}} : sets horizontal text scaling ({{Tz}}) ; {{(set-text-leading PAGE SPACE)}} : sets line leading ({{TL}}) ; {{(set-text-rise PAGE RISE)}} : sets text rise (baseline offset) ({{Ts}}) ; {{(set-text-matrix PAGE A B C D E F)}} : sets the text matrix ({{Tm}}) ; {{(draw-and-adjust-string PAGE STRINGS)}} : draws {{STRINGS}}, a list mixing substrings and numeric kerning adjustments ({{TJ}}) ; {{(escape STR)}} : escapes {{(}}, {{)}}, and {{\}} in {{STR}} for use in a PDF literal string ==== Graphics state operators ; {{(rotate PAGE DEGREES)}} : rotates the coordinate system ; {{(translate PAGE DX DY)}} : translates the coordinate system ; {{(scale PAGE SX SY)}} : scales the coordinate system ; {{(set-line-width PAGE WIDTH)}} : sets the stroke line width ; {{(set-line-cap PAGE MODE)}} : sets the line cap style ; {{(set-line-join PAGE MODE)}} : sets the line join style ; {{(set-dash-pattern PAGE DASH-ARRAY PHASE)}} : sets the dash pattern ; {{(set-mitter-limit PAGE LIMIT)}} : sets the miter limit ; {{(save-graphics-state PAGE)}} : pushes the current graphics state onto a stack ({{q}}) ; {{(restore-graphics-state PAGE)}} : pops the graphics state stack, undoing changes made since the matching {{save-graphics-state}} ({{Q}}) ; {{(set-ext-gstate PAGE NAME)}} : applies a PDF 1.4 ExtGState resource built by {{build-ext-gstate}}, e.g. for alpha transparency ({{gs}}) {{save-graphics-state}} and {{restore-graphics-state}} must be correctly paired; {{with-graphics-state}} (see Building pages, above) does this automatically. ==== Path construction operators ; {{(move-to PAGE X Y)}} : starts a new subpath at ({{X}}, {{Y}}) ; {{(line-to PAGE X Y)}} : adds a straight line segment to ({{X}}, {{Y}}) ; {{(bezier-to PAGE X1 Y1 X2 Y2 X3 Y3)}} : adds a cubic Bezier curve with two control points ; {{(bezier2-to PAGE X2 Y2 X3 Y3)}} : adds a cubic Bezier curve using the current point as its first control point ; {{(bezier3-to PAGE X1 Y1 X3 Y3)}} : adds a cubic Bezier curve using the end point as its second control point ; {{(close-path PAGE)}} : closes the current subpath ; {{(basic-rect PAGE X Y DX DY)}} : adds a rectangle subpath ==== Painting operators ; {{(stroke PAGE)}} : strokes the current path ; {{(close-and-stroke PAGE)}} : closes and strokes the current path ; {{(fill-path PAGE)}} : fills the current path (nonzero winding rule) ; {{(close-and-fill PAGE)}} : closes and fills the current path ; {{(even-odd-fill PAGE)}} : fills the current path (even-odd rule) ; {{(fill-and-stroke PAGE)}} : fills then strokes the current path ; {{(even-odd-fill-and-stroke PAGE)}} : fills (even-odd rule) then strokes the current path ; {{(close-fill-and-stroke PAGE)}} : closes, fills, then strokes the current path ; {{(close-even-odd-fill-and-stroke PAGE)}} : closes, fills (even-odd rule), then strokes the current path ; {{(end-path-no-op PAGE)}} : ends the current path without painting it ; {{(clip-path PAGE)}} : intersects the clip region with the current path (nonzero winding rule) ; {{(even-odd-clip-path PAGE)}} : intersects the clip region with the current path (even-odd rule) Clipping only takes effect at the next path-painting operator (commonly {{end-path-no-op}}, if the path itself should not also be painted), and stays in effect until the graphics state is restored (see {{with-graphics-state}}). {{with-clip}} (see Building pages, above) combines all of this into one step. ==== Color operators ; {{(set-gray-stroke PAGE GRAY)}} : sets the stroke color, gray scale ; {{(set-gray-fill PAGE GRAY)}} : sets the fill color, gray scale ; {{(set-rgb-stroke PAGE R G B)}} : sets the stroke color, RGB ; {{(set-rgb-fill PAGE R G B)}} : sets the fill color, RGB ; {{(set-cymk-stroke PAGE C Y M K)}} : sets the stroke color, CMYK ; {{(set-cymk-fill PAGE C Y M K)}} : sets the fill color, CMYK ==== Geometry helpers Higher-level shapes built from the path construction operators above. ; {{+2pi+}} : the constant 2{{pi}} ; {{+pi/2+}} : the constant {{pi}}/2 ; {{(arc PAGE CX CY RADIUS START EXTENT)}} : adds an arc subpath, closed with a chord back to the center ; {{(pie PAGE CX CY RADIUS START EXTENT)}} : adds a pie-slice subpath ; {{(circle PAGE CX CY RADIUS)}} : adds a circular subpath ; {{(ellipse PAGE CX CY RADIUS-A RADIUS-B)}} : adds an elliptical subpath ; {{(rectangle PAGE X Y DX DY RADIUS)}} : adds a rectangle subpath, with rounded corners if {{RADIUS}} is nonzero ; {{(polyline PAGE POINTS RADIUS CLOSED?)}} : adds a subpath through {{POINTS}} (a list of {{(X Y)}} pairs), with corners rounded by {{RADIUS}} ; {{(regular-polygon PAGE CX CY RADIUS SIDES [FILLET-RADIUS])}} : adds a regular polygon subpath ; {{(star PAGE CX CY EXT-RADIUS INT-RADIUS SIDES [FILLET-RADIUS])}} : adds a star subpath === Examples <enscript highlight="scheme"> (import scheme (chicken base) (chicken random) (prefix pdf pdf:)) (define random pseudo-random-integer) (define-constant pi 3.14159) (define-syntax dotimes (syntax-rules () ((_ (index maxval) body ...) (do ((index 0 (+ index 1))) ((= index maxval)) body ...)))) (define (ex1) (pdf:with-document-to-file (doc) "ex1.pdf" (let ((helvetica (pdf:build-font doc "Helvetica")) (courier (pdf:build-font doc "Courier"))) (pdf:with-page doc (pg) (pdf:in-text-mode pg (pdf:set-font pg (pdf:font-name helvetica) 36) (pdf:move-text pg 100 750) (pdf:draw-text pg "scm-pdf: Example 1")) (pdf:in-text-mode pg (dotimes (i 25) (pdf:set-font pg (pdf:font-name helvetica) (* i 1.5)) (pdf:move-text pg (+ i 5) (+ i 10)) (pdf:draw-text pg "Helvetica"))) (pdf:in-text-mode pg (dotimes (i 25) (pdf:set-font pg (pdf:font-name courier) (* i 1.5)) (pdf:move-text pg (+ i 5) (- 50 (+ i 10))) (pdf:draw-text pg "Courier"))))))) (define (ex2) (pdf:with-document-to-file (doc) "ex2.pdf" (let ((helvetica (pdf:build-font doc "Helvetica"))) (pdf:with-page doc (pg) (pdf:in-text-mode pg (pdf:set-font pg (pdf:font-name helvetica) 36) (pdf:move-text pg 100 750) (pdf:draw-text pg "scm-pdf: Example 2")) (pdf:translate pg 230 500) (do ((j 0 (+ j 1)) (i 0.67 (* i 1.045))) ((= j 101)) (pdf:in-text-mode pg (pdf:set-font pg (pdf:font-name helvetica) i) (pdf:move-text pg (* i 3) 0) (pdf:draw-text pg "rotation")) (pdf:rotate pg 18))) (pdf:with-page doc (pg) (pdf:in-text-mode pg (pdf:set-font pg (pdf:font-name helvetica) 40) (pdf:move-text pg 230 500) (pdf:draw-text pg "That's All, Folks!")))))) (define (ex3) (pdf:with-document-to-file (doc) "ex3.pdf" (let ((helvetica (pdf:build-font doc "Helvetica"))) (pdf:with-page doc (pg 800 1000) (pdf:in-text-mode pg (pdf:set-font pg (pdf:font-name helvetica) 36.0) (pdf:move-text pg 100 900) (pdf:draw-text pg "scm-pdf: Example 3")) (pdf:move-to pg (+ 10 (random 500))(+ 10 (random 400))) (pdf:set-gray-fill pg 0.5) (dotimes (i 50) (pdf:line-to pg (+ 50 (random 500)) (+ 50 (random 400)))) (pdf:close-even-odd-fill-and-stroke pg) (pdf:move-to pg (+ 50 (random 500))(+ 400 (random 400))) (pdf:set-rgb-fill pg 0.5 0.5 0.8) (pdf:set-rgb-stroke pg 0.9 0.5 0.1) (dotimes (i 50) (pdf:bezier2-to pg (+ 50 (random 500)) (+ 400 (random 400)) (+ 50 (random 500)) (+ 400 (random 400)))) (pdf:close-even-odd-fill-and-stroke pg))))) (define (ex4) (pdf:with-document-to-file (doc) "ex4.pdf" (let ((helvetica (pdf:build-font doc "Helvetica"))) (pdf:with-page doc (pg) (pdf:in-text-mode pg (pdf:set-font pg (pdf:font-name helvetica) 36.0) (pdf:move-text pg 100 750) (pdf:draw-text pg "scm-pdf: Example 4")) (pdf:set-rgb-stroke pg 0.1 0.1 0.1) (pdf:set-rgb-fill pg 0.8 0.8 0.8) (let ((x 50) (y 600)) (dotimes (i 2) (pdf:rectangle pg x y 500 140 10) (pdf:close-fill-and-stroke pg) (set! y (- y 180)))) (pdf:translate pg 50 670) (let ((x 50) (y 0)) (do ((i 0 (+ i 1)) (j 8 (* j 1.05))) ((= i 4)) (pdf:set-rgb-fill pg (* 0.1 j) (* 0.01 j) (* 0.02 j)) (pdf:circle pg x y (* 4 j)) (pdf:close-fill-and-stroke pg) (pdf:ellipse pg (+ x 250) y (* 5 j) (* 4 j)) (pdf:close-fill-and-stroke pg) (set! x (+ x 50)))) (pdf:translate pg 0 -180) (pdf:regular-polygon pg 150 0 50 7 8) (pdf:close-fill-and-stroke pg) (pdf:star pg 350 0 50 30 6 5) (pdf:close-fill-and-stroke pg) (pdf:set-rgb-fill pg 0.8 0.6 0.2) (pdf:regular-polygon pg 150 0 30 5 4) (pdf:close-fill-and-stroke pg) (pdf:star pg 350 0 40 20 4 6) (pdf:close-fill-and-stroke pg) (pdf:set-rgb-fill pg 0.4 0.8 0.7) (pdf:regular-polygon pg 150 0 15 3 3) (pdf:close-fill-and-stroke pg) (pdf:star pg 350 0 35 10 12 1) (pdf:close-fill-and-stroke pg) (pdf:set-line-width pg 0.5) (do ((r 2 (+ r 2))) ((= r 100)) (pdf:set-rgb-stroke pg (* 0.01 (random 100)) (* 0.01 (random 100)) (* 0.01 (random 100))) (pdf:arc pg 250 -230 r (* pi 0.001 (random 2000)) (* pi 0.001 (random 2000))) (pdf:stroke pg)))))) ;; Demonstrates the PDF 1.4-gated features: a document built with ;; pdf-version "1.4" is required before build-ext-gstate will produce ;; alpha-transparency resources; with-clip and with-graphics-state wrap ;; the underlying W/W*/n and q/Q operators so clip regions and state ;; changes (fill color, alpha) are automatically undone afterward. (define (ex5) (pdf:with-document-to-file (doc #t "1.4") "ex5.pdf" (let ((helvetica (pdf:build-font doc "Helvetica")) (gs-half (pdf:build-ext-gstate doc 0.5)) (gs-quarter (pdf:build-ext-gstate doc 0.25 #f "/Multiply"))) (pdf:with-page doc (pg) (pdf:in-text-mode pg (pdf:set-font pg (pdf:font-name helvetica) 36) (pdf:move-text pg 100 750) (pdf:draw-text pg "scm-pdf: Example 5")) ;; Clip subsequent drawing to a rounded rectangle, then draw a row ;; of overlapping, half-transparent circles inside it; the clip ;; region and the fill color/alpha changes made here are all ;; undone once with-clip's body ends. (pdf:with-clip pg ((pdf:rectangle pg 100 400 300 300 20)) (pdf:set-rgb-fill pg 0.8 0.2 0.2) (do ((i 0 (+ i 1))) ((= i 6)) (pdf:with-graphics-state pg (pdf:set-ext-gstate pg (pdf:ext-gstate-name gs-half)) (pdf:circle pg (+ 150 (* i 40)) 550 80) (pdf:fill-path pg)))) ;; Outside the clip region, draw a second overlapping shape using ;; the other ExtGState (lower alpha, Multiply blend mode). (pdf:set-rgb-fill pg 0.2 0.2 0.8) (pdf:with-graphics-state pg (pdf:set-ext-gstate pg (pdf:ext-gstate-name gs-quarter)) (pdf:circle pg 250 250 100) (pdf:fill-path pg) (pdf:circle pg 320 250 100) (pdf:fill-path pg)))))) (ex1) (ex2) (ex3) (ex4) (ex5) </enscript>
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you add 17 to 20?