Commit | Line | Data |
---|---|---|
50c75381 TC |
1 | package Imager::Font::FT2; |
2 | use strict; | |
3 | use Imager; | |
4 | use vars qw($VERSION @ISA); | |
5 | @ISA = qw(Imager::Font); | |
6 | ||
7 | BEGIN { | |
d5ccf7cc | 8 | $VERSION = "0.80"; |
50c75381 TC |
9 | |
10 | eval { | |
11 | require XSLoader; | |
12 | XSLoader::load('Imager::Font::FT2', $VERSION); | |
13 | 1; | |
14 | } or do { | |
15 | require DynaLoader; | |
16 | push @ISA, 'DynaLoader'; | |
17 | bootstrap Imager::Font::FT2 $VERSION; | |
18 | }; | |
19 | } | |
20 | ||
21 | *_first = \&Imager::Font::_first; | |
22 | ||
23 | sub new { | |
24 | my $class = shift; | |
25 | my %hsh=(color=>Imager::Color->new(255,0,0,0), | |
26 | size=>15, | |
27 | @_); | |
28 | ||
29 | unless ($hsh{file}) { | |
30 | $Imager::ERRSTR = "No font file specified"; | |
31 | return; | |
32 | } | |
33 | unless (-e $hsh{file}) { | |
34 | $Imager::ERRSTR = "Font file $hsh{file} not found"; | |
35 | return; | |
36 | } | |
37 | unless ($Imager::formats{ft2}) { | |
38 | $Imager::ERRSTR = "Freetype2 not supported in this build"; | |
39 | return; | |
40 | } | |
41 | my $id = i_ft2_new($hsh{file}, $hsh{'index'} || 0); | |
42 | unless ($id) { # the low-level code may miss some error handling | |
43 | $Imager::ERRSTR = Imager::_error_as_msg(); | |
44 | return; | |
45 | } | |
46 | return bless { | |
47 | id => $id, | |
48 | aa => $hsh{aa} || 0, | |
49 | file => $hsh{file}, | |
50 | type => 't1', | |
51 | size => $hsh{size}, | |
52 | color => $hsh{color}, | |
53 | utf8 => $hsh{utf8}, | |
54 | vlayout => $hsh{vlayout}, | |
55 | }, $class; | |
56 | } | |
57 | ||
58 | sub _draw { | |
59 | my $self = shift; | |
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 | ||
75 | sub _bounding_box { | |
76 | my $self = shift; | |
77 | my %input = @_; | |
78 | ||
79 | return i_ft2_bbox($self->{id}, $input{size}, $input{sizew}, $input{string}, | |
80 | $input{utf8}); | |
81 | } | |
82 | ||
83 | sub dpi { | |
84 | my $self = shift; | |
85 | my @old = i_ft2_getdpi($self->{id}); | |
86 | if (@_) { | |
87 | my %hsh = @_; | |
88 | my $result; | |
89 | unless ($hsh{xdpi} && $hsh{ydpi}) { | |
90 | if ($hsh{dpi}) { | |
91 | $hsh{xdpi} = $hsh{ydpi} = $hsh{dpi}; | |
92 | } | |
93 | else { | |
94 | $Imager::ERRSTR = "dpi method requires xdpi and ydpi or just dpi"; | |
95 | return; | |
96 | } | |
97 | i_ft2_setdpi($self->{id}, $hsh{xdpi}, $hsh{ydpi}) or return; | |
98 | } | |
99 | } | |
100 | ||
101 | return @old; | |
102 | } | |
103 | ||
104 | sub hinting { | |
105 | my ($self, %opts) = @_; | |
106 | ||
107 | i_ft2_sethinting($self->{id}, $opts{hinting} || 0); | |
108 | } | |
109 | ||
110 | sub _transform { | |
111 | my $self = shift; | |
112 | ||
113 | my %hsh = @_; | |
114 | my $matrix = $hsh{matrix} or return undef; | |
115 | ||
116 | return i_ft2_settransform($self->{id}, $matrix) | |
117 | } | |
118 | ||
119 | sub utf8 { | |
120 | return 1; | |
121 | } | |
122 | ||
123 | # check if the font has the characters in the given string | |
124 | sub has_chars { | |
125 | my ($self, %hsh) = @_; | |
126 | ||
127 | unless (defined $hsh{string} && length $hsh{string}) { | |
128 | $Imager::ERRSTR = "No string supplied to \$font->has_chars()"; | |
129 | return; | |
130 | } | |
131 | return i_ft2_has_chars($self->{id}, $hsh{string}, | |
132 | _first($hsh{'utf8'}, $self->{utf8}, 0)); | |
133 | } | |
134 | ||
135 | sub face_name { | |
136 | my ($self) = @_; | |
137 | ||
138 | i_ft2_face_name($self->{id}); | |
139 | } | |
140 | ||
141 | sub can_glyph_names { | |
142 | i_ft2_can_do_glyph_names(); | |
143 | } | |
144 | ||
145 | sub glyph_names { | |
146 | my ($self, %input) = @_; | |
147 | ||
148 | my $string = $input{string}; | |
149 | defined $string | |
150 | or return Imager->_set_error("no string parameter passed to glyph_names"); | |
151 | my $utf8 = _first($input{utf8}, 0); | |
152 | my $reliable_only = _first($input{reliable_only}, 1); | |
153 | ||
154 | my @names = i_ft2_glyph_name($self->{id}, $string, $utf8, $reliable_only); | |
155 | @names or return Imager->_set_error(Imager->_error_as_msg); | |
156 | ||
157 | return @names if wantarray; | |
158 | return pop @names; | |
159 | } | |
160 | ||
161 | sub is_mm { | |
162 | my ($self) = @_; | |
163 | ||
164 | i_ft2_is_multiple_master($self->{id}); | |
165 | } | |
166 | ||
167 | sub mm_axes { | |
168 | my ($self) = @_; | |
169 | ||
170 | my ($num_axis, $num_design, @axes) = | |
171 | i_ft2_get_multiple_masters($self->{id}) | |
172 | or return Imager->_set_error(Imager->_error_as_msg); | |
173 | ||
174 | return @axes; | |
175 | } | |
176 | ||
177 | sub set_mm_coords { | |
178 | my ($self, %opts) = @_; | |
179 | ||
180 | $opts{coords} | |
181 | or return Imager->_set_error("Missing coords parameter"); | |
182 | ref($opts{coords}) && $opts{coords} =~ /ARRAY\(0x[\da-f]+\)$/ | |
183 | or return Imager->_set_error("coords parameter must be an ARRAY ref"); | |
184 | ||
185 | i_ft2_set_mm_coords($self->{id}, @{$opts{coords}}) | |
186 | or return Imager->_set_error(Imager->_error_as_msg); | |
187 | ||
188 | return 1; | |
189 | } | |
190 | 1; | |
191 | ||
192 | __END__ | |
193 | ||
194 | =head1 NAME | |
195 | ||
196 | Imager::Font::FT2 - font support using FreeType 2 | |
197 | ||
198 | =head1 SYNOPSIS | |
199 | ||
200 | use Imager; | |
201 | ||
202 | my $img = Imager->new; | |
203 | my $font = Imager::Font->new(file => "foo.ttf", type => "ft2"); | |
204 | ||
205 | $img->string(... font => $font); | |
206 | ||
207 | =head1 DESCRIPTION | |
208 | ||
209 | This provides font support on FreeType 2. | |
210 | ||
211 | =head1 CAVEATS | |
212 | ||
213 | Unfortunately, older versions of Imager would install | |
214 | C<Imager::Font::FreeType2> even if FreeType 2 wasn't available, and if | |
215 | no font was created would succeed in loading the module. This means | |
216 | that an existing C<FreeType2.pm> could cause a probe success for | |
217 | supported font files, so I've renamed it. | |
218 | ||
219 | =head1 AUTHOR | |
220 | ||
5b480b14 | 221 | Tony Cook <tonyc@cpan.org> |
50c75381 TC |
222 | |
223 | =head1 SEE ALSO | |
224 | ||
225 | Imager, Imager::Font. | |
226 | ||
227 | =cut |