From peter at gigamonkeys.com Wed Jul 6 03:35:04 2005 From: peter at gigamonkeys.com (Peter Seibel) Date: Tue, 5 Jul 2005 20:35:04 -0700 Subject: [cl-typesetting-devel] Reusing bits of code Message-ID: I have some code that generates a logo using cl-typesetting. Now I'd like to generate documents that use that same logo in different places (and possibly even scaled). What's the best way to separate the code that sets the logo so I can reuse it in different contexts. FWIW, here's the function I used to genarate the logo: (defun logo (&optional (file "/tmp/logo.pdf")) (let ((big-font 48) (small-font 16) (extra-spacing 7)) (pdf:with-document () (pdf:with-page (:bounds (vector 0 0 612 792)) (let ((content (compile-text () (with-style (:font "Didot-Bold" :font-size big-font) (put-string "gigamonkeys")) :eol (vspace -12) (hspace 69) (with-style (:font "Optima-Regular" :font-size small-font) (loop for char across "CONSULTING" do (put-string (string char)) (typeset::add-box (make-instance 'typeset::h-spacing :dx extra-spacing :max-expansion extra-spacing :max-compression extra-spacing :expansibility 1.0 :compressibility 1.0))))))) (typeset::draw-block content 100 (- 792 100) (- 612 (* 2 100)) 100 :v-align :fill :border nil))) (pdf:write-document file)))) -Peter -- Peter Seibel * peter at gigamonkeys.com Gigamonkeys Consulting * http://www.gigamonkeys.com/ Practical Common Lisp * http://www.gigamonkeys.com/book/ From peter at gigamonkeys.com Wed Jul 6 18:27:16 2005 From: peter at gigamonkeys.com (Peter Seibel) Date: Wed, 6 Jul 2005 11:27:16 -0700 Subject: [cl-typesetting-devel] svn propset? Message-ID: I'm not sure I understand things exactly correctly but it seems that we could get subversion to take care of fixing line endings between Mac, Unix, and Windows modes on .lisp files if someone would do a find . -name '*.lisp' -exec svn propset svn:eol-style native {} \; in the cl-pdf and cl-typesetting directories and check in the change. Anyone with commit access should also, I think, edit their ~/.subversion/config file to uncomment the line: enable-auto-props = yes and add a line to the [auto-props] section like: *.lisp = svn:eol-style=native This last bit will cause new .lisp files to automatically be given the svn:eol-style property of native when they are added. This would make dealing with the cl-pdf and cl-typesetting sources a bit easier since tools like grep would work properly on source files. -Peter -- Peter Seibel * peter at gigamonkeys.com Gigamonkeys Consulting * http://www.gigamonkeys.com/ Practical Common Lisp * http://www.gigamonkeys.com/book/ From marc.battyani at fractalconcept.com Thu Jul 7 23:23:08 2005 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Fri, 8 Jul 2005 01:23:08 +0200 Subject: [cl-typesetting-devel] svn propset? References: Message-ID: <05fb01c5834a$d69dede0$0a02a8c0@marcxp> "Peter Seibel" wrote: > I'm not sure I understand things exactly correctly but it seems that > we could get subversion to take care of fixing line endings between > Mac, Unix, and Windows modes on .lisp files if someone would do a > > find . -name '*.lisp' -exec svn propset svn:eol-style native {} \; > > in the cl-pdf and cl-typesetting directories and check in the change. > Anyone with commit access should also, I think, edit their > ~/.subversion/config file to uncomment the line: > > enable-auto-props = yes > > and add a line to the [auto-props] section like: > > *.lisp = svn:eol-style=native > > This last bit will cause new .lisp files to automatically be given > the svn:eol-style property of native when they are added. > > This would make dealing with the cl-pdf and cl-typesetting sources a > bit easier since tools like grep would work properly on source files. Very good! As I use both Windows and Linux, I have been annoyed by these EOL problems too. I will try to do that tomorrow. Marc From marc.battyani at fractalconcept.com Fri Jul 8 08:31:56 2005 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Fri, 8 Jul 2005 10:31:56 +0200 Subject: [cl-typesetting-devel] Reusing bits of code References: Message-ID: <06f801c58397$814af200$0a02a8c0@marcxp> "Peter Seibel" wrote: [sorry for the late reply. I hope it's not to late...] > I have some code that generates a logo using cl-typesetting. Now I'd > like to generate documents that use that same logo in different > places (and possibly even scaled). What's the best way to separate > the code that sets the logo so I can reuse it in different contexts. > FWIW, here's the function I used to genarate the logo: > > (defun logo (&optional (file "/tmp/logo.pdf")) > (let ((big-font 48) > (small-font 16) > (extra-spacing 7)) > > (pdf:with-document () > (pdf:with-page (:bounds (vector 0 0 612 792)) > (let ((content > (compile-text () > (with-style (:font "Didot-Bold" :font-size big-font) > (put-string "gigamonkeys")) :eol > (vspace -12) > (hspace 69) > (with-style (:font "Optima-Regular" :font-size small-font) > (loop for char across "CONSULTING" do > (put-string (string char)) > (typeset::add-box > (make-instance 'typeset::h-spacing > :dx extra-spacing > :max-expansion extra-spacing > :max-compression extra-spacing > :expansibility 1.0 > :compressibility 1.0))))))) > (typeset::draw-block content 100 (- 792 100) (- 612 (* 2 100)) > 100 :v-align :fill :border nil))) > (pdf:write-document file)))) Here is how I would do it: (defun draw-logo (x y scale rotation) (let* ((big-font 48) (small-font 16) (extra-spacing 7) (content (compile-text () (with-style (:font "helvetica-bold" :font-size big-font) (put-string "gigamonkeys")) :eol (vspace -12) (hspace 69) (with-style (:font "helvetica" :font-size small-font) (loop for char across "CONSULTING" do (put-string (string char)) (typeset::add-box (make-instance 'typeset::h-spacing :dx extra-spacing :max-expansion extra-spacing :max-compression extra-spacing :expansibility 1.0 :compressibility 1.0))))))) (pdf:with-saved-state (pdf:translate x y) (pdf:scale scale scale) (pdf:rotate rotation) (typeset::draw-block content 0 0 412 100 :v-align :fill :border nil)))) Test: (defun logo (&optional (file #P"/tmp/logo.pdf")) (pdf:with-document () (pdf:with-page () (loop repeat 5 for scale = 1.0 then (* scale 0.7) for rotation from 0.0 by 20 for x from 100 by 60 for y from 692 by -120 do (draw-logo x y scale rotation))) (pdf:write-document file))) Marc -------------- next part -------------- A non-text attachment was scrubbed... Name: logo.pdf Type: application/pdf Size: 1388 bytes Desc: not available URL: From peter at gigamonkeys.com Fri Jul 8 14:20:59 2005 From: peter at gigamonkeys.com (Peter Seibel) Date: Fri, 8 Jul 2005 07:20:59 -0700 Subject: [cl-typesetting-devel] Reusing bits of code In-Reply-To: <06f801c58397$814af200$0a02a8c0@marcxp> References: <06f801c58397$814af200$0a02a8c0@marcxp> Message-ID: <17F06C5C-7299-4799-8C82-DF67B616E0BB@gigamonkeys.com> On Jul 8, 2005, at 1:31 AM, Marc Battyani wrote: > "Peter Seibel" wrote: > > [sorry for the late reply. I hope it's not to late...] Nope. Thanks. I have one question below. > Here is how I would do it: > > (defun draw-logo (x y scale rotation) > (let* ((big-font 48) > (small-font 16) > (extra-spacing 7) > (content > (compile-text () > (with-style (:font "helvetica-bold" :font-size big-font) > (put-string "gigamonkeys")) :eol > (vspace -12) > (hspace 69) > (with-style (:font "helvetica" :font-size small-font) > (loop for char across "CONSULTING" do > (put-string (string char)) > (typeset::add-box > (make-instance 'typeset::h-spacing > :dx extra-spacing > :max-expansion extra-spacing > :max-compression extra-spacing > :expansibility 1.0 > :compressibility 1.0))))))) > (pdf:with-saved-state > (pdf:translate x y) > (pdf:scale scale scale) > (pdf:rotate rotation) > (typeset::draw-block content 0 0 412 100 :v-align :fill :border > nil)))) > So how did you arrive at the values 412 and 100? Trial-and-error? -Peter -- Peter Seibel * peter at gigamonkeys.com Gigamonkeys Consulting * http://www.gigamonkeys.com/ Practical Common Lisp * http://www.gigamonkeys.com/book/ From marc.battyani at fractalconcept.com Fri Jul 8 14:51:47 2005 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Fri, 8 Jul 2005 16:51:47 +0200 Subject: [cl-typesetting-devel] Reusing bits of code References: <06f801c58397$814af200$0a02a8c0@marcxp> <17F06C5C-7299-4799-8C82-DF67B616E0BB@gigamonkeys.com> Message-ID: <089101c583cc$91f7a460$0a02a8c0@marcxp> Peter Seibel wrote: > On Jul 8, 2005, at 1:31 AM, Marc Battyani wrote: > > > "Peter Seibel" wrote: > > > > [sorry for the late reply. I hope it's not to late...] > > Nope. Thanks. I have one question below. > > > > Here is how I would do it: > > > > (defun draw-logo (x y scale rotation) > > (let* ((big-font 48) > > (small-font 16) > > (extra-spacing 7) > > (content > > (compile-text () > > (with-style (:font "helvetica-bold" :font-size big-font) > > (put-string "gigamonkeys")) :eol > > (vspace -12) > > (hspace 69) > > (with-style (:font "helvetica" :font-size small-font) > > (loop for char across "CONSULTING" do > > (put-string (string char)) > > (typeset::add-box > > (make-instance 'typeset::h-spacing > > :dx extra-spacing > > :max-expansion extra-spacing > > :max-compression extra-spacing > > :expansibility 1.0 > > :compressibility 1.0))))))) > > (pdf:with-saved-state > > (pdf:translate x y) > > (pdf:scale scale scale) > > (pdf:rotate rotation) > > (typeset::draw-block content 0 0 412 100 :v-align :fill :border > > nil)))) > > > > So how did you arrive at the values 412 and 100? Trial-and-error? It's from your original code... >(typeset::draw-block content 100 (- 792 100) (- 612 (* 2 100)) >100 :v-align :fill :border nil))) Though I made some constant folding optimization ;-) Marc From marc.battyani at fractalconcept.com Fri Jul 8 16:10:14 2005 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Fri, 8 Jul 2005 18:10:14 +0200 Subject: [cl-typesetting-devel] Reusing bits of code References: <06f801c58397$814af200$0a02a8c0@marcxp> <17F06C5C-7299-4799-8C82-DF67B616E0BB@gigamonkeys.com> <089101c583cc$91f7a460$0a02a8c0@marcxp> <3BD9B348-7A1C-484A-9CE6-8D4777678D33@gigamonkeys.com> Message-ID: <092301c583d7$87903770$0a02a8c0@marcxp> Peter Seibel wrote: > On Jul 8, 2005, at 7:51 AM, Marc Battyani wrote: > > > Peter Seibel wrote: > >> > >> So how did you arrive at the values 412 and 100? Trial-and-error? > >> > > > > It's from your original code... > > > > > >> (typeset::draw-block content 100 (- 792 100) (- 612 (* 2 100)) > >> 100 :v-align :fill :border nil))) > >> > > > > Though I made some constant folding optimization ;-) > > Duh. Okay, so my real question is, how *should* those numbers be > picked. It seems silly to draw this enormous block (I basically based > the block size on the paper size (American letter) minus some > margins. But obviously the logo doesn't actually take that much > space. But if I make the values too small it complains that it can't > fit the contents. You can get the "natural" size on some text content with something like that: (compute-boxes-natural-size (boxes (compile-text () (with-style (:font "Times-Roman") "foo"))) #'dx) 15.996 Note that this will give the width of the full text before the line breaking. Otherwise for trial and error it's useful to draw the block border to speed-up the convergence process. Marc From marc.battyani at fractalconcept.com Fri Jul 8 16:58:20 2005 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Fri, 8 Jul 2005 18:58:20 +0200 Subject: [cl-typesetting-devel] Reusing bits of code References: <06f801c58397$814af200$0a02a8c0@marcxp> <17F06C5C-7299-4799-8C82-DF67B616E0BB@gigamonkeys.com> <089101c583cc$91f7a460$0a02a8c0@marcxp> <3BD9B348-7A1C-484A-9CE6-8D4777678D33@gigamonkeys.com> <092301c583d7$87903770$0a02a8c0@marcxp> <52C31A0D-AB00-4142-9C12-3375A677592E@gigamonkeys.com> Message-ID: <098f01c583de$3f609600$0a02a8c0@marcxp> Peter Seibel wrote: > On Jul 8, 2005, at 9:10 AM, Marc Battyani wrote: > > > > Otherwise for trial and error it's useful to draw the block border to > > speed-up the convergence process. > > Okay, so that seems a bit kludgy. Let me step back and ask this: is > there any (easy) way to define a new kind of box? Since cl- > typesetting seems to all be done in terms of boxes It'd be sort of > cool if I could define a logo-box which I can then place in any > content (perhaps scaling it at the same time) and then let cl- > typesetting take care of laying it out relative to everything else. > Does that make sense? More or less... ;-) Making a special kind of box is very easy, just have a look at the simple boxes like image or colored-box for instance. But in your case you don't need to make a new kind of box, just use an user-drawn-box and provide the drawing function. Now it's using this for a logo that seems strange to me. Generally you place the logo at some fixed places on the page, not in the text. Anyway once you have a draw-logo function you can use it in a user-drawn-box as well as using it directly. > -Peter > > P.S. I was taking a look at the internals of cl-pdf and cl- > typesetting the other day and I noticed that cl-pdf contains two > variables *font* and *font-size* which, as far as I can tell, are > write-only. (Took me a while to figure that out since cl-typesetting > also has *font* and *font-size* variables that it does use. But the > cl-pdf symbols aren't exported so those are different vars. I assume > the cl-pdf ones are vestigial and perhaps should be deleted.) OK I will have a look at that. Marc From peter at gigamonkeys.com Sat Jul 9 03:08:37 2005 From: peter at gigamonkeys.com (Peter Seibel) Date: Fri, 8 Jul 2005 20:08:37 -0700 Subject: [cl-typesetting-devel] Reusing bits of code In-Reply-To: <098f01c583de$3f609600$0a02a8c0@marcxp> References: <06f801c58397$814af200$0a02a8c0@marcxp> <17F06C5C-7299-4799-8C82-DF67B616E0BB@gigamonkeys.com> <089101c583cc$91f7a460$0a02a8c0@marcxp> <3BD9B348-7A1C-484A-9CE6-8D4777678D33@gigamonkeys.com> <092301c583d7$87903770$0a02a8c0@marcxp> <52C31A0D-AB00-4142-9C12-3375A677592E@gigamonkeys.com> <098f01c583de$3f609600$0a02a8c0@marcxp> Message-ID: <75FF135A-2B75-4B50-800B-F2F8329DD182@gigamonkeys.com> On Jul 8, 2005, at 9:58 AM, Marc Battyani wrote: > Now it's using this for a logo that seems strange to me. > Generally you place the logo at some fixed places on the page, not > in the > text. Anyway once you have a draw-logo function you can use it in a > user-drawn-box as well as using it directly. Well, here's how I'm thinking of it. I've got this code to draw the logo. Now suppose I want to design an invoice. The logo is going to appear on the page somewhere and I'd like to place my address somewhere relative to the logo. Rather than figure out how big the logo is and absolutely positioning the address I'd like to be able to do something along the lines of: - create a vbox. - add the logo to the vbox - add some vspace - add my address (itself a box) to the vbox - set the vbox somewhere on the page and so on. In other words I'd like to build up the whole page out of nested vboxes and hboxes with the sub-elements perhaps being relatively involved and reusable components such as the logo. Do you see what I'm getting at? And if so, am I on crack to want to do it this way? -Peter -- Peter Seibel * peter at gigamonkeys.com Gigamonkeys Consulting * http://www.gigamonkeys.com/ Practical Common Lisp * http://www.gigamonkeys.com/book/ From peter at gigamonkeys.com Sat Jul 9 03:42:35 2005 From: peter at gigamonkeys.com (Peter Seibel) Date: Fri, 8 Jul 2005 20:42:35 -0700 Subject: [cl-typesetting-devel] More chaos Message-ID: <7BF168D5-A285-4B19-B32B-82B859B07A97@gigamonkeys.com> So, I'm playing around with user-drawn-box. Seems like what I want. But I'm getting some strange behavior. Here's some sample code: (defun user-drawn-logo (box x y) (let* ((big-font 48) (small-font 16) (extra-spacing 7)) (pdf:with-saved-state (pdf:translate x y) (pdf:scale (/ (typeset::dx box) 290) (/ (typeset::dy box) 80)) (draw-block (compile-text () (with-style (:font "Didot-Bold" :font-size big-font) (put- string "gigamonkeys")) :eol (vspace -2) (hspace 69) (with-style (:font "Optima-Regular" :font-size small-font) (loop for char across "CONSULTING" do (put-string (string char)) (unless (char= char #\G) (typeset::add-box (make-instance 'typeset::h-spacing :dx extra-spacing :max-expansion extra-spacing :max-compression extra-spacing :expansibility 1.0 :compressibility 1.0)))))) 0 0 290 80 :border 0.1)))) (defun foo-logo (&optional (file "/tmp/logo.pdf")) (pdf:with-document () (pdf:with-page (:bounds (vector 0 0 612 792)) (draw-block (compile-text () (user-drawn-box :dx 290 :dy 80 :stroke-fn 'user-drawn-logo) (user-drawn-box :dx 290/2 :dy 80/2 :stroke-fn 'user-drawn-logo)) 100 692 412 100)) (pdf:write-document file))) I'd expect this to draw a page with two copies of the logo, one full size and one half size. But it doesn't. And stranger yet, if I (trace user-drawn-logo) I only see it getting called once. *But* if I change the :dx and :dy arguments in the first call to user-drawn-box to 290/2 and 80/2, then it gets called twice and I get two half-size logos. What's up with that? Another odditity is that in user-drawn-logo I had to change the argument to the VSPACE call after I set "gigamonkeys" to -2 rather than -12 as it was in my old code, to get the "CONSULTING" to come out in the right place. Any ideas why that might be? -Peter -- Peter Seibel * peter at gigamonkeys.com Gigamonkeys Consulting * http://www.gigamonkeys.com/ Practical Common Lisp * http://www.gigamonkeys.com/book/ From peter at gigamonkeys.com Sat Jul 9 03:59:27 2005 From: peter at gigamonkeys.com (Peter Seibel) Date: Fri, 8 Jul 2005 20:59:27 -0700 Subject: [cl-typesetting-devel] More chaos In-Reply-To: <7BF168D5-A285-4B19-B32B-82B859B07A97@gigamonkeys.com> References: <7BF168D5-A285-4B19-B32B-82B859B07A97@gigamonkeys.com> Message-ID: <15A3CF62-9C5A-49C1-8478-4F183AC90F05@gigamonkeys.com> On Jul 8, 2005, at 8:42 PM, Peter Seibel wrote: > So, I'm playing around with user-drawn-box. Seems like what I want. > But I'm getting some strange behavior. Bah, never mind on the first question, the box I was drowing the whole thing in had too small a dy. I am, however, still curious why I needed to change the VSPACE to get the right positioning. -Peter -- Peter Seibel * peter at gigamonkeys.com Gigamonkeys Consulting * http://www.gigamonkeys.com/ Practical Common Lisp * http://www.gigamonkeys.com/book/ From peter at gigamonkeys.com Sat Jul 9 04:17:16 2005 From: peter at gigamonkeys.com (Peter Seibel) Date: Fri, 8 Jul 2005 21:17:16 -0700 Subject: [cl-typesetting-devel] Reusing bits of code In-Reply-To: <092301c583d7$87903770$0a02a8c0@marcxp> References: <06f801c58397$814af200$0a02a8c0@marcxp> <17F06C5C-7299-4799-8C82-DF67B616E0BB@gigamonkeys.com> <089101c583cc$91f7a460$0a02a8c0@marcxp> <3BD9B348-7A1C-484A-9CE6-8D4777678D33@gigamonkeys.com> <092301c583d7$87903770$0a02a8c0@marcxp> Message-ID: On Jul 8, 2005, at 9:10 AM, Marc Battyani wrote: > You can get the "natural" size on some text content with something > like > that: > > (compute-boxes-natural-size > (boxes (compile-text () > (with-style (:font "Times-Roman") "foo"))) #'dx) > 15.996 Okay, more puzzles. Why does this function: (defun measure-logo () (let* ((big-font 48) (small-font 16) (extra-spacing 7) (content (compile-text () (with-style (:font "Didot-Bold" :font-size big-font) (put- string "gigamonkeys")) :eol (vspace -2) (hspace 69) (with-style (:font "Optima-Regular" :font-size small-font) (loop for char across "CONSULTING" do (put-string (string char)) (unless (char= char #\G) (typeset::add-box (make-instance 'typeset::h-spacing :dx extra-spacing :max-expansion extra-spacing :max-compression extra-spacing :expansibility 1.0 :compressibility 1.0)))))))) (values (typeset::compute-boxes-natural-size (boxes content) #'typeset::dx) (typeset::compute-boxes-natural-size (boxes content) #'typeset::dy)))) return 521.12006 823.6001 The logo is *not* bigger than a piece of 8.5x11 paper! -Peter -- Peter Seibel * peter at gigamonkeys.com Gigamonkeys Consulting * http://www.gigamonkeys.com/ Practical Common Lisp * http://www.gigamonkeys.com/book/ From peter at gigamonkeys.com Wed Jul 13 16:28:01 2005 From: peter at gigamonkeys.com (Peter Seibel) Date: Wed, 13 Jul 2005 09:28:01 -0700 Subject: [cl-typesetting-devel] How does rotation work? Message-ID: I'm trying to set set a block of text rotated 90 degrees but the rotation seems to rotate the box right off the page. Around what axis does pdf:rotate rotate stuff? Or more to the point, what's the easiest way to draw a block at a particular place but rotated 90 degrees? -Peter -- Peter Seibel * peter at gigamonkeys.com Gigamonkeys Consulting * http://www.gigamonkeys.com/ Practical Common Lisp * http://www.gigamonkeys.com/book/ From peter at gigamonkeys.com Thu Jul 14 19:06:24 2005 From: peter at gigamonkeys.com (Peter Seibel) Date: Thu, 14 Jul 2005 12:06:24 -0700 Subject: [cl-typesetting-devel] Reusing bits of code In-Reply-To: References: <06f801c58397$814af200$0a02a8c0@marcxp> <17F06C5C-7299-4799-8C82-DF67B616E0BB@gigamonkeys.com> <089101c583cc$91f7a460$0a02a8c0@marcxp> <3BD9B348-7A1C-484A-9CE6-8D4777678D33@gigamonkeys.com> <092301c583d7$87903770$0a02a8c0@marcxp> Message-ID: <44B54333-C857-4404-A4A8-B27311E4E44A@gigamonkeys.com> On Jul 8, 2005, at 9:17 PM, Peter Seibel wrote: > > On Jul 8, 2005, at 9:10 AM, Marc Battyani wrote: > > >> You can get the "natural" size on some text content with something >> like >> that: >> >> (compute-boxes-natural-size >> (boxes (compile-text () >> (with-style (:font "Times-Roman") "foo"))) #'dx) >> 15.996 >> > > Okay, more puzzles. Why does this function: > > (defun measure-logo () > (let* ((big-font 48) > (small-font 16) > (extra-spacing 7) > (content > (compile-text () > (with-style (:font "Didot-Bold" :font-size big-font) (put- > string "gigamonkeys")) :eol > (vspace -2) > (hspace 69) > (with-style (:font "Optima-Regular" :font-size small-font) > (loop for char across "CONSULTING" do > (put-string (string char)) > (unless (char= char #\G) > (typeset::add-box > (make-instance 'typeset::h-spacing > :dx extra-spacing > :max-expansion extra-spacing > :max-compression extra-spacing > :expansibility 1.0 > :compressibility 1.0)))))))) > (values > (typeset::compute-boxes-natural-size (boxes content) > #'typeset::dx) > (typeset::compute-boxes-natural-size (boxes content) > #'typeset::dy)))) > > return > > 521.12006 > 823.6001 > > The logo is *not* bigger than a piece of 8.5x11 paper! So, I figured this one out. Sort of. The problem is that compute- boxes-natural-size simply sums the values returned by the size-fn (dx or dy here). Which means that if you have CHAR-BOX, CHAR-BOX, :EOL, CHAR-BOX, CHAR-BOX the "natural" width is the sum of the widths of the four char-boxes even though there's a line break. Similarly, the height is even more off because it sums the heights of a bunch of boxes that are actually all in a row. Here are two functions that seem to more or less do what I want though I'm not sure if I've dealt with all the edge cases: (defun natural-width (content) (loop with max-width = 0 with current-width = 0 for box in (boxes content) for dx = (typeset::dx box) when (eql box :eol) do (setf current-width 0) do (incf current-width dx) do (setf max-width (max current-width max-width)) finally (return max-width))) (defun natural-height (content) (loop with max-height = 0 with total-height = 0 for box in (boxes content) for dy = (typeset::dy box) when (eql box :eol) do (incf total-height (* typeset::*leading-ratio* max-height)) (setf max-height 0) do (setf max-height (max max-height dy)) finally (return total-height))) This lets me write a function like this to position a block of text in the middle of a page at its natural size: (defun small-envelope (&optional (address *gigamonkeys*) (file "/tmp/ small-envelope.pdf")) (pdf:with-document () (pdf:with-page (:bounds (vector 0 0 *small-envelope-width* *small-envelope-height*)) (let* ((content (compile-text () (with-style (:font "Optima-Regular" :font-size 12) (paragraph () (loop for line in address do (put-string line) (typeset::add-box :eol)))))) (width (natural-width content)) (height (natural-height content)) (x (/ (- *small-envelope-width* width) 2)) (y (- *small-envelope-height* (/ (- *small-envelope-height* height) 2)))) (draw-block content x y width height))) (pdf:write-document file))) If there's an easier way to do this, I'd be glad to hear it. -Peter -- Peter Seibel * peter at gigamonkeys.com Gigamonkeys Consulting * http://www.gigamonkeys.com/ Practical Common Lisp * http://www.gigamonkeys.com/book/ From marc.battyani at fractalconcept.com Wed Jul 20 17:25:51 2005 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Wed, 20 Jul 2005 19:25:51 +0200 Subject: [cl-typesetting-devel] How does rotation work? References: Message-ID: <037101c58d50$192fcbb0$0a02a8c0@marcxp> Peter Seibel wrote: Hi Peter, Sorry for the long reply delay, I'm just coming back from backpacking in the Alps :-) > I'm trying to set set a block of text rotated 90 degrees but the > rotation seems to rotate the box right off the page. Around what axis > does pdf:rotate rotate stuff? Or more to the point, what's the > easiest way to draw a block at a particular place but rotated 90 > degrees? You can use the rotation parameter of draw-block. The rotation is around the top left corner of the block IIRC. Marc From peter at gigamonkeys.com Wed Jul 20 17:30:00 2005 From: peter at gigamonkeys.com (Peter Seibel) Date: Wed, 20 Jul 2005 10:30:00 -0700 Subject: [cl-typesetting-devel] How does rotation work? In-Reply-To: <037101c58d50$192fcbb0$0a02a8c0@marcxp> References: <037101c58d50$192fcbb0$0a02a8c0@marcxp> Message-ID: On Jul 20, 2005, at 10:25 AM, Marc Battyani wrote: > Peter Seibel wrote: > > Hi Peter, > > Sorry for the long reply delay, I'm just coming back from > backpacking in the > Alps :-) > > >> I'm trying to set set a block of text rotated 90 degrees but the >> rotation seems to rotate the box right off the page. Around what axis >> does pdf:rotate rotate stuff? Or more to the point, what's the >> easiest way to draw a block at a particular place but rotated 90 >> degrees? >> > > You can use the rotation parameter of draw-block. The rotation is > around the > top left corner of the block IIRC. Actually I think the rotation is around 0,0. So the trick is to use pdf:translate to translate the coordinate system to where you want the top left corner of the box to be and then draw-block at 0, 0 with whatever rotation you want. But if you draw-block at some x,y with a rotation it requires advanced trig to figure out where the box is actually going to end up. At least it seems that way to my math impaired brain. -Peter -- Peter Seibel * peter at gigamonkeys.com Gigamonkeys Consulting * http://www.gigamonkeys.com/ Practical Common Lisp * http://www.gigamonkeys.com/book/ From marc.battyani at fractalconcept.com Wed Jul 20 17:38:26 2005 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Wed, 20 Jul 2005 19:38:26 +0200 Subject: [cl-typesetting-devel] How does rotation work? References: <037101c58d50$192fcbb0$0a02a8c0@marcxp> Message-ID: <038601c58d51$d6ce5140$0a02a8c0@marcxp> Peter Seibel wrote: > On Jul 20, 2005, at 10:25 AM, Marc Battyani wrote: > > > Peter Seibel wrote: > > > > Hi Peter, > > > > Sorry for the long reply delay, I'm just coming back from > > backpacking in the > > Alps :-) > > > >> I'm trying to set set a block of text rotated 90 degrees but the > >> rotation seems to rotate the box right off the page. Around what axis > >> does pdf:rotate rotate stuff? Or more to the point, what's the > >> easiest way to draw a block at a particular place but rotated 90 > >> degrees? > >> > > > > You can use the rotation parameter of draw-block. The rotation is > > around the > > top left corner of the block IIRC. > > Actually I think the rotation is around 0,0. So the trick is to use > pdf:translate to translate the coordinate system to where you want > the top left corner of the box to be and then draw-block at 0, 0 with > whatever rotation you want. But if you draw-block at some x,y with a > rotation it requires advanced trig to figure out where the box is > actually going to end up. At least it seems that way to my math > impaired brain. No, draw-block already does the translate + rotation: ;;; from top-level.lisp (defmethod draw-block (content x y dx dy &key border (padding 5) rotation (v-align :top) special-fn) (pdf:with-saved-state (pdf:translate x y) (when rotation (pdf:rotate rotation)) ... Marc From peter at gigamonkeys.com Wed Jul 20 17:47:08 2005 From: peter at gigamonkeys.com (Peter Seibel) Date: Wed, 20 Jul 2005 10:47:08 -0700 Subject: [cl-typesetting-devel] How does rotation work? In-Reply-To: <038601c58d51$d6ce5140$0a02a8c0@marcxp> References: <037101c58d50$192fcbb0$0a02a8c0@marcxp> <038601c58d51$d6ce5140$0a02a8c0@marcxp> Message-ID: <12F0CE29-583F-49CE-A4FA-97E456870931@gigamonkeys.com> On Jul 20, 2005, at 10:38 AM, Marc Battyani wrote: > Peter Seibel wrote: > >> On Jul 20, 2005, at 10:25 AM, Marc Battyani wrote: >> >> >>> Peter Seibel wrote: >>> >>> Hi Peter, >>> >>> Sorry for the long reply delay, I'm just coming back from >>> backpacking in the >>> Alps :-) >>> >>> >>>> I'm trying to set set a block of text rotated 90 degrees but the >>>> rotation seems to rotate the box right off the page. Around what >>>> axis >>>> does pdf:rotate rotate stuff? Or more to the point, what's the >>>> easiest way to draw a block at a particular place but rotated 90 >>>> degrees? >>>> >>>> >>> >>> You can use the rotation parameter of draw-block. The rotation is >>> around the >>> top left corner of the block IIRC. >>> >> >> Actually I think the rotation is around 0,0. So the trick is to use >> pdf:translate to translate the coordinate system to where you want >> the top left corner of the box to be and then draw-block at 0, 0 with >> whatever rotation you want. But if you draw-block at some x,y with a >> rotation it requires advanced trig to figure out where the box is >> actually going to end up. At least it seems that way to my math >> impaired brain. >> > > No, draw-block already does the translate + rotation: > > ;;; from top-level.lisp > > (defmethod draw-block (content x y dx dy > &key border (padding 5) rotation (v-align :top) > special-fn) > (pdf:with-saved-state > (pdf:translate x y) > (when rotation > (pdf:rotate rotation)) > ... Hmmm. I'll have to look back at my code when I get a chance. I got it working but I seem to recall having to manage the translation myself. -Peter -- Peter Seibel * peter at gigamonkeys.com Gigamonkeys Consulting * http://www.gigamonkeys.com/ Practical Common Lisp * http://www.gigamonkeys.com/book/ From marc.battyani at fractalconcept.com Wed Jul 20 19:55:24 2005 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Wed, 20 Jul 2005 21:55:24 +0200 Subject: [cl-typesetting-devel] Reusing bits of code References: <06f801c58397$814af200$0a02a8c0@marcxp><17F06C5C-7299-4799-8C82-DF67B616E0BB@gigamonkeys.com><089101c583cc$91f7a460$0a02a8c0@marcxp><3BD9B348-7A1C-484A-9CE6-8D4777678D33@gigamonkeys.com><092301c583d7$87903770$0a02a8c0@marcxp> <44B54333-C857-4404-A4A8-B27311E4E44A@gigamonkeys.com> Message-ID: <03ae01c58d64$f88eeed0$0a02a8c0@marcxp> Peter Seibel wrote: > On Jul 8, 2005, at 9:17 PM, Peter Seibel wrote: > > So, I figured this one out. Sort of. The problem is that compute- > boxes-natural-size simply sums the values returned by the size-fn (dx > or dy here). Which means that if you have CHAR-BOX, CHAR-BOX, :EOL, > CHAR-BOX, CHAR-BOX the "natural" width is the sum of the widths of > the four char-boxes even though there's a line break. Similarly, the > height is even more off because it sums the heights of a bunch of > boxes that are actually all in a row. Here are two functions that > seem to more or less do what I want though I'm not sure if I've dealt > with all the edge cases: > > (defun natural-width (content) > (loop with max-width = 0 > with current-width = 0 > for box in (boxes content) > for dx = (typeset::dx box) > when (eql box :eol) do (setf current-width 0) > do (incf current-width dx) > do (setf max-width (max current-width max-width)) > finally (return max-width))) > > (defun natural-height (content) > (loop with max-height = 0 > with total-height = 0 > for box in (boxes content) > for dy = (typeset::dy box) > when (eql box :eol) do > (incf total-height (* typeset::*leading-ratio* max-height)) > (setf max-height 0) > do (setf max-height (max max-height dy)) > finally (return total-height))) > > This lets me write a function like this to position a block of text > in the middle of a page at its natural size: > > (defun small-envelope (&optional (address *gigamonkeys*) (file "/tmp/ > small-envelope.pdf")) > (pdf:with-document () > (pdf:with-page (:bounds (vector 0 0 *small-envelope-width* > *small-envelope-height*)) > (let* ((content (compile-text () > (with-style (:font "Optima-Regular" :font-size 12) > (paragraph () > (loop for line in address do > (put-string line) > (typeset::add-box :eol)))))) > (width (natural-width content)) > (height (natural-height content)) > (x (/ (- *small-envelope-width* width) 2)) > (y (- *small-envelope-height* (/ (- *small-envelope-height* > height) 2)))) > (draw-block content x y width height))) > (pdf:write-document file))) > > If there's an easier way to do this, I'd be glad to hear it. The problem here is that you are only implementing a small part of the function that cuts the content into lines. So this will work only on small lines without any breaks. In your case, as this is what you want, it's OK. I would rather do this: Make a vbox with #'make-filled-vbox by giving it large dx and dy values. Then use #'compute-boxes-natural-size with #'dy to get the height and a reduce #'max of #'compute-boxes-natural-size on #'dx of the lines boxes. Hum.... I'm not sure I'm very clear ;-) Marc