]> git.imager.perl.org - imager.git/commitdiff
split Imager::Font into base *::Type1 and *::Truetype, which should
authorTony Cook <tony@develop=help.com>
Thu, 24 May 2001 09:45:07 +0000 (09:45 +0000)
committerTony Cook <tony@develop=help.com>
Thu, 24 May 2001 09:45:07 +0000 (09:45 +0000)
simplify adding new font types (I hope)

Changes
Imager.pm
lib/Imager/Font.pm
lib/Imager/Font/Truetype.pm [new file with mode: 0644]
lib/Imager/Font/Type1.pm [new file with mode: 0644]

diff --git a/Changes b/Changes
index 1acc40c0029ec6b03c1189ae34a9a7adbd984808..4aa8a0808204cab147340f8df317a88a9f2de19c 100644 (file)
--- a/Changes
+++ b/Changes
@@ -417,6 +417,9 @@ Revision history for Perl extension Imager.
         - changed README note on libgif bug to refer to t105gif.t instead
          of t10formats.t
 
+0.39  pre1
+       - split Imager::Font into a base, *::Type1 and *::Truetype
+
 =================================================================
 
         For latest versions check the Imager-devel pages:
index efdf6fa198cd1be855130f2b40e86867cebe5a55..33541837e0116d535b127ddfcc1cd903fd53bd6c 100644 (file)
--- a/Imager.pm
+++ b/Imager.pm
@@ -1408,52 +1408,7 @@ sub string {
     return;
   }
 
-  my $aa=1;
-  my $font=$input{'font'};
-  my $align=$font->{'align'} unless exists $input{'align'};
-  my $color=$input{'color'} || $font->{'color'};
-  my $size=$input{'size'}   || $font->{'size'};
-
-  if (!defined($size)) { $self->{ERRSTR}='No size parameter and no default in font'; return undef; }
-
-  $aa=$font->{'aa'} if exists $font->{'aa'};
-  $aa=$input{'aa'} if exists $input{'aa'};
-
-
-
-#  unless($font->can('text')) {
-#    $self->{ERRSTR}="font is unable to do what we need";
-#    return;
-#  }
-
-#  use Data::Dumper; 
-#  warn Dumper($font);
-
-#  print "Channel=".$input{'channel'}."\n";
-
-  if ( $font->{'type'} eq 't1' ) {
-    if ( exists $input{'channel'} ) {
-      Imager::Font::t1_set_aa_level($aa);
-      i_t1_cp($self->{IMG},$input{'x'},$input{'y'},
-             $input{'channel'},$font->{'id'},$size,
-             $input{'string'},length($input{'string'}),1);
-    } else {
-      Imager::Font::t1_set_aa_level($aa);
-      i_t1_text($self->{IMG},$input{'x'},$input{'y'},
-               $color,$font->{'id'},$size,
-               $input{'string'},length($input{'string'}),1);
-    }
-  }
-
-  if ( $font->{'type'} eq 'tt' ) {
-    if ( exists $input{'channel'} ) {
-      i_tt_cp($font->{'id'},$self->{IMG},$input{'x'},$input{'y'},$input{'channel'},
-             $size,$input{'string'},length($input{'string'}),$aa); 
-    } else {
-      i_tt_text($font->{'id'},$self->{IMG},$input{'x'},$input{'y'},$color,$size,
-               $input{'string'},length($input{'string'}),$aa); 
-    }
-  }
+  $input{font}->draw(image=>$self, %input);
 
   return $self;
 }
index 6edc953149f68bbd3449ad771d311a78a0298fe5..fab3e474883a44d2b7afe5eb24f11f63633314df 100644 (file)
@@ -2,22 +2,12 @@ package Imager::Font;
 
 use Imager::Color;
 use strict;
-use vars qw(%T1_Paths %TT_Paths %T1_Cache %TT_Cache $TT_CSize $TT_CSize $T1AA);
+use File::Spec;
 
 # This class is a container
 # and works for both truetype and t1 fonts.
 
 
-# $T1AA is in there because for some reason (probably cache related) antialiasing
-# is a system wide setting in t1 lib.
-
-sub t1_set_aa_level {
-  if (!defined $T1AA or $_[0] != $T1AA) {
-    Imager::i_t1_set_aa($_[0]);
-    $T1AA=$_[0];
-  }
-}
-
 # search method
 # 1. start by checking if file is the parameter
 # 1a. if so qualify path and compare to the cache.
