File Coverage

blib/lib/PDF/API3/Compat/API2/Resource/CIDFont/CJKFont.pm
Criterion Covered Total %
statement 33 130 25.3
branch 0 36 0.0
condition 0 44 0.0
subroutine 11 18 61.1
pod 3 5 60.0
total 47 233 20.1


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: CJKFont.pm,v 2.1 2007/03/17 20:38:51 areibens Exp $
31             #
32             #=======================================================================
33             package PDF::API3::Compat::API2::Resource::CIDFont::CJKFont;
34            
35             BEGIN {
36            
37 1     1   6 use utf8;
  1         3  
  1         10  
38 1     1   29 use Encode qw(:all);
  1         2  
  1         310  
39            
40 1     1   6 use PDF::API3::Compat::API2::Util;
  1         2  
  1         190  
41 1     1   6 use PDF::API3::Compat::API2::Basic::PDF::Utils;
  1         3  
  1         149  
42 1     1   6 use PDF::API3::Compat::API2::Resource::CIDFont;
  1         2  
  1         20  
43            
44 1     1   5 use PDF::API3::Compat::API2::Basic::TTF::Font;
  1         2  
  1         24  
45            
46 1     1   5 use POSIX;
  1         2  
  1         9  
47            
48 1     1   2553 use vars qw( @ISA $fonts $cmap $alias $subs $VERSION );
  1         2  
  1         172  
49            
50 1     1   30 @ISA = qw( PDF::API3::Compat::API2::Resource::CIDFont );
51            
52 1         12 ( $VERSION ) = sprintf '%i.%03i', split(/\./,('$Revision: 2.1 $' =~ /Revision: (\S+)\s/)[0]); # $Date: 2007/03/17 20:38:51 $
53            
54 1         4 $fonts = { };
55 1         29 $cmap = { };
56             }
57 1     1   6 no warnings qw[ deprecated recursion uninitialized ];
  1         3  
  1         15928  
