Description
A library for PDF generation.
Author
Marc Battyani and Bruce Butterfield
Maintainer
Repository
This egg is hosted on the CHICKEN Subversion repository:
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 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.
Building documents
build-doc
[procedure] (build-doc [COMPRESS-STREAMS?])Creates and returns a new, empty document. COMPRESS-STREAMS? (default #t) sets whether streams are compressed when the document is written.
with-document
[syntax] (with-document (DOC [COMPRESS-STREAMS?]) BODY ...)Binds DOC to a new document (as build-doc) for BODY, and evaluates to the finished document.
with-document-to-file
[syntax] (with-document-to-file (DOC [COMPRESS-STREAMS?]) FILENAME BODY ...)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])Writes DOC to FILE. VERSION (default "1.3") is the PDF version string. TRAILER-EXTRA (default "") is raw text appended to the trailer dictionary, after /Root.
doc-compress-streams?
[procedure] (doc-compress-streams? DOC)[procedure] (doc-compress-streams?-set! DOC BOOLEAN)
Reads or sets whether DOC's streams are compressed.
Building pages
build-page-context
[procedure] (build-page-context PORT [WIDTH] [HEIGHT])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
[syntax] (with-page DOC (PAGE [WIDTH HEIGHT]) BODY ...)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)Returns the output port PAGE draws into.
page-width
[procedure] (page-width PAGE)[procedure] (page-height PAGE)
Return PAGE's width or height, in points.
in-text-mode
[syntax] (in-text-mode PAGE BODY ...)Wraps BODY in a PDF text object (BT/ET) on PAGE. Text must be drawn inside in-text-mode.
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)Adds a font named BASE-FONT (e.g. "Helvetica") to DOC and returns it.
font-name
[procedure] (font-name FONT)Returns the resource name FONT was assigned (for use with set-font), as a string, e.g. "/CLF1".
build-indirect-obj
[procedure] (build-indirect-obj DOC CONTENT [REGISTER?])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)Returns a PDF dictionary object from VALUES, an alist of ("/Key" . value) pairs.
build-pdf-stream
[procedure] (build-pdf-stream CONTENT [EXTRA] [FORCE-UNCOMPRESSED?])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)Adds NAME/VALUE to dictionary DICT.
get-obj-ref
[procedure] (get-obj-ref OBJ)Returns the PDF indirect reference (e.g. "3 0 R") for indirect object OBJ.
doc-catalog
[procedure] (doc-catalog DOC)Returns DOC's /Catalog indirect object.
indirect-obj-content
[procedure] (indirect-obj-content OBJ)Returns the dictionary or stream wrapped by indirect object OBJ.
unit-size
[procedure] (unit-size)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
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)
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 2pi
- +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
(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)))))) (ex1) (ex2) (ex3) (ex4)