File Coverage

blib/lib/PDF/API3/Compat/API2/Resource/CIDFont.pm
Criterion Covered Total %
statement 26 173 15.0
branch 0 68 0.0
condition 0 62 0.0
subroutine 9 35 25.7
pod 10 25 40.0
total 45 363 12.4


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: CIDFont.pm,v 2.3 2007/03/17 20:38:50 areibens Exp $
31             #
32             #=======================================================================
33             package PDF::API3::Compat::API2::Resource::CIDFont;
34            
35             BEGIN
36             {
37            
38 1     1   5 use utf8;
  1         3  
  1         6  
39 1     1   29 use Encode qw(:all);
  1         213  
  1         282  
40            
41 1     1   7 use PDF::API3::Compat::API2::Util;
  1         2  
  1         166  
42 1     1   5 use PDF::API3::Compat::API2::Basic::PDF::Utils;
  1         1  
  1         114  
43 1     1   6 use PDF::API3::Compat::API2::Resource::BaseFont;
  1         2  
  1         37  
44            
45 1     1   4 use POSIX;
  1         2  
  1         8  
46            
47 1     1   2863 use vars qw(@ISA $VERSION);
  1         3  
  1         144  
48            
49 1     1   26 @ISA = qw( PDF::API3::Compat::API2::Resource::BaseFont );
50            
51 1         45 ( $VERSION ) = sprintf '%i.%03i', split(/\./,('$Revision: 2.3 $' =~ /Revision: (\S+)\s/)[0]); # $Date: 2007/03/17 20:38:50 $
52             }
53            
54 1     1   7 no warnings qw[ deprecated recursion uninitialized ];
  1         2  
  1         2588  
