eliminate use vars
[imager.git] / FT2 / FT2.pm
CommitLineData
50c75381 1package Imager::Font::FT2;
ee64a81f 2use 5.006;
50c75381
TC
3use strict;
4use Imager;
98d6ae27 5use Scalar::Util ();
ee64a81f
TC
6our @ISA = qw(Imager::Font);
7
8our $VERSION;
50c75381
TC
9
10BEGIN {
b22cbaf8 11 $VERSION = "0.98";
50c75381 12
a5919365
TC
13 require XSLoader;
14 XSLoader::load('Imager::Font::FT2', $VERSION);
50c75381
TC
15}
16
17*_first = \&Imager::Font::_first;
18
19sub new {
20 my $class = shift;
61e5a61a 21 my %hsh=(color=>Imager::Color->new(255,0,0,255),
50c75381
TC
22 size=>15,
23 @_);
24
25 unless ($hsh{file}) {
26 $Imager::ERRSTR = "No font file specified";
27 return;
28 }
29 unless (-e $hsh{file}) {
30 $Imager::ERRSTR = "Font file $hsh{file} not found";
31 return;
32 }
33 unless ($Imager::formats{ft2}) {
34 $Imager::ERRSTR = "Freetype2 not supported in this build";
35 return;
36 }
37 my $id = i_ft2_new($hsh{file}, $hsh{'index'} || 0);
38 unless ($id) { # the low-level code may miss some error handling
39 $Imager::ERRSTR = Imager::_error_as_msg();
40 return;
41 }
42 return bless {
43 id => $id,
44 aa => $hsh{aa} || 0,
45 file => $hsh{file},
46 type => 't1',
47 size => $hsh{size},
48 color => $hsh{color},
49 utf8 => $hsh{utf8},
50 vlayout => $hsh{vlayout},
51 }, $class;
52}
53
54sub _draw {
55 my $self = shift;
98d6ae27
TC
56
57 $self->_valid
58 or return;
59
50c75381
TC
60 my %input = @_;
61 if (exists $input{channel}) {
62 i_ft2_cp($self->{id}, $input{image}{IMG}, $input{'x'}, $input{'y'},
63 $input{channel}, $input{size}, $input{sizew} || 0,
64 $input{string}, , $input{align}, $input{aa}, $input{vlayout},
65 $input{utf8});
66 } else {
67 i_ft2_text($self->{id}, $input{image}{IMG},
68 $input{'x'}, $input{'y'},
69 $input{color}, $input{size}, $input{sizew} || 0,
70 $input{string}, $input{align}, $input{aa}, $input{vlayout},
71 $input{utf8});
72 }
73}
74
75sub _bounding_box {
76 my $self = shift;
77 my %input = @_;
78
98d6ae27
TC
79 $self->_valid
80 or return;
81
d6f02a59
TC
82 my @result = i_ft2_bbox($self->{id}, $input{size}, $input{sizew},
83 $input{string}, $input{utf8});
84 unless (@result) {
85 Imager->_set_error(Imager->_error_as_msg);
86 return;
87 }
88
89 return @result;
50c75381
TC
90}
91
92sub dpi {
93 my $self = shift;
98d6ae27
TC
94
95 $self->_valid
96 or return;
97
50c75381
TC
98 my @old = i_ft2_getdpi($self->{id});
99 if (@_) {
100 my %hsh = @_;
101 my $result;
102 unless ($hsh{xdpi} && $hsh{ydpi}) {
103 if ($hsh{dpi}) {
104 $hsh{xdpi} = $hsh{ydpi} = $hsh{dpi};
105 }
106 else {
107 $Imager::ERRSTR = "dpi method requires xdpi and ydpi or just dpi";
108 return;
109 }
110 i_ft2_setdpi($self->{id}, $hsh{xdpi}, $hsh{ydpi}) or return;
111 }
112 }
113
114 return @old;
115}
116
117sub hinting {
118 my ($self, %opts) = @_;
119
98d6ae27
TC
120 $self->_valid
121 or return;
122
50c75381
TC
123 i_ft2_sethinting($self->{id}, $opts{hinting} || 0);
124}
125
126sub _transform {
127 my $self = shift;
128
98d6ae27
TC
129 $self->_valid
130 or return;
131
50c75381
TC
132 my %hsh = @_;
133 my $matrix = $hsh{matrix} or return undef;
134
135 return i_ft2_settransform($self->{id}, $matrix)
136}
137
138sub utf8 {
139 return 1;
140}
141
142# check if the font has the characters in the given string
143sub has_chars {
144 my ($self, %hsh) = @_;
145
98d6ae27
TC
146 $self->_valid
147 or return;
148
50c75381
TC
149 unless (defined $hsh{string} && length $hsh{string}) {
150 $Imager::ERRSTR = "No string supplied to \$font->has_chars()";
151 return;
152 }
d6f02a59
TC
153 if (wantarray) {
154 my @result = i_ft2_has_chars($self->{id}, $hsh{string},
155 _first($hsh{'utf8'}, $self->{utf8}, 0));
156 unless (@result) {
157 Imager->_set_error(Imager->_error_as_msg);
158 return;
159 }
160
161 return @result;
162 }
163 else {
164 my $result = i_ft2_has_chars($self->{id}, $hsh{string},
165 _first($hsh{'utf8'}, $self->{utf8}, 0));
166 unless (defined $result) {
167 Imager->_set_error(Imager->_error_as_msg);
168 return;
169 }
170 return $result;
171 }
50c75381
TC
172}
173
174sub face_name {
175 my ($self) = @_;
176
98d6ae27
TC
177 $self->_valid
178 or return;
179
50c75381
TC
180 i_ft2_face_name($self->{id});
181}
182
183sub can_glyph_names {
d6f02a59
TC
184 my ($self) = @_;
185
186 i_ft2_can_do_glyph_names()
187 or return;
188
189 if (ref $self) {
190 $self->_valid
191 or return;
192
193 i_ft2_face_has_glyph_names($self->{id})
194 or return;
195 }
196
197 return 1;
50c75381
TC
198}
199
200sub glyph_names {
201 my ($self, %input) = @_;
202
98d6ae27
TC
203 $self->_valid
204 or return;
205
50c75381
TC
206 my $string = $input{string};
207 defined $string
208 or return Imager->_set_error("no string parameter passed to glyph_names");
209 my $utf8 = _first($input{utf8}, 0);
210 my $reliable_only = _first($input{reliable_only}, 1);
211
212 my @names = i_ft2_glyph_name($self->{id}, $string, $utf8, $reliable_only);
213 @names or return Imager->_set_error(Imager->_error_as_msg);
214
215 return @names if wantarray;
216 return pop @names;
217}
218
219sub is_mm {
220 my ($self) = @_;
221
98d6ae27
TC
222 $self->_valid
223 or return;
224
50c75381
TC
225 i_ft2_is_multiple_master($self->{id});
226}
227
228sub mm_axes {
229 my ($self) = @_;
230
98d6ae27
TC
231 $self->_valid
232 or return;
233
50c75381
TC
234 my ($num_axis, $num_design, @axes) =
235 i_ft2_get_multiple_masters($self->{id})
236 or return Imager->_set_error(Imager->_error_as_msg);
237
238 return @axes;
239}
240
241sub set_mm_coords {
242 my ($self, %opts) = @_;
243
98d6ae27
TC
244 $self->_valid
245 or return;
246
50c75381
TC
247 $opts{coords}
248 or return Imager->_set_error("Missing coords parameter");
249 ref($opts{coords}) && $opts{coords} =~ /ARRAY\(0x[\da-f]+\)$/
250 or return Imager->_set_error("coords parameter must be an ARRAY ref");
251
252 i_ft2_set_mm_coords($self->{id}, @{$opts{coords}})
253 or return Imager->_set_error(Imager->_error_as_msg);
254
255 return 1;
256}
98d6ae27
TC
257
258# objects may be invalidated on thread creation (or Win32 fork emulation)
259sub _valid {
260 my $self = shift;
261
262 unless ($self->{id} && Scalar::Util::blessed($self->{id})) {
263 Imager->_set_error("font object was created in another thread");
264 return;
265 }
266
267 return 1;
268}
269
50c75381
TC
2701;
271
272__END__
273
274=head1 NAME
275
276Imager::Font::FT2 - font support using FreeType 2
277
278=head1 SYNOPSIS
279
280 use Imager;
281
282 my $img = Imager->new;
283 my $font = Imager::Font->new(file => "foo.ttf", type => "ft2");
284
285 $img->string(... font => $font);
286
287=head1 DESCRIPTION
288
289This provides font support on FreeType 2.
290
291=head1 CAVEATS
292
293Unfortunately, older versions of Imager would install
294C<Imager::Font::FreeType2> even if FreeType 2 wasn't available, and if
295no font was created would succeed in loading the module. This means
296that an existing C<FreeType2.pm> could cause a probe success for
297supported font files, so I've renamed it.
298
299=head1 AUTHOR
300
5b480b14 301Tony Cook <tonyc@cpan.org>
50c75381
TC
302
303=head1 SEE ALSO
304
305Imager, Imager::Font.
306
307=cut