Added preliminary support for adding image based fonts.
[imager.git] / lib / Imager / Font / FreeType2.pm
1 package Imager::Font::FreeType2;
2 use strict;
3 use Imager::Color;
4 use vars qw(@ISA);
5 @ISA = qw(Imager::Font);
6
7 *_first = \&Imager::Font::_first;
8
9 sub new {
10   my $class = shift;
11   my %hsh=(color=>Imager::Color->new(255,0,0,0),
12            size=>15,
13            @_);
14
15   unless ($hsh{file}) {
16     $Imager::ERRSTR = "No font file specified";
17     return;
18   }
19   unless (-e $hsh{file}) {
20     $Imager::ERRSTR = "Font file $hsh{file} not found";
21     return;
22   }
23   unless ($Imager::formats{ft2}) {
24     $Imager::ERRSTR = "Freetype2 not supported in this build";
25     return;
26   }
27   my $id = i_ft2_new($hsh{file}, $hsh{'index'} || 0);
28   unless ($id) { # the low-level code may miss some error handling
29     $Imager::ERRSTR = Imager::_error_as_msg();
30     return;
31   }
32   return bless {
33                 id       => $id,
34                 aa       => $hsh{aa} || 0,
35                 file     => $hsh{file},
36                 type     => 't1',
37                 size     => $hsh{size},
38                 color    => $hsh{color},
39                 utf8     => $hsh{utf8},
40                 vlayout  => $hsh{vlayout},
41                }, $class;
42 }
43
44 sub _draw {
45   my $self = shift;
46   my %input = @_;
47   if (exists $input{channel}) {
48     i_ft2_cp($self->{id}, $input{image}{IMG}, $input{'x'}, $input{'y'},
49              $input{channel}, $input{size}, $input{sizew} || 0,
50              $input{string}, , $input{align}, $input{aa}, $input{vlayout},
51              $input{utf8});
52   } else {
53     i_ft2_text($self->{id}, $input{image}{IMG},
54                $input{'x'}, $input{'y'},
55                $input{color}, $input{size}, $input{sizew} || 0,
56                $input{string}, $input{align}, $input{aa}, $input{vlayout},
57                $input{utf8});
58   }
59 }
60
61 sub _bounding_box {
62   my $self = shift;
63   my %input = @_;
64
65   return i_ft2_bbox($self->{id}, $input{size}, $input{sizew}, $input{string}, 
66                     $input{utf8});
67 }
68
69 sub dpi {
70   my $self = shift;
71   my @old = i_ft2_getdpi($self->{id});
72   if (@_) {
73     my %hsh = @_;
74     my $result;
75     unless ($hsh{xdpi} && $hsh{ydpi}) {
76       if ($hsh{dpi}) {
77         $hsh{xdpi} = $hsh{ydpi} = $hsh{dpi};
78       }
79       else {
80         $Imager::ERRSTR = "dpi method requires xdpi and ydpi or just dpi";
81         return;
82       }
83       i_ft2_setdpi($self->{id}, $hsh{xdpi}, $hsh{ydpi}) or return;
84     }
85   }
86   
87   return @old;
88 }
89
90 sub hinting {
91   my ($self, %opts) = @_;
92
93   i_ft2_sethinting($self->{id}, $opts{hinting} || 0);
94 }
95
96 sub _transform {
97   my $self = shift;
98
99   my %hsh = @_;
100   my $matrix = $hsh{matrix} or return undef;
101
102   return i_ft2_settransform($self->{id}, $matrix)
103 }
104
105 sub utf8 {
106   return 1;
107 }
108
109 # check if the font has the characters in the given string
110 sub has_chars {
111   my ($self, %hsh) = @_;
112
113   unless (defined $hsh{string} && length $hsh{string}) {
114     $Imager::ERRSTR = "No string supplied to \$font->has_chars()";
115     return;
116   }
117   return i_ft2_has_chars($self->{id}, $hsh{string}, $hsh{'utf8'} || 0);
118 }
119
120 sub face_name {
121   my ($self) = @_;
122
123   i_ft2_face_name($self->{id});
124 }
125
126 sub can_glyph_names {
127   i_ft2_can_do_glyph_names();
128 }
129
130 sub glyph_names {
131   my ($self, %input) = @_;
132
133   my $string = $input{string};
134   defined $string
135     or return Imager->_seterror("no string parameter passed to glyph_names");
136   my $utf8 = _first($input{utf8} || 0);
137
138   i_ft2_glyph_name($self->{id}, $string, $utf8);
139 }
140
141 1;
142
143 __END__
144
145 =head1 NAME
146
147   Imager::Font::FreeType2 - low-level functions for FreeType2 text output
148
149 =head1 DESCRIPTION
150
151 Imager::Font creates a Imager::Font::FreeType2 object when asked to.
152
153 See Imager::Font to see how to use this type.
154
155 This class provides low-level functions that require the caller to
156 perform data validation.
157
158 This driver supports:
159
160 =over
161
162 =item transform()
163
164 =item dpi()
165
166 =item draw()
167
168 The following parameters:
169
170 =over
171
172 =item utf8
173
174 =item vlayour
175
176 =item sizew
177
178 =back
179
180 =back
181
182 =head2 Special behaviors
183
184 If you call transform() to set a transformation matrix, hinting will
185 be switched off.  This prevents sudden jumps in the size of the text
186 caused by the hinting when the transformation is the identity matrix.
187 If for some reason you want hinting enabled, use
188 $font->hinting(hinting=>1) to re-enable hinting.  This will need to be
189 called after I<each> call to transform().
190
191 =head1 AUTHOR
192
193 Addi, Tony
194
195 =cut