55            
56             =item $font = PDF::API3::Compat::API2::Resource::CIDFont->new $pdf, $name
57            
58             Returns a cid-font object. base class form all CID based fonts.
59            
60             =cut
61            
62             sub new
63             {
64 0     0 1   my ($class,$pdf,$name,@opts) = @_;
65 0           my %opts=();
66 0 0         %opts=@opts if((scalar @opts)%2 == 0);
67            
68 0 0         $class = ref $class if ref $class;
69 0           my $self=$class->SUPER::new($pdf,$name);
70 0 0 0       $pdf->new_obj($self) if(defined($pdf) && !$self->is_obj($pdf));
71            
72 0           $self->{Type} = PDFName('Font');
73 0           $self->{'Subtype'} = PDFName('Type0');
74 0           $self->{'Encoding'} = PDFName('Identity-H');
75            
76 0           my $de=PDFDict();
77 0           $pdf->new_obj($de);
78 0           $self->{'DescendantFonts'} = PDFArray($de);
79            
80 0           $de->{'Type'} = PDFName('Font');
81 0           $de->{'CIDSystemInfo'} = PDFDict();
82 0           $de->{'CIDSystemInfo'}->{Registry} = PDFStr('Adobe');
83 0           $de->{'CIDSystemInfo'}->{Ordering} = PDFStr('Identity');
84 0           $de->{'CIDSystemInfo'}->{Supplement} = PDFNum(0);
85 0           $de->{'CIDToGIDMap'} = PDFName('Identity');
86            
87 0           $self->{' de'} = $de;
88            
89 0           return($self);
90             }
91            
92             =item $font = PDF::API3::Compat::API2::Resource::CIDFont->new_api $api, $name, %options
93            
94             Returns a cid-font object. This method is different from 'new' that
95             it needs an PDF::API3::Compat::API2-object rather than a Text::PDF::File-object.
96            
97             =cut
98            
99             sub new_api
100             {
101 0     0 1   my ($class,$api,@opts)=@_;
102            
103 0           my $obj=$class->new($api->{pdf},@opts);
104 0           $self->{' api'}=$api;
105            
106 0           $api->{pdf}->out_obj($api->{pages});
107 0           return($obj);
108             }
109            
110 0     0 0   sub glyphByCId { return( $_[0]->data->{g2n}->[$_[1]] ); }
111            
112 0     0 0   sub uniByCId { return( $_[0]->data->{g2u}->[$_[1]] ); }
113            
114 0     0 0   sub cidByUni { return( $_[0]->data->{u2g}->{$_[1]} ); }
115            
116 0     0 0   sub cidByEnc { return( $_[0]->data->{e2g}->[$_[1]] ); }
117            
118             sub wxByCId
119             {
120 0     0 0   my $self=shift @_;
121 0           my $g=shift @_;
122 0           my $w;
123            
124 0 0 0       if(ref($self->data->{wx}) eq 'ARRAY' && defined $self->data->{wx}->[$g])
    0 0        
125             {
126 0           $w = int($self->data->{wx}->[$g]);
127             }
128             elsif(ref($self->data->{wx}) eq 'HASH' && defined $self->data->{wx}->{$g})
129             {
130 0           $w = int($self->data->{wx}->{$g});
131             }
132             else
133             {
134 0           $w = $self->missingwidth;
135             }
136            
137 0           return($w);
138             }
139            
140 0     0 1   sub wxByUni { return( $_[0]->wxByCId($_[0]->data->{u2g}->{$_[1]}) ); }
141 0     0 1   sub wxByEnc { return( $_[0]->wxByCId($_[0]->data->{e2g}->[$_[1]]) ); }
142            
143             sub width
144             {
145 0     0 1   my ($self,$text)=@_;
146 0           return($self->width_cid($self->cidsByStr($text)));
147             }
148            
149             sub width_cid
150             {
151 0     0 0   my ($self,$text)=@_;
152 0           my $width=0;
153 0           my $lastglyph=0;
154 0           foreach my $n (unpack('n*',$text))
155             {
156 0           $width+=$self->wxByCId($n);
157 0 0 0       if($self->{-dokern} && $self->haveKernPairs())
158             {
159 0 0         if($self->kernPairCid($lastglyph, $n))
160             {
161 0           $width-=$self->kernPairCid($lastglyph, $n);
162             }
163             }
164 0           $lastglyph=$n;
165             }
166 0           $width/=1000;
167 0           return($width);
168             }
169            
170             =item $cidstring = $font->cidsByStr $string
171            
172             Returns the cid-string from string based on the fonts encoding map.
173            
174             =cut
175            
176             sub _cidsByStr
177             {
178 0     0     my ($self,$s)=@_;
179 0           $s=pack('n*',map { $self->cidByEnc($_) } unpack('C*',$s));
  0            
180 0           return($s);
181             }
182            
183             sub cidsByStr
184             {
185 0     0 1   my ($self,$text)=@_;
186 0 0 0       if(is_utf8($text) && defined $self->data->{decode} && $self->data->{decode} ne 'ident')
    0 0        
    0 0        
    0 0        
      0        
      0        
      0        
      0        
187             {
188 0           $text=encode($self->data->{decode},$text);
189             }
190             elsif(is_utf8($text) && $self->data->{decode} eq 'ident')
191             {
192 0           $text=$self->cidsByUtf($text);
193             }
194             elsif(!is_utf8($text) && defined $self->data->{encode} && $self->data->{decode} eq 'ident')
195             {
196 0           $text=$self->cidsByUtf(decode($self->data->{encode},$text));
197             }
198             elsif(!is_utf8($text) && UNIVERSAL::can($self,'issymbol') && $self->issymbol && $self->data->{decode} eq 'ident')
199             {
200 0           $text=pack('U*',(map { $_+0xf000 } unpack('C*',$text)));
  0            
201 0           $text=$self->cidsByUtf($text);
202             }
203             else
204             {
205 0           $text=$self->_cidsByStr($text);
206             }
207 0           return($text);
208             }
209            
210             =item $cidstring = $font->cidsByUtf $utf8string
211            
212             Returns the cid-encoded string from utf8-string.
213            
214             =cut
215            
216             sub cidsByUtf {
217 0     0 1   my ($self,$s)=@_;
218 0 0 0       $s=pack('n*',map { $self->cidByUni($_) } (map { $_>0x7f && $_<0xA0 ? uniByName(nameByUni($_)): $_ } unpack('U*',$s)));
  0            
  0            
219 0           utf8::downgrade($s);
220 0           return($s);
221             }
222            
223             sub textByStr
224             {
225 0     0 1   my ($self,$text)=@_;
226 0           return($self->text_cid($self->cidsByStr($text)));
227             }
228            
229             sub textByStrKern
230             {
231 0     0 0   my ($self,$text,$size,$ident)=@_;
232 0           return($self->text_cid_kern($self->cidsByStr($text),$size,$ident));
233             }
234            
235             sub text
236             {
237 0     0 0   my ($self,$text,$size,$ident)=@_;
238 0           my $newtext=$self->textByStr($text);
239 0 0 0       if(defined $size && $self->{-dokern})
    0          
240             {
241 0           $newtext=$self->textByStrKern($text,$size,$ident);
242 0           return($newtext);
243             }
244             elsif(defined $size)
245             {
246 0 0 0       if(defined($ident) && $ident!=0)
247             {
248 0           return("[ $ident $newtext ] TJ");
249             }
250             else
251             {
252 0           return("$newtext Tj");
253             }
254             }
255             else
256             {
257 0           return($newtext);
258             }
259             }
260            
261             sub text_cid
262             {
263 0     0 0   my ($self,$text,$size)=@_;
264 0 0         if(UNIVERSAL::can($self,'fontfile'))
265             {
266 0           foreach my $g (unpack('n*',$text))
267             {
268 0           $self->fontfile->subsetByCId($g);
269             }
270             }
271 0           my $newtext=unpack('H*',$text);
272 0 0         if(defined $size)
273             {
274 0           return("<$newtext> Tj");
275             }
276             else
277             {
278 0           return("<$newtext>");
279             }
280             }
281            
282             sub text_cid_kern
283             {
284 0     0 0   my ($self,$text,$size,$ident)=@_;
285 0 0         if(UNIVERSAL::can($self,'fontfile'))
286             {
287 0           foreach my $g (unpack('n*',$text))
288             {
289 0           $self->fontfile->subsetByCId($g);
290             }
291             }
292 0 0 0       if(defined $size && $self->{-dokern} && $self->haveKernPairs())
    0 0        
293             {
294 0           my $newtext=' ';
295 0           my $lastglyph=0;
296 0           my $tBefore=0;
297 0           foreach my $n (unpack('n*',$text))
298             {
299 0 0         if($self->kernPairCid($lastglyph, $n))
300             {
301 0 0         $newtext.='> ' if($tBefore);
302 0           $newtext.=sprintf('%i ',$self->kernPairCid($lastglyph, $n));
303 0           $tBefore=0;
304             }
305 0           $lastglyph=$n;
306 0           my $t=sprintf('%04X',$n);
307 0 0         $newtext.='<' if(!$tBefore);
308 0           $newtext.=$t;
309 0           $tBefore=1;
310             }
311 0 0         $newtext.='> ' if($tBefore);
312 0 0 0       if(defined($ident) && $ident!=0)
313             {
314 0           return("[ $ident $newtext ] TJ");
315             }
316             else
317             {
318 0           return("[ $newtext ] TJ");
319             }
320             }
321             elsif(defined $size)
322             {
323 0           my $newtext=unpack('H*',$text);
324 0 0 0       if(defined($ident) && $ident!=0)
325             {
326 0           return("[ $ident <$newtext> ] TJ");
327             }
328             else
329             {
330 0           return("<$newtext> Tj");
331             }
332             }
333             else
334             {
335 0           my $newtext=unpack('H*',$text);
336 0           return("<$newtext>");
337             }
338             }
339            
340             sub kernPairCid
341             {
342 0     0 0   return(0);
343             }
344            
345             sub haveKernPairs
346             {
347 0     0 0   return(0);
348             }
349            
350             sub encodeByName
351             {
352 0     0 0   my ($self,$enc) = @_;
353 0 0         return if($self->issymbol);
354            
355 0 0 0       $self->data->{e2u}=[ map { $_>0x7f && $_<0xA0 ? uniByName(nameByUni($_)): $_ } unpack('U*',decode($enc, pack('C*',0..255))) ] if(defined $enc);
  0 0          
356 0 0 0       $self->data->{e2n}=[ map { $self->data->{g2n}->[$self->data->{u2g}->{$_} || 0] || '.notdef' } @{$self->data->{e2u}} ];
  0            
  0            
357 0 0         $self->data->{e2g}=[ map { $self->data->{u2g}->{$_} || 0 } @{$self->data->{e2u}} ];
  0            
  0            
358            
359 0           $self->data->{u2e}={};
360 0           foreach my $n (reverse 0..255)
361             {
362 0 0         $self->data->{u2e}->{$self->data->{e2u}->[$n]}=$n unless(defined $self->data->{u2e}->{$self->data->{e2u}->[$n]});
363             }
364            
365 0           return($self);
366             }
367            
368             sub subsetByCId
369             {
370 0     0 0   return(1);
371             }
372            
373             sub subvec
374             {
375 0     0 0   return(1);
376             }
377            
378             sub glyphNum
379             {
380 0     0 1   my $self=shift @_;
381 0 0         if(defined $self->data->{glyphs})
382             {
383 0           return ( $self->data->{glyphs} );
384             }
385 0           return ( scalar @{$self->data->{wx}} );
  0            
386             }
387            
388             sub outobjdeep
389             {
390 0     0 1   my ($self, $fh, $pdf, %opts) = @_;
391            
392 0 0         return $self->SUPER::outobjdeep($fh, $pdf) if defined $opts{'passthru'};
393            
394 0           $self->SUPER::outobjdeep($fh, $pdf, %opts);
395             }
396            
397            
398             1;
399            
400             __END__