(archive 'newLISPer)

October 5, 2007

Jack the Glypher

Filed under: newLISP — newlisper @ 17:41

After looking into captchas and FIGlets a few weeks go, I spent a little time wondering about doing something similar in newLISP. I didn’t feel able to rewrite the FIGlet code completely, so I did some investigation of easier alternatives. In a burst of wanton glyphomania, I ended up with code that produced this. I’ve put them vertically because this layout won’t like them horizontally:

    $$$$$$$$      s$$$$$$$$$$$$$      
    $$$$$$$$$$$$$$$$$$$+  t$$$$$$$$7  
    $$$$$$$$$$$$            #$$$$$$$  
    $$$$$$$$&               $$$$$$$$  
   #$$$$$$$6                #$$$$$$$+ 
   #$$$$$$$-                 $$$$$$$$8
    $$$$$$$                   $$$$$$$$




              @$$$$$$$$$$$$$$%           
      %$$$$$$$$$$$o     6@$$$$$$$$$$.    
   $$$$$$$$            i$$$$$$$$$$$$     
  $$$$$$86$$$$$$$$$$$$$$$$               
  $$$$$$$$$$x                            
    $$$$$$$$$$$$            0$$$$$$$$$$$7
            &$$$$$$$$$$$$$$$$$$o         




  @$$$$$               i$$$$s               $$$$$$
 t$$$$$$$$          i$$$$$$$$$$           $$$$$$$$
  #$$$$$$$+       0$$$$$$$$$$$$$        t$$$$$$$s 
   o$$$$$$$6    @$$$$$$#  #$$$$$$6     $$$$$$$@   
    &$$$$$$$  $$$$$$$      0$$$$$$-  6$$$$$$$     
      $$$$$$$$$$$$7         -$$$$$$$$$$$$$$       
        $$$$$$$$               $$$$$$$$$          




      $$$$                               
    $$$$$$$$                             
    $$$$$$$$                             
    $$$$$$$$                             
    $$$$$$$$                             
   o$$$$$$$8                             
   $$$$$$$$.                             
   $$$$$$$@                              
  $$$$$$$$               6$$$$$$$$$$$$$$$
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$&       




 #$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
               $$$$$$$$                 
              &$$$$$$$%                 
              $$$$$$$$+                 
              $$$$$$$$+                 
              s$$$$$$$8                 
              :$$$$$$$@                 
    0$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$  
   $$$$$$$$$$$$$@8t=                    



                  %$$$$$$$$$$$$$$$$$$$$$$$$$$$8   
           $$$$$$$$$$6                            
        t$$$$$$$$#                                
          $$$$$$$$$$$$$$$$$$$$$$$$$$@o            
                              -s$$$$$$$$$$$$$$$7  
                                         0$$$$$$$$
      $$$                                $$$$$$$$$
    $$$$$$$$$$$$+               @$$$$$$$$$$$$$    
            x$$$$$$$$$$$$$$$$$$$$$$$              




     $$$$$$$$$$$$$$$$$$$$$            
    $$$$$$$+        0$$$$$$$$$$$$$    
    $$$$$$$                   $$$$$$$@
   o$$$$$$$                   $$$$$$$%
   $$$$$$$+             7$$$$$$$$$$.  
  o$$$$$$$$$$$$$$$$$$$$$$$$$:         
  $$$$$$$$                            
  $$$$$$$$                            
  $$$$$$$@                            
   :$$$$

For the typophiles everywhere, this is a nightmare world of tortured type and screaming serifs. Those elegant Bezier curves have just been reduced to jagged outlines. On the bright side, this was Comic Sans MS, the most hated font on the internet, so perhaps the typophiles won’t mind too much. (Anyway, it didn’t work well with Bodoni.)

The task of generating these letters involves a couple of stages. The first is to create the fonts; the second is to feed in the string that you want to display and produce the ASCII output. Of the two, the first is much more interesting.

The hard work is done by a clever little program I found on Apple’s web site, the ASCIIMoviePlayer. This is a small command-line application that interfaces with QuickTime (MacOS X and Windows only, I think) and outputs any QuickTime compatible file in ASCII format. It does movies – I’ll watch Crouching Tiger, Hidden Dragon in ASCII format next week – but any compatible image is OK too.

After making a few changes, I was ready to write the newLISP wrapper that attacks those innocent fonts and leaves the mangled letters behind.

So, here’s the script – Jack the Glypher:

(load (append (env "NEWLISPDIR") "/guiserver.lsp"))

(set 'font {Comic Sans MS} 'font-size 200  )

(define (trim-glyph glyph)
  ; strip off the white space fore and aft
  (set 'height (length glyph) 'width (length (first glyph)))
  ; find the line with the fewest spaces at the end
  (set 'longest 0)
  (dolist (row glyph)
    (set 'longest (max longest (length (trim row "" " ")))))
  ; trim all lines to the longest
  (dolist (row glyph)
    (nth-set (glyph $idx) (chop row (- (length row) longest))))
  glyph
) 

(gs:init)
(set 'window-height 400)
(gs:window 'Glypher 200 200 200 window-height)
(gs:set-background 'Glypher 1 0 1)
(gs:panel 'GlyphPanel)

(gs:set-grid-layout 'GlyphPanel 1 1 0 0)
(gs:canvas 'glyph)
(gs:set-background 'glyph 0 0 0)

(gs:add-to 'GlyphPanel 'glyph)
(gs:add-to 'Glypher 'GlyphPanel)

(gs:set-visible 'Glypher true)
(gs:set-font 'glyph font font-size)
(gs:set-paint '(1 1 1))

(set 'start-char 32)
(map set '(x y)  (gs:get-font-metrics 'glyph {g}))

(set 'context-name (string (replace { } font "") font-size))

(while (< start-char 127)
  (gs:draw-text 'glyphchar (char start-char) 0 200)
  (gs:update)
  (set 'temp-file (string "/tmp/" {glyph} (string start-char) {.png}))
  (gs:export temp-file)
  (set 'ascii-glyph (exec (string {/usr/local/bin/ASCIIMoviePlayer } temp-file)))
  (set 'ascii-glyph (trim-glyph ascii-glyph))
  (context (sym context-name) (string {glyph} start-char) ascii-glyph)
  (inc 'start-char)
  (gs:delete-tag 'glyphchar))

; save and disappear into the night
(context (sym context-name) {height} (length ascii-glyph)) ; height, last one will do
(save (string (env {HOME}) {/Desktop/ascii-} context-name {.lsp}) (sym context-name))
(exit)

This is a newLISP-GS script that produces a series of PNG files of individual letters, runs then through a hacked version of ASCIIMoviePlayer, and then saves the resulting text files in a newLISP context.

The context file starts out like this:

(context 'ComicSansMS200)

(set 'glyph100 '(
  "                                            " 
  "                                            " 
  "                                            " 
  "                                    $$$$$$$s" 
  "                                    $$$$$$$6" 
  "                                   #$$$$$$$ " 
  "                 8$$$$$$$$$$$$$    $$$$$$$  " 
  "        ,$$$$$$$$$$$$$s7it%$$$$$$$$$$$$$$$  " 
  "     7$$$$$$$                     $$$$$$$@  " 
  "    $$$$$$$@                      $$$$$$$8  " 
  "    ;$$$$$$$.                     $$$$$$$$  " 
  "       &$$$$$$$$$$$7       =$$$$$$$$$$$$$$  " 
  "               %$$$$$$$$$$$$$$$;    =$$$$#  " 
  "                                            " 
  "                                            " 
  "                                            " 
  "                                            " 
  "                                            " 
  "                                            " 
  "                                            " 
  "                                            " 
  "                                            " 
  "                                            " 
  "                                            "))

So, having created a few fonts, we can write another script to load the context and build the output strings. This doesn’t have to be a newLISP-GS script:

(set 'font {ComicSansMS} 'font-size 200)
(load (string (env {HOME}) 
        {/Desktop/} 
        (string {ascii-} font font-size) {.lsp}) 
      (sym (string font font-size)))

(set 'ctxt ComicSansMS200)

(define (ctxt:get-glyph n)
  (if (= n 32)
    (dup (dup { } 12) ctxt:height true)
    (eval (sym (string {glyph} n) ctxt))))

(define (message s)
  (let (big-buffer '())
  (dostring (i s)
    (set 'g (ctxt:get-glyph i))    
    (push g big-buffer -1))
  (dotimes (r (length (first big-buffer)))
    (dolist (i big-buffer)
      (print (i r)))
    (println))))

(dostring (c "newLISP")
  (message (char c))
  (println))

There’s small infelicity with this script, to do with the definition of ctxt. Can you fix it?

Comment from m i c h a e l

Man, newlisper, this is definitely the work of a true bricoleur.

Somehow, with the letters composed of the characters like this, even Comic Sans can be tolerated ;-)

m i c h a e l

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: