File Coverage

blib/lib/PDF/API3/Compat/API2/Resource/UniFont.pm
Criterion Covered Total %
statement 19 112 16.9
branch 0 40 0.0
condition 0 15 0.0
subroutine 7 13 53.8
pod 2 6 33.3
total 28 186 15.0


line stmt bran cond sub pod time code
1             #=======================================================================
2             # ____ ____ _____ _ ____ ___ ____
3             # | _ \| _ \| ___| _ _ / \ | _ \_ _| |___ \
4             # | |_) | | | | |_ (_) (_) / _ \ | |_) | | __) |
5             # | __/| |_| | _| _ _ / ___ \| __/| | / __/
6             # |_| |____/|_| (_) (_) /_/ \_\_| |___| |_____|
7             #
8             # A Perl Module Chain to faciliate the Creation and Modification
9             # of High-Quality "Portable Document Format (PDF)" Files.
10             #
11             # Copyright 1999-2005 Alfred Reibenschuh .
12             #
13             #=======================================================================
14             #
15             # This library is free software; you can redistribute it and/or
16             # modify it under the terms of the GNU Lesser General Public
17             # License as published by the Free Software Foundation; either
18             # version 2 of the License, or (at your option) any later version.
19             #
20             # This library is distributed in the hope that it will be useful,
21             # but WITHOUT ANY WARRANTY; without even the implied warranty of
22             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23             # Lesser General Public License for more details.
24             #
25             # You should have received a copy of the GNU Lesser General Public
26             # License along with this library; if not, write to the
27             # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28             # Boston, MA 02111-1307, USA.
29             #
30             # $Id: UniFont.pm,v 2.1 2007/01/04 16:02:28 areibens Exp $
31             #
32             #=======================================================================
33             package PDF::API3::Compat::API2::Resource::UniFont;
34            
35             BEGIN {
36            
37 1     1   8 use utf8;
  1         3  
  1         10  
38 1     1   39 use Encode qw(:all);
  1         2  
  1         430  
39            
40 1     1   7 use PDF::API3::Compat::API2::Util;
  1         3  
  1         236  
41            
42 1     1   15 use POSIX;
  1         4  
  1         12  
43            
44 1     1   2856 use vars qw($VERSION);
  1         2  
  1         126  
45            
46 1     1   42 ( $VERSION ) = sprintf '%i.%03i', split(/\./,('$Revision: 2.1 $' =~ /Revision: (\S+)\s/)[0]); # $Date: 2007/01/04 16:02:28 $
47            
48             }
49 1     1   6 no warnings qw[ deprecated recursion uninitialized ];
  1         3  
  1         1315  