@@ -66,42 +56,64 @@ sub new {
   # here we should have the font type or be dead already.
 
   if ($type eq 't1') {
-    $id=Imager::i_t1_new($file);
+    require 'Imager/Font/Type1.pm';
+    return Imager::Font::Type1->new(%hsh);
   }
 
   if ($type eq 'tt') {
-    $id=Imager::i_tt_new($file);
+    require 'Imager/Font/Truetype.pm';
+    return Imager::Font::Truetype->new(%hsh);
   }
-
-  $self->{'aa'}=$hsh{'aa'}||'0';
-  $self->{'file'}=$file;
-  $self->{'id'}=$id;
-  $self->{'type'}=$type;
-  $self->{'size'}=$hsh{'size'};
-  $self->{'color'}=$hsh{'color'};
-  return $self;
+  # it would be nice to have some generic mechanism to select the
+  # class
+  
+  return undef;
 }
 
+# returns first defined parameter
+sub _first {
+  for (@_) {
+    return $_ if defined $_;
+  }
+  return undef;
+}
 
-
-
-
+sub draw {
+  my $self = shift;
+  my %input = (x => 0, 'y' => 0, @_);
+  unless ($input{image}) {
+    $Imager::ERRSTR = 'No image supplied to $font->draw()';
+    return;
+  }
+  $input{string} = _first($input{string}, $input{text});
+  unless (defined $input{string}) {
+    $Imager::ERRSTR = "Missing require parameter 'string'";
+    return;
+  }
+  $input{aa} = _first($input{aa}, $input{antialias}, $self->{aa}, 1);
+  # the original draw code worked this out but didn't use it
+  $input{align} = _first($input{align}, $self->{align});
+  $input{color} = _first($input{color}, $self->{color});
+  $input{size} = _first($input{size}, $self->{size});
+  unless (defined $input{size}) {
+    $input{image}{ERRSTR} = "No font size provided";
+    return undef;
+  }
+  $input{align} = _first($input{align}, 1);
+  $self->_draw(%input);
+}
 
 sub bounding_box {
   my $self=shift;
   my %input=@_;
-  my @box;
-
-  if (!exists $input{'string'}) { $Imager::ERRSTR='string parameter missing'; return; }
 
-  if ($self->{type} eq 't1') {
-    @box=Imager::i_t1_bbox($self->{id}, defined($input{size}) ? $input{size} :$self->{size},
-                          $input{string}, length($input{string}));
-  }
-  if ($self->{type} eq 'tt') {
-    @box=Imager::i_tt_bbox($self->{id}, defined($input{size}) ? $input{size} :$self->{size},
-                          $input{string}, length($input{string}));
+  if (!exists $input{'string'}) { 
+    $Imager::ERRSTR='string parameter missing'; 
+    return;
   }
+  $input{size} ||= $self->{size};
+
+  my @box = $self->_bounding_box(%input);
 
   if(exists $input{'x'} and exists $input{'y'}) {
     my($gdescent, $gascent)=@box[1,3];
@@ -118,8 +130,6 @@ sub bounding_box {
 
 1;
 
-
-
 __END__
 
 =head1 NAME
@@ -305,6 +315,10 @@ Arnar M. Hrafnkelsson, addi@umich.edu
 And a great deal of help from others - see the README for a complete
 list.
 
+=head1 BUGS
+
+You need to modify this class to add new font types.
+
 =head1 SEE ALSO
 
 Imager(3)
diff --git a/lib/Imager/Font/Truetype.pm b/lib/Imager/Font/Truetype.pm
new file mode 100644 (file)
index 0000000..61d5728
--- /dev/null
@@ -0,0 +1,83 @@
+package Imager::Font::Truetype;
+use strict;
+use vars qw(@ISA);
+@ISA = qw(Imager::Font);
+
+sub new {
+  my $class = shift;
+  my %hsh=(color=>Imager::Color->new(255,0,0,0),
+          size=>15,
+          @_);
+
+  unless ($hsh{file}) {
+    $Imager::ERRSTR = "No font file specified";
+    return;
+  }
+  unless (-e $hsh{file}) {
+    $Imager::ERRSTR = "Font file $hsh{file} not found";
+    return;
+  }
+  unless ($Imager::formats{tt}) {
+    $Imager::ERRSTR = "Type 1 fonts not supported in this build";
+    return;
+  }
+  my $id = Imager::i_tt_new($hsh{file});
+  unless ($id >= 0) { # the low-level code may miss some error handling
+    $Imager::ERRSTR = "Could not load font ($id)";
+    return;
+  }
+  return bless {
+               id    => $id,
+               aa    => $hsh{aa} || 0,
+               file  => $hsh{file},
+               type  => 'tt',
+               size  => $hsh{size},
+               color => $hsh{color},
+              }, $class;
+}
+
+sub _draw {
+  my $self = shift;
+  my %input = @_;
+  if ( exists $input{channel} ) {
+    Imager::i_tt_cp($self->{id},$input{image}{IMG},
+                   $input{x}, $input{'y'}, $input{channel}, $input{size},
+                   $input{string}, length($input{string}),$input{aa}); 
+  } else {
+    Imager::i_tt_text($self->{id}, $input{image}{IMG}, 
+                     $input{x}, $input{'y'}, $input{color},
+                     $input{size}, $input{string}, 
+                     length($input{string}), $input{aa}); 
+  }
+}
+
+sub _bounding_box {
+  my $self = shift;
+  my %input = @_;
+  return Imager::i_tt_bbox($self->{id}, $input{size},
+                          $input{string}, length($input{string}));
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+  Imager::Font::Truetype - low-level functions for Truetype fonts
+
+=head1 DESCRIPTION
+
+Imager::Font creates a Imager::Font::Truetype object when asked to create
+a font object based on a .ttf file.
+
+See Imager::Font to see how to use this type.
+
+This class provides low-level functions that require the caller to
+perform data validation.
+
+=head1 AUTHOR
+
+Addi, Tony
+
+=cut
diff --git a/lib/Imager/Font/Type1.pm b/lib/Imager/Font/Type1.pm
new file mode 100644 (file)
index 0000000..e3f884e
--- /dev/null
@@ -0,0 +1,103 @@
+package Imager::Font::Type1;
+use strict;
+use Imager::Color;
+use vars qw(@ISA);
+@ISA = qw(Imager::Font);
+use File::Spec;
+
+my $t1aa;
+
+# $T1AA is in there because for some reason (probably cache related) antialiasing
+# is a system wide setting in t1 lib.
+
+sub t1_set_aa_level {
+  if (!defined $t1aa or $_[0] != $t1aa) {
+    Imager::i_t1_set_aa($_[0]);
+    $t1aa=$_[0];
+  }
+}
+
+sub new {
+  my $class = shift;
+  my %hsh=(color=>Imager::Color->new(255,0,0,0),
+          size=>15,
+          @_);
+
+  unless ($hsh{file}) {
+    $Imager::ERRSTR = "No font file specified";
+    return;
+  }
+  unless (-e $hsh{file}) {
+    $Imager::ERRSTR = "Font file $hsh{file} not found";
+    return;
+  }
+  unless ($Imager::formats{t1}) {
+    $Imager::ERRSTR = "Type 1 fonts not supported in this build";
+    return;
+  }
+  unless ($hsh{file} =~ m!^/! || $hsh{file} =~ m!^\./!) {
+    $hsh{file} = File::Spec->catfile(File::Spec->curdir, $hsh{file});
+  }
+  my $id = Imager::i_t1_new($hsh{file});
+  unless ($id >= 0) { # the low-level code may miss some error handling
+    $Imager::ERRSTR = "Could not load font ($id)";
+    return;
+  }
+  return bless {
+               id    => $id,
+               aa    => $hsh{aa} || 0,
+               file  => $hsh{file},
+               type  => 't1',
+               size  => $hsh{size},
+               color => $hsh{color},
+              }, $class;
+}
+
+sub _draw {
+  my $self = shift;
+  my %input = @_;
+  t1_set_aa_level($input{aa});
+  if (exists $input{channel}) {
+    Imager::i_t1_cp($input{image}{IMG}, $input{x}, $input{'y'},
+                   $input{channel}, $self->{id}, $input{size},
+                   $input{string}, length($input{string}), $input{align});
+  } else {
+    Imager::i_t1_text($input{image}{IMG}, $input{x}, $input{'y'}, 
+                     $input{color}, $self->{id}, $input{size}, 
+                     $input{string}, length($input{string}), 
+                     $input{align});
+  }
+
+  return $self;
+}
+
+sub _bounding_box {
+  my $self = shift;
+  my %input = @_;
+  return Imager::i_t1_bbox($self->{id}, $input{size}, $input{string},
+                          length($input{string}));
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+  Imager::Font::Type1 - low-level functions for Type1 fonts
+
+=head1 DESCRIPTION
+
+Imager::Font creates a Imager::Font::Type1 object when asked to create
+a font object based on a .pfb file.
+
+See Imager::Font to see how to use this type.
+
+This class provides low-level functions that require the caller to
+perform data validation
+
+=head1 AUTHOR
+
+Addi, Tony
+
+=cut