Changes updates
[imager.git] / T1 / T1.pm
CommitLineData
a556912d
TC
1package Imager::Font::T1;
2use strict;
3use Imager::Color;
4use vars qw(@ISA $VERSION);
5@ISA = qw(Imager::Font);
1aaae40f 6use Scalar::Util ();
a556912d
TC
7
8BEGIN {
567c2038 9 $VERSION = "1.026";
a556912d 10
a5919365
TC
11 require XSLoader;
12 XSLoader::load('Imager::Font::T1', $VERSION);
a556912d
TC
13}
14
15
16*_first = \&Imager::Font::_first;
17
5cb09ff7 18my $t1aa = 2;
d03fd5a4 19
a556912d
TC
20sub new {
21 my $class = shift;
61e5a61a 22 my %hsh=(color=>Imager::Color->new(255,0,0,255),
a556912d
TC
23 size=>15,
24 @_);
25
26 unless ($hsh{file}) {
27 $Imager::ERRSTR = "No font file specified";
28 return;
29 }
30 unless (-e $hsh{file}) {
31 $Imager::ERRSTR = "Font file $hsh{file} not found";
32 return;
33 }
34 unless ($Imager::formats{t1}) {
35 $Imager::ERRSTR = "Type 1 fonts not supported in this build";
36 return;
37 }
38 # we want to avoid T1Lib's file search mechanism
39 unless ($hsh{file} =~ m!^/!
40 || $hsh{file} =~ m!^\.\/?/!
43233e13 41 || $^O =~ /^(MSWin32|cygwin)$/ && $hsh{file} =~ /^[a-z]:/i) {
a556912d
TC
42 $hsh{file} = './' . $hsh{file};
43 }
44
45 if($hsh{afm}) {
46 unless (-e $hsh{afm}) {
47 $Imager::ERRSTR = "Afm file $hsh{afm} not found";
48 return;
49 }
50 unless ($hsh{afm} =~ m!^/!
51 || $hsh{afm} =~ m!^\./!
43233e13 52 || $^O =~ /^(MSWin32|cygwin)$/ && $hsh{file} =~ /^[a-z]:/i) {
a556912d
TC
53 $hsh{file} = './' . $hsh{file};
54 }
55 } else {
56 $hsh{afm} = 0;
57 }
58
1aaae40f
TC
59 my $font = Imager::Font::T1xs->new($hsh{file},$hsh{afm});
60 unless ($font) { # the low-level code may miss some error handling
73e3ff55 61 Imager->_set_error(Imager->_error_as_msg);
a556912d
TC
62 return;
63 }
64 return bless {
1aaae40f 65 t1font => $font,
a556912d
TC
66 aa => $hsh{aa} || 0,
67 file => $hsh{file},
68 type => 't1',
69 size => $hsh{size},
70 color => $hsh{color},
5cb09ff7 71 t1aa => $t1aa,
a556912d
TC
72 }, $class;
73}
74
75sub _draw {
76 my $self = shift;
1aaae40f
TC
77
78 $self->_valid
79 or return;
80
a556912d 81 my %input = @_;
a556912d
TC
82 my $flags = '';
83 $flags .= 'u' if $input{underline};
84 $flags .= 's' if $input{strikethrough};
85 $flags .= 'o' if $input{overline};
5cb09ff7 86 my $aa = $input{aa} ? $self->{t1aa} : 0;
a556912d 87 if (exists $input{channel}) {
1aaae40f
TC
88 $self->{t1font}->cp($input{image}{IMG}, $input{'x'}, $input{'y'},
89 $input{channel}, $input{size},
b3f71a5b 90 $input{string}, $input{align},
5cb09ff7
TC
91 $input{utf8}, $flags, $aa)
92 or return;
a556912d 93 } else {
1aaae40f
TC
94 $self->{t1font}->text($input{image}{IMG}, $input{'x'}, $input{'y'},
95 $input{color}, $input{size},
b3f71a5b 96 $input{string}, $input{align}, $input{utf8}, $flags, $aa)
5cb09ff7 97 or return;
a556912d
TC
98 }
99
100 return $self;
101}
102
103sub _bounding_box {
104 my $self = shift;
1aaae40f
TC
105
106 $self->_valid
107 or return;
108
a556912d
TC
109 my %input = @_;
110 my $flags = '';
111 $flags .= 'u' if $input{underline};
112 $flags .= 's' if $input{strikethrough};
113 $flags .= 'o' if $input{overline};
932f9afb
TC
114 my @bbox = $self->{t1font}->bbox($input{size}, $input{string},
115 $input{utf8}, $flags);
116 unless (@bbox) {
117 Imager->_set_error(Imager->_error_as_msg);
118 return;
119 }
120
121 return @bbox;
a556912d
TC
122}
123
124# check if the font has the characters in the given string
125sub has_chars {
126 my ($self, %hsh) = @_;
127
1aaae40f
TC
128 $self->_valid
129 or return;
130
b3f71a5b 131 unless (defined $hsh{string}) {
a556912d
TC
132 $Imager::ERRSTR = "No string supplied to \$font->has_chars()";
133 return;
134 }
932f9afb
TC
135 if (wantarray) {
136 my @result = $self->{t1font}
137 ->has_chars($hsh{string}, _first($hsh{'utf8'}, $self->{utf8}, 0));
138 unless (@result) {
139 Imager->_set_error(Imager->_error_as_msg);
140 return;
141 }
142
143 return @result;
144 }
145 else {
146 my $result = $self->{t1font}
147 ->has_chars($hsh{string}, _first($hsh{'utf8'}, $self->{utf8}, 0));
148 unless (defined $result) {
149 Imager->_set_error(Imager->_error_as_msg);
150 return;
151 }
152 return $result;
153 }
a556912d
TC
154}
155
156sub utf8 {
157 1;
158}
159
76ae98a6
TC
160sub can_glyph_names {
161 1;
162}
163
a556912d
TC
164sub face_name {
165 my ($self) = @_;
166
1aaae40f
TC
167 $self->_valid
168 or return;
169
170 return $self->{t1font}->face_name();
a556912d
TC
171}
172
173sub glyph_names {
174 my ($self, %input) = @_;
175
1aaae40f
TC
176 $self->_valid
177 or return;
178
a556912d
TC
179 my $string = $input{string};
180 defined $string
181 or return Imager->_set_error("no string parameter passed to glyph_names");
182 my $utf8 = _first($input{utf8} || 0);
183
932f9afb
TC
184 my @result = $self->{t1font}->glyph_names($string, $utf8);
185 unless (@result) {
186 Imager->_set_error(Imager->_error_as_msg);
187 return;
188 }
189
190 return @result;
a556912d
TC
191}
192
5cb09ff7
TC
193sub set_aa_level {
194 my ($self, $new_t1aa) = @_;
195
196 if (!defined $new_t1aa ||
197 ($new_t1aa != 1 && $new_t1aa != 2)) {
198 Imager->_set_error("set_aa_level: parameter must be 1 or 2");
199 return;
200 }
201
202 if (ref $self) {
203 $self->_valid
204 or return;
205
206 $self->{t1aa} = $new_t1aa;
207 }
208 else {
209 $t1aa = $new_t1aa;
210 }
211
212 return 1;
213}
a556912d 214
1aaae40f
TC
215sub _valid {
216 my $self = shift;
217
218 unless ($self->{t1font} && Scalar::Util::blessed($self->{t1font})) {
219 Imager->_set_error("font object was created in another thread");
220 return;
221 }
222
223 return 1;
224}
225
a556912d
TC
2261;
227
228__END__
229
230=head1 NAME
231
232 Imager::Font::Type1 - low-level functions for Type1 fonts
233
234=head1 DESCRIPTION
235
236Imager::Font creates a Imager::Font::Type1 object when asked to create
237a font object based on a C<.pfb> file.
238
239See Imager::Font to see how to use this type.
240
241This class provides low-level functions that require the caller to
242perform data validation
243
244By default Imager no longer creates the F<t1lib.log> log file. You
245can re-enable that by calling Imager::init() with the C<t1log> option:
246
247 Imager::init(t1log=>1);
248
249This must be called before creating any fonts.
250
251Currently specific to Imager::Font::Type1, you can use the following
252flags when drawing text or calculating a bounding box:
253
254=for stopwords overline strikethrough
255
256=over
257
258=item *
259
260C<underline> - Draw the text with an underline.
261
262=item *
263
264C<overline> - Draw the text with an overline.
265
266=item *
267
268C<strikethrough> - Draw the text with a strikethrough.
269
270=back
271
272Obviously, if you're calculating the bounding box the size of the line
273is included in the box, and the line isn't drawn :)
274
5cb09ff7
TC
275=head2 Anti-aliasing
276
277T1Lib supports multiple levels of anti-aliasing, by default, if you
278request anti-aliased output, Imager::Font::T1 will use the maximum
279level.
280
281You can override this with the set_t1_aa() method:
282
283=over
284
285=item set_aa_level()
286
287Usage:
288
289 $font->set_aa_level(1);
290 Imager::Font::T1->set_aa_level(2);
291
292Sets the T1Lib anti-aliasing level either for the specified font, or
293for new font objects.
294
295The only parameter must be 1 or 2.
296
297Returns true on success.
298
299=back
300
a556912d
TC
301=head1 AUTHOR
302
303Addi, Tony
304
305=cut