[cl-pdf-devel] Simple patch for draw-...-text

Andrey Moskvitin archimag at gmail.com
Wed Apr 29 12:12:35 UTC 2009


Hi,

I apologize for the long silence, was strongly engaged.

> Anyway, it's an interesting feature so could you rework its
implementation?
Well, I agree, this is a new version.

Andrey

---

diff --git a/text.lisp b/text.lisp
 index 8fbddf3..4c695d4 100644
--- a/text.lisp
+++ b/text.lisp
@@ -16,56 +16,71 @@ with Lisps that read source files in UTF-8 encoding.")
    (loop for c across string
     summing (get-char-width c font font-size)))

-(defun split-text (string font font-size max-width)
-  (if (> (* 2 (get-char-width #\M font font-size)) max-width)
-      (loop for c across string
 -        collect (make-string 1 :initial-element c))
-      (let ((width 0)
-        (start 0)
-        (result ()))
-    (loop for i from 0
-          for c across string
-          for d = (get-char-width c font font-size) do
 -          (if (or (char= c #\Newline)
-                      (char= c +section-char+)
-                      (> (+ width d) max-width))
-          (progn
-            (push (string-trim *delimiter-chars* (subseq string start i))
result)
 -            (setf start i width 0))
-          (incf width d))
-          finally (push (string-trim *delimiter-chars* (subseq string
start)) result))
-    (nreverse result))))
+(defun split-text (string font font-size max-width &optional max-height)
 +  (let ((max-line-number (if max-height
+                             (floor (+ max-height (* 0.2 font-size))
+                                    (* 1.2 font-size))))
+        (current-line-number 1))
+    (flet ((check-max-number-of-lines ()
 +             (and max-line-number
+                  (< max-line-number
+                     (prog1
+                         current-line-number
+                       (incf current-line-number))))))
 +      (if (> (* 2 (get-char-width #\M font font-size)) max-width)
+          (loop for c across string
+                until (check-max-number-of-lines)
+                collect (string c))
+          (let ((width 0)
 +                (start 0)
+                (result ()))
+            (loop with max-number-of-lines = (and max-line-number (<
max-line-number current-line-number))
+                  until max-number-of-lines
 +                  for i from 0
+                  for c across string
+                  for d = (get-char-width c font font-size) do
+                  (if (or (char= c #\Newline)
+                          (char= c +section-char+)
 +                          (> (+ width d) max-width))
+                      (progn
+                        (push (string-trim *delimiter-chars* (subseq string
start i)) result)
+                        (setf start i width 0)
 +                        (setf max-number-of-lines
(check-max-number-of-lines)))
+                      (incf width d))
+                  finally (unless max-number-of-lines
+                            (push (string-trim *delimiter-chars* (subseq
string start)) result)))
 +            (nreverse result))))))

-(defun draw-centered-text (x y string font font-size &optional max-width)
+(defun draw-centered-text (x y string font font-size &optional max-width
max-height)
   (pdf:in-text-mode
     (pdf:move-text x y)
    (pdf:set-font font font-size)
    (loop with dy = (* -1.2 font-size)
-     for (str . rest) on (if max-width (split-text string font font-size
max-width) (list string))
+     for (str . rest) on (if max-width (split-text string font font-size
max-width max-height) (list string))
       for last-x = 0 then offset
      for offset = (* -0.5 (text-width str font font-size)) do
      (move-text (- offset last-x) 0)
      (show-text str)
      (when rest (pdf:move-text 0 dy)))))

-(defun draw-left-text (x y string font font-size &optional max-width)
+(defun draw-left-text (x y string font font-size &optional max-width
max-height)
   (pdf:in-text-mode
    (pdf:move-text x y)
    (pdf:set-font font font-size)
    (loop with dy = (* -1.2 font-size)
-     for (str . rest) on (if max-width (split-text string font font-size
max-width) (list string))
 +     for (str . rest) on (if max-width (split-text string font font-size
max-width max-height) (list string))
      for last-x = 0 then offset
      for offset = (- (text-width str font font-size)) do
      (move-text (- offset last-x) 0)
       (show-text str)
      (when rest (pdf:move-text 0 dy)))))

-(defun draw-right-text (x y string font font-size &optional max-width)
+(defun draw-right-text (x y string font font-size &optional max-width
max-height)
   (pdf:in-text-mode
    (pdf:move-text x y)
    (pdf:set-font font font-size)
    (loop with dy = (* -1.2 font-size)
-     for (str . rest) on (if max-width (split-text string font font-size
max-width) (list string))
 +     for (str . rest) on (if max-width (split-text string font font-size
max-width max-height) (list string))
      do
      (show-text str)
      (when rest (move-text 0 dy)))))


2009/3/29 Marc Battyani <marc.battyani at fractalconcept.com>

>  Hi Andrey,
>
> This is a very good idea but I think it needs some polish. :)
>
> Having a while clause before for clauses is not compliant even if most loop
> implementations are OK with this.
>
> Using a line count and then multiplying by dy at each iteration is not very
> efficient, it would be better to have a current-height and add dy at each
> iteration or even simply to substract dy from max-height until it goes
> negative (with a default huge value for max-height)
>
> BTW as the draw-...-text functions all call split text, in fact it would be
> much more efficient to limit the number of lines directly in split-text.
> After all what is the point of splitting a text in n lines if we only want 2
> lines for instance.
>
> Anyway, it's an interesting feature so could you rework its implementation?
>
> Thanks,
>
> Marc
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/cl-pdf-devel/attachments/20090429/6b754bc8/attachment.html>


More information about the cl-pdf-devel mailing list