50            
51             =item $font = PDF::API3::Compat::API2::Resource::UniFont->new $pdf, @fontspecs, %options
52            
53             Returns a uni-font object.
54            
55             =cut
56            
57             =pod
58            
59             B fonts can be registered using the following hash-ref:
60            
61             {
62             font => $fontobj, # the font to be registered
63             blocks => $blockspec, # the unicode blocks, the font is being registered for
64             codes => $codespec, # the unicode codepoints, -"-
65             }
66            
67             B
68            
69             [
70             $block1, $block3, # register font for block 1 + 3
71             [$blockA,$blockZ], # register font for blocks A .. Z
72             ]
73            
74             B
75            
76             [
77             $cp1, $cp3, # register font for codepoint 1 + 3
78             [$cpA,$cpZ], # register font for codepoints A .. Z
79             ]
80            
81             B if you want to register a font for the entire unicode space
82             (ie. U+0000 .. U+FFFF), then simply specify a font-object without the hash-ref.
83            
84            
85             Valid %options are:
86            
87             '-encode' ... changes the encoding of the font from its default.
88             (see "perldoc Encode" for a list of valid tags)
89            
90             =cut
91            
92             sub new {
93 0     0 1   my ($class,$pdf,@fonts) = @_;
94            
95 0 0         $class = ref $class if ref $class;
96 0           my $self={
97             fonts=>[],
98             block=>{},
99             code=>{},
100             };
101 0           bless $self,$class;
102            
103 0           $self->{pdf}=$pdf;
104            
105             # look at all fonts
106 0           my $fn=0;
107 0           while (ref $fonts[0])
108             {
109 0           my $font=shift @fonts;
110 0 0         if(ref($font) eq 'ARRAY')
    0          
111             {
112 0           push @{$self->{fonts}},$font->[0];
  0            
113 0           shift @{$font};
  0            
114 0           while(defined $font->[0])
115             {
116 0           my $r0=shift @{$font};
  0            
117 0 0         if(ref $r0)
118             {
119 0           foreach my $b ($r0->[0]..$r0->[-1])
120             {
121 0           $self->{block}->{$b}=$fn;
122             }
123             }
124             else
125             {
126 0           $self->{block}->{$r0}=$fn;
127             }
128             }
129             }
130             elsif(ref($font) eq 'HASH')
131             {
132 0           push @{$self->{fonts}},$font->{font};
  0            
133            
134 0 0 0       if(defined $font->{blocks} && ref($font->{blocks}) eq 'ARRAY')
135             {
136 0           foreach my $r0 (@{$font->{blocks}})
  0            
137             {
138 0 0         if(ref $r0)
139             {
140 0           foreach my $b ($r0->[0]..$r0->[-1])
141             {
142 0           $self->{block}->{$b}=$fn;
143             }
144             }
145             else
146             {
147 0           $self->{block}->{$r0}=$fn;
148             }
149             }
150             }
151            
152 0 0 0       if(defined $font->{codes} && ref($font->{codes}) eq 'ARRAY')
153             {
154 0           foreach my $r0 (@{$font->{codes}})
  0            
155             {
156 0 0         if(ref $r0)
157             {
158 0           foreach my $b ($r0->[0]..$r0->[-1])
159             {
160 0           $self->{code}->{$b}=$fn;
161             }
162             }
163             else
164             {
165 0           $self->{code}->{$r0}=$fn;
166             }
167             }
168             }
169             }
170             else
171             {
172 0           push @{$self->{fonts}},$font;
  0            
173 0           foreach my $b (0..255)
174             {
175 0           $self->{block}->{$b}=$fn;
176             }
177             }
178 0           $fn++;
179             }
180            
181 0           my %opts=@fonts;
182            
183 0 0         $self->{encode}=$opts{-encode} if(defined $opts{-encode});
184            
185 0           return($self);
186             }
187            
188             =item $font = PDF::API3::Compat::API2::Resource::UniFont->new_api $api, $name, %options
189            
190             Returns a uni-font object. This method is different from 'new' that
191             it needs an PDF::API3::Compat::API2-object rather than a Text::PDF::File-object.
192            
193             =cut
194            
195             sub new_api {
196 0     0 1   my ($class,$api,@opts)=@_;
197            
198 0           my $obj=$class->new($api->{pdf},@opts);
199 0           $obj->{api}=$api;
200            
201 0           return($obj);
202             }
203            
204 0     0 0   sub isvirtual { return(1); }
205            
206             sub fontlist
207             {
208 0     0 0   my ($self)=@_;
209 0           return [@{$self->{fonts}}];
  0            
210             }
211            
212             sub width {
213 0     0 0   my ($self,$text)=@_;
214 0 0         $text=decode($self->{encode},$text) unless(is_utf8($text));
215 0           my $width=0;
216 0           if(1)
217             {
218 0           my @blks=();
219 0           foreach my $u (unpack('U*',$text))
220             {
221 0           my $fn=0;
222 0 0         if(defined $self->{code}->{$u})
    0          
223             {
224 0           $fn=$self->{code}->{$u};
225             }
226             elsif(defined $self->{block}->{($u>>8)})
227             {
228 0           $fn=$self->{block}->{($u>>8)};
229             }
230             else
231             {
232 0           $fn=0;
233             }
234 0 0 0       if(scalar @blks==0 || $blks[-1]->[0]!=$fn)
235             {
236 0           push @blks,[$fn,pack('U',$u)];
237             }
238             else
239             {
240 0           $blks[-1]->[1].=pack('U',$u);
241             }
242             }
243 0           foreach my $blk (@blks)
244             {
245 0           $width+=$self->fontlist->[$blk->[0]]->width($blk->[1]);
246             }
247             }
248             else
249             {
250             foreach my $u (unpack('U*',$text))
251             {
252             if(defined $self->{code}->{$u})
253             {
254             $width+=$self->fontlist->[$self->{code}->{$u}]->width(pack('U',$u));
255             }
256             elsif(defined $self->{block}->{($u>>8)})
257             {
258             $width+=$self->fontlist->[$self->{block}->{($u>>8)}]->width(pack('U',$u));
259             }
260             else
261             {
262             $width+=$self->fontlist->[0]->width(pack('U',$u));
263             }
264             }
265             }
266            
267 0           return($width);
268             }
269            
270             sub text
271             {
272 0     0 0   my ($self,$text,$size,$ident)=@_;
273 0 0         $text=decode($self->{encode},$text) unless(is_utf8($text));
274 0 0         die 'textsize not specified' unless(defined $size);
275 0           my $newtext='';
276 0           my $lastfont=-1;
277 0           my @codes=();
278            
279 0           foreach my $u (unpack('U*',$text))
280             {
281 0           my $thisfont=0;
282 0 0         if(defined $self->{code}->{$u})
    0          
283             {
284 0           $thisfont=$self->{code}->{$u};
285             }
286             elsif(defined $self->{block}->{($u>>8)})
287             {
288 0           $thisfont=$self->{block}->{($u>>8)};
289             }
290            
291 0 0 0       if($thisfont!=$lastfont && $lastfont!=-1)
292             {
293 0           my $f=$self->fontlist->[$lastfont];
294 0 0 0       if(defined($ident) && $ident!=0)
295             {
296 0           $newtext.='/'.$f->name.' '.$size.' Tf ['.$ident.' '.$f->text(pack('U*',@codes)).'] TJ ';
297 0           $ident=undef;
298             }
299             else
300             {
301 0           $newtext.='/'.$f->name.' '.$size.' Tf '.$f->text(pack('U*',@codes)).' Tj ';
302             }
303 0           @codes=();
304             }
305            
306 0           push(@codes,$u);
307 0           $lastfont=$thisfont;
308             }
309            
310 0 0         if(scalar @codes > 0)
311             {
312 0           my $f=$self->fontlist->[$lastfont];
313 0           $newtext.='/'.$f->name.' '.$size.' Tf '.$f->text(pack('U*',@codes),$size).' ';
314             }
315            
316 0           return($newtext);
317             }
318            
319             1;
320            
321             __END__