| 1 |
;;; cl-pdf copyright 2002-2003 Marc Battyani see license.txt for the details |
|---|
| 2 |
;;; You can reach me at marc.battyani@fractalconcept.com or marc@battyani.net |
|---|
| 3 |
;;; The homepage of cl-pdf is here: http://www.fractalconcept.com/asp/html/cl-pdf.html |
|---|
| 4 |
|
|---|
| 5 |
(in-package #:pdf) |
|---|
| 6 |
|
|---|
| 7 |
;;; Basic (and crude) text layout functions |
|---|
| 8 |
;;; use cl-typesetting for nice text layout functions |
|---|
| 9 |
|
|---|
| 10 |
(defconstant +section-char+ (code-char 167) |
|---|
| 11 |
"This character is not entered literally to avoid causing problems |
|---|
| 12 |
with Lisps that read source files in UTF-8 encoding.") |
|---|
| 13 |
(defvar *delimiter-chars* (list #\Space #\Tab #\Newline +section-char+)) |
|---|
| 14 |
|
|---|
| 15 |
(defun text-width (string font font-size) |
|---|
| 16 |
(loop for c across string |
|---|
| 17 |
summing (get-char-width c font font-size))) |
|---|
| 18 |
|
|---|
| 19 |
(defun split-text (string font font-size max-width) |
|---|
| 20 |
(if (> (* 2 (get-char-width #\M font font-size)) max-width) |
|---|
| 21 |
(loop for c across string |
|---|
| 22 |
collect (make-string 1 :initial-element c)) |
|---|
| 23 |
(let ((width 0) |
|---|
| 24 |
(start 0) |
|---|
| 25 |
(result ())) |
|---|
| 26 |
(loop for i from 0 |
|---|
| 27 |
for c across string |
|---|
| 28 |
for d = (get-char-width c font font-size) do |
|---|
| 29 |
(if (or (char= c #\Newline) |
|---|
| 30 |
(char= c +section-char+) |
|---|
| 31 |
(> (+ width d) max-width)) |
|---|
| 32 |
(progn |
|---|
| 33 |
(push (string-trim *delimiter-chars* (subseq string start i)) result) |
|---|
| 34 |
(setf start i width 0)) |
|---|
| 35 |
(incf width d)) |
|---|
| 36 |
finally (push (string-trim *delimiter-chars* (subseq string start)) result)) |
|---|
| 37 |
(nreverse result)))) |
|---|
| 38 |
|
|---|
| 39 |
(defun draw-centered-text (x y string font font-size &optional max-width) |
|---|
| 40 |
(pdf:in-text-mode |
|---|
| 41 |
(pdf:move-text x y) |
|---|
| 42 |
(pdf:set-font font font-size) |
|---|
| 43 |
(loop with dy = (* -1.2 font-size) |
|---|
| 44 |
for (str . rest) on (if max-width (split-text string font font-size max-width) (list string)) |
|---|
| 45 |
for last-x = 0 then offset |
|---|
| 46 |
for offset = (* -0.5 (text-width str font font-size)) do |
|---|
| 47 |
(move-text (- offset last-x) 0) |
|---|
| 48 |
(show-text str) |
|---|
| 49 |
(when rest (pdf:move-text 0 dy))))) |
|---|
| 50 |
|
|---|
| 51 |
(defun draw-left-text (x y string font font-size &optional max-width) |
|---|
| 52 |
(pdf:in-text-mode |
|---|
| 53 |
(pdf:move-text x y) |
|---|
| 54 |
(pdf:set-font font font-size) |
|---|
| 55 |
(loop with dy = (* -1.2 font-size) |
|---|
| 56 |
for (str . rest) on (if max-width (split-text string font font-size max-width) (list string)) |
|---|
| 57 |
for last-x = 0 then offset |
|---|
| 58 |
for offset = (- (text-width str font font-size)) do |
|---|
| 59 |
(move-text (- offset last-x) 0) |
|---|
| 60 |
(show-text str) |
|---|
| 61 |
(when rest (pdf:move-text 0 dy))))) |
|---|
| 62 |
|
|---|
| 63 |
(defun draw-right-text (x y string font font-size &optional max-width) |
|---|
| 64 |
(pdf:in-text-mode |
|---|
| 65 |
(pdf:move-text x y) |
|---|
| 66 |
(pdf:set-font font font-size) |
|---|
| 67 |
(loop with dy = (* -1.2 font-size) |
|---|
| 68 |
for (str . rest) on (if max-width (split-text string font font-size max-width) (list string)) |
|---|
| 69 |
do |
|---|
| 70 |
(show-text str) |
|---|
| 71 |
(when rest (move-text 0 dy))))) |
|---|