[magick-users] Re: letter spacing?

Anthony Thyssen anthony at griffith.edu.au
Sun Sep 23 16:27:25 PDT 2007


T o n g on  wrote...
| On Sat, 22 Sep 2007 23:34:48 -0500, Kent wrote:
| 
| > the letters in IM text are a little too close=20
| > together.  Is there a setting (hopefully PHP/MagickWand) to adjust this=
| ?
| 
| I asked whether it is possible to control line spacing the other day, and
| the answer was negative. If your string is not too complicated, maybe you
| can 'montage' them together, thus you can freely control the letter &=20
| line spacing.
| 
I have a PerlMagick sub-routine, that was set to the dicussion forum
some time ago which takes a string and does word wrapping based on
Font Metric lookups.

That same subroutine can be adjusted to do inter-line, inter-word
and with some extra work inter-letter spacing.   I suppose if someone
was willing to spend the time it could even be adjusted to do text
justification.

I include the subroutine below.

If you try out or improve this subroutine, please contribute your
additions back to the list and or forum.

-------------- next part --------------
#!/usr/bin/perl
# This function will wrap at a space or hyphen, and if a word is longer than a
# line it will just break it at the end of the first line. To figure out the
# height of the text, pass the returned string to QueryMultilineFontMetrics.
#
# pass in the string to wrap, the IM object with font and size set, and the
# width you want to wrap to; returns new string
#
# From: Gabe Schaffer,  IM Forum: f=7&t=3708      7 October 2004
#
sub Wrap
{
   my ($text, $img, $maxwidth) = @_;

   # figure out the width of every character in the string
   #
   my %widths = map(($_ => ($img->QueryFontMetrics(text=>$_))[4]),
      keys %{{map(($_ => 1), split //, $text)}});

   my (@newtext, $pos);
   for (split //, $text) {
      # check to see if we're about to go out of bounds
      if ($widths{$_} + $pos > $maxwidth) {
         $pos = 0;
         my @word;
         # if we aren't already at the end of the word,
         # loop until we hit the beginning
         if ( $newtext[-1] ne " "
              && $newtext[-1] ne "-"
              && $newtext[-1] ne "\n") {
            unshift @word, pop @newtext
               while ( @newtext && $newtext[-1] ne " "
                       && $newtext[-1] ne "-"
                       && $newtext[-1] ne "\n")
         }

         # if we hit the beginning of a line,
         # we need to split a word in the middle
         if ($newtext[-1] eq "\n" || @newtext == 0) {
            push @newtext, @word, "\n";
         } else {
            push @newtext, "\n", @word;
            $pos += $widths{$_} for (@word);
         }
      }
      push @newtext, $_;
      $pos += $widths{$_};
      $pos = 0 if $newtext[-1] eq "\n";
   }

   return join "", @newtext;
}


More information about the Magick-users mailing list