58            
59             =item $font = PDF::API3::Compat::API2::Resource::CIDFont::CJKFont->new $pdf, $cjkname, %options
60            
61             Returns a cjk-font object.
62            
63             Traditional Chinese: Ming Ming-Bold Ming-Italic Ming-BoldItalic
64            
65             Simplified Chinese: Song Song-Bold Song-Italic Song-BoldItalic
66            
67             Korean: MyungJo MyungJo-Bold MyungJo-Italic MyungJo-BoldItalic
68            
69             Japanese (Mincho): KozMin KozMin-Bold KozMin-Italic KozMin-BoldItalic
70            
71             Japanese (Gothic): KozGo KozGo-Bold KozGo-Italic KozGo-BoldItalic
72            
73             Defined Options:
74            
75             -encode ... specify fonts encoding for non-utf8 text.
76            
77             =cut
78            
79             sub _look_for_font {
80 0     0     my $fname=lc(shift);
81 0           $fname=~s/[^a-z0-9]+//gi;
82 0 0         $fname=$alias->{$fname} if(defined $alias->{$fname});
83 0 0         return({%{$fonts->{$fname}}}) if(defined $fonts->{$fname});
  0            
84            
85 0 0         if(defined $subs->{$fname}) {
86 0           $data=_look_for_font($subs->{$fname}->{-alias});
87 0           foreach my $k (keys %{$subs->{$fname}}) {
  0            
88 0 0         next if($k=~/^\-/);
89 0 0         if(substr($k,0,1) eq '+')
90             {
91 0           $data->{substr($k,1)}.=$subs->{$fname}->{$k};
92             }
93             else
94             {
95 0           $data->{$k}=$subs->{$fname}->{$k};
96             }
97             }
98 0           $fonts->{$fname}=$data;
99 0           return({%{$data}})
  0            
100             }
101            
102 0           eval "require PDF::API3::Compat::API2::Resource::CIDFont::CJKFont::$fname; ";
103 0 0         unless($@){
104 0           return({%{$fonts->{$fname}}});
  0            
105             } else {
106 0           die "requested font '$fname' not installed ";
107             }
108             }
109            
110             sub _look_for_cmap ($) {
111 0     0     my $fname=lc(shift);
112 0           $fname=~s/[^a-z0-9]+//gi;
113 0 0         return({%{$cmap->{$fname}}}) if(defined $cmap->{$fname});
  0            
114 0           eval "require PDF::API3::Compat::API2::Resource::CIDFont::CMap::$fname; ";
115 0 0         unless($@){
116 0           return({%{$cmap->{$fname}}});
  0            
117             } else {
118 0           die "requested cmap '$fname' not installed ";
119             }
120             }
121             sub new {
122 0     0 1   my ($class,$pdf,$name,@opts) = @_;
123 0           my %opts=();
124 0 0         %opts=@opts if((scalar @opts)%2 == 0);
125 0   0       $opts{-encode}||='ident';
126            
127 0           my $data = _look_for_font($name);
128            
129 0           my $cmap = _look_for_cmap($data->{cmap});
130            
131 0           $data->{u2g} = { %{$cmap->{u2g}} };
  0            
132 0           $data->{g2u} = [ @{$cmap->{g2u}} ];
  0            
133            
134 0 0         $class = ref $class if ref $class;
135 0           my $self=$class->SUPER::new($pdf,$data->{apiname}.pdfkey());
136 0 0 0       $pdf->new_obj($self) if(defined($pdf) && !$self->is_obj($pdf));
137            
138 0           $self->{' data'}=$data;
139            
140 0           my $des=$self->descrByData;
141            
142 0           my $de=$self->{' de'};
143            
144 0 0 0       if(defined $opts{-encode} && $opts{-encode} ne 'ident') {
145 0           $self->data->{encode}=$opts{-encode};
146             }
147            
148 0           my $emap={
149             'reg'=>'Adobe',
150             'ord'=>'Identity',
151             'sup'=> 0,
152             'map'=>'Identity',
153             'dir'=>'H',
154             'dec'=>'ident',
155             };
156            
157 0 0         if(defined $cmap->{ccs}) {
158 0           $emap->{reg}=$cmap->{ccs}->[0];
159 0           $emap->{ord}=$cmap->{ccs}->[1];
160 0           $emap->{sup}=$cmap->{ccs}->[2];
161             }
162            
163             #if(defined $cmap->{cmap} && defined $cmap->{cmap}->{$opts{-encode}} ) {
164             # $emap->{dec}=$cmap->{cmap}->{$opts{-encode}}->[0];
165             # $emap->{map}=$cmap->{cmap}->{$opts{-encode}}->[1];
166             #} elsif(defined $cmap->{cmap} && defined $cmap->{cmap}->{'utf8'} ) {
167             # $emap->{dec}=$cmap->{cmap}->{'utf8'}->[0];
168             # $emap->{map}=$cmap->{cmap}->{'utf8'}->[1];
169             #}
170            
171 0           $self->data->{decode}=$emap->{dec};
172            
173 0           $self->{'BaseFont'} = PDFName($self->fontname."-$emap->{map}-$emap->{dir}");
174 0           $self->{'Encoding'} = PDFName("$emap->{map}-$emap->{dir}");
175            
176 0           $de->{'FontDescriptor'} = $des;
177 0           $de->{'Subtype'} = PDFName('CIDFontType0');
178 0           $de->{'BaseFont'} = PDFName($self->fontname);
179 0           $de->{'DW'} = PDFNum($self->missingwidth);
180 0           $de->{'CIDSystemInfo'}->{Registry} = PDFStr($emap->{reg});
181 0           $de->{'CIDSystemInfo'}->{Ordering} = PDFStr($emap->{ord});
182 0           $de->{'CIDSystemInfo'}->{Supplement} = PDFNum($emap->{sup});
183             ## $de->{'CIDToGIDMap'} = PDFName($emap->{map}); # ttf only
184            
185 0           return($self);
186             }
187            
188             =item $font = PDF::API3::Compat::API2::Resource::CIDFont::CJKFont->new_api $api, $cjkname, %options
189            
190             Returns a cjk-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           $self->{' api'}=$api;
200            
201 0           $api->{pdf}->out_obj($api->{pages});
202 0           return($obj);
203             }
204            
205             sub tounicodemap {
206 0     0 0   my $self=shift @_;
207             # noop since pdf knows its char-collection
208 0           return($self);
209             }
210            
211             sub glyphByCId
212             {
213 0     0 0   my ($self,$cid)=@_;
214 0           my $uni = $self->uniByCId($cid);
215 0           return( nameByUni($uni) );
216             }
217            
218             sub outobjdeep {
219 0     0 1   my ($self, $fh, $pdf, %opts) = @_;
220            
221 0 0         return $self->SUPER::outobjdeep($fh, $pdf) if defined $opts{'passthru'};
222            
223 0           my $notdefbefore=1;
224            
225 0           my $wx=PDFArray();
226 0           $self->{' de'}->{'W'} = $wx;
227 0           my $ml;
228            
229 0           foreach my $w (0..(scalar @{$self->data->{g2u}} - 1 )) {
  0            
230 0 0 0       if(ref($self->data->{wx}) eq 'ARRAY'
    0 0        
    0 0        
    0 0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
231             && (defined $self->data->{wx}->[$w])
232             && ($self->data->{wx}->[$w] != $self->missingwidth)
233             && $notdefbefore==1)
234             {
235 0           $notdefbefore=0;
236 0           $ml=PDFArray();
237 0           $wx->add_elements(PDFNum($w),$ml);
238 0           $ml->add_elements(PDFNum($self->data->{wx}->[$w]));
239             }
240             elsif(ref($self->data->{wx}) eq 'HASH'
241             && (defined $self->data->{wx}->{$w})
242             && ($self->data->{wx}->{$w} != $self->missingwidth)
243             && $notdefbefore==1)
244             {
245 0           $notdefbefore=0;
246 0           $ml=PDFArray();
247 0           $wx->add_elements(PDFNum($w),$ml);
248 0           $ml->add_elements(PDFNum($self->data->{wx}->{$w}));
249             }
250             elsif(ref($self->data->{wx}) eq 'ARRAY'
251             && (defined $self->data->{wx}->[$w])
252             && ($self->data->{wx}->[$w] != $self->missingwidth)
253             && $notdefbefore==0)
254             {
255 0           $notdefbefore=0;
256 0           $ml->add_elements(PDFNum($self->data->{wx}->[$w]));
257             }
258             elsif(ref($self->data->{wx}) eq 'HASH'
259             && (defined $self->data->{wx}->{$w})
260             && ($self->data->{wx}->{$w} != $self->missingwidth)
261             && $notdefbefore==0)
262             {
263 0           $notdefbefore=0;
264 0           $ml->add_elements(PDFNum($self->data->{wx}->{$w}));
265             }
266             else
267             {
268 0           $notdefbefore=1;
269             }
270             }
271            
272 0           $self->SUPER::outobjdeep($fh, $pdf, %opts);
273             }
274            
275             BEGIN {
276            
277 1     1   25 $alias={
278             'traditional' => 'adobemingstdlightacro',
279             'traditionalbold' => 'mingbold',
280             'traditionalitalic' => 'mingitalic',
281             'traditionalbolditalic' => 'mingbolditalic',
282             'ming' => 'adobemingstdlightacro',
283            
284             'simplified' => 'adobesongstdlightacro',
285             'simplifiedbold' => 'songbold',
286             'simplifieditalic' => 'songitalic',
287             'simplifiedbolditalic' => 'songbolditalic',
288             'song' => 'adobesongstdlightacro',
289            
290             'korean' => 'adobemyungjostdmediumacro',
291             'koreanbold' => 'myungjobold',
292             'koreanitalic' => 'myungjoitalic',
293             'koreanbolditalic' => 'myungjobolditalic',
294             'myungjo' => 'adobemyungjostdmediumacro',
295            
296             'japanese' => 'kozminproregularacro',
297             'japanesebold' => 'kozminbold',
298             'japaneseitalic' => 'kozminitalic',
299             'japanesebolditalic' => 'kozminbolditalic',
300             'kozmin' => 'kozminproregularacro',
301             'kozgo' => 'kozgopromediumacro',
302            
303             };
304 1         70 $subs={
305             # Chinese Traditional (ie. Taiwan) Fonts
306             'mingitalic' => {
307             '-alias' => 'adobemingstdlightacro',
308             '+fontname' => ',Italic',
309             },
310             'mingbold' => {
311             '-alias' => 'adobemingstdlightacro',
312             '+fontname' => ',Bold',
313             },
314             'mingbolditalic' => {
315             '-alias' => 'adobemingstdlightacro',
316             '+fontname' => ',BoldItalic',
317             },
318             # Chinese Simplified (ie. Mainland China) Fonts
319             'songitalic' => {
320             '-alias' => 'adobesongstdlightacro',
321             '+fontname' => ',Italic',
322             },
323             'songbold' => {
324             '-alias' => 'adobesongstdlightacro',
325             '+fontname' => ',Bold',
326             },
327             'songbolditalic' => {
328             '-alias' => 'adobesongstdlightacro',
329             '+fontname' => ',BoldItalic',
330             },
331             # Japanese Gothic (ie. sans) Fonts
332             'kozgoitalic' => {
333             '-alias' => 'kozgopromediumacro',
334             '+fontname' => ',Italic',
335             },
336             'kozgobold' => {
337             '-alias' => 'kozgopromediumacro',
338             '+fontname' => ',Bold',
339             },
340             'kozgobolditalic' => {
341             '-alias' => 'kozgopromediumacro',
342             '+fontname' => ',BoldItalic',
343             },
344             # Japanese Mincho (ie. serif) Fonts
345             'kozminitalic' => {
346             '-alias' => 'kozminproregularacro',
347             '+fontname' => ',Italic',
348             },
349             'kozminbold' => {
350             '-alias' => 'kozminproregularacro',
351             '+fontname' => ',Bold',
352             },
353             'kozminbolditalic' => {
354             '-alias' => 'kozminproregularacro',
355             '+fontname' => ',BoldItalic',
356             },
357             # Korean Fonts
358             'myungjoitalic' => {
359             '-alias' => 'adobemyungjostdmediumacro',
360             '+fontname' => ',Italic',
361             },
362             'myungjobold' => {
363             '-alias' => 'adobemyungjostdmediumacro',
364             '+fontname' => ',Bold',
365             },
366             'myungjobolditalic' => {
367             '-alias' => 'adobemyungjostdmediumacro',
368             '+fontname' => ',BoldItalic',
369             },
370             };
371            
372             }
373             1;
374            
375             __END__