File Coverage

blib/lib/PDF/Builder/Resource/CIDFont/CJKFont.pm
Criterion Covered Total %
statement 66 108 61.1
branch 12 36 33.3
condition 3 44 6.8
subroutine 9 12 75.0
pod 2 4 50.0
total 92 204 45.1


line stmt bran cond sub pod time code
1             package PDF::Builder::Resource::CIDFont::CJKFont;
2              
3 2     2   1884 use base 'PDF::Builder::Resource::CIDFont';
  2         5  
  2         682  
4              
5 2     2   16 use strict;
  2         6  
  2         45  
6 2     2   11 use warnings;
  2         5  
  2         106  
7             #no warnings qw[ deprecated recursion uninitialized ];
8              
9             our $VERSION = '3.023'; # VERSION
10             our $LAST_UPDATE = '3.021'; # manually update whenever code is changed
11              
12 2     2   13 use PDF::Builder::Util;
  2         6  
  2         286  
13 2     2   26 use PDF::Builder::Basic::PDF::Utils;
  2         39  
  2         3608  
14              
15             our $fonts = {};
16             our $cmap = {};
17             our $alias;
18             our $subs;
19              
20             =head1 NAME
21              
22             PDF::Builder::Resource::CIDFont::CJKFont - Base class for CJK fonts
23              
24             =head1 METHODS
25              
26             =over
27              
28             =item $font = PDF::Builder::Resource::CIDFont::CJKFont->new($pdf, $cjkname, %options)
29              
30             Returns a cjk-font object.
31              
32             Traditional Chinese: Ming Ming-Bold Ming-Italic Ming-BoldItalic
33              
34             Simplified Chinese: Song Song-Bold Song-Italic Song-BoldItalic
35              
36             Korean: MyungJo MyungJo-Bold MyungJo-Italic MyungJo-BoldItalic
37              
38             Japanese (Mincho): KozMin KozMin-Bold KozMin-Italic KozMin-BoldItalic
39              
40             Japanese (Gothic): KozGo KozGo-Bold KozGo-Italic KozGo-BoldItalic
41              
42             Defined Options:
43              
44             -encode ... specify fonts encoding for non-utf8 text.
45              
46             =cut
47              
48             sub _look_for_font {
49 1     1   4 my $fname = lc(shift);
50              
51 1         5 $fname =~ s/[^a-z0-9]+//gi;
52 1 50       8 $fname = $alias->{$fname} if defined $alias->{$fname};
53 1 50       5 return {%{$fonts->{$fname}}} if defined $fonts->{$fname};
  0         0  
54              
55 1 50       4 if (defined $subs->{$fname}) {
56 0         0 my $data = _look_for_font($subs->{$fname}->{'-alias'});
57 0         0 foreach my $k (keys %{$subs->{$fname}}) {
  0         0  
58 0 0       0 next if $k=~/^\-/;
59 0 0       0 if (substr($k, 0, 1) eq '+') {
60 0         0 $data->{substr($k, 1)} .= $subs->{$fname}->{$k};
61             } else {
62 0         0 $data->{$k} = $subs->{$fname}->{$k};
63             }
64             }
65 0         0 $fonts->{$fname}=$data;
66 0         0 return ({%{$data}});
  0         0  
67             }
68              
69 1         74 eval "require 'PDF/Builder/Resource/CIDFont/CJKFont/$fname.data'"; ## no critic
70 1 50       16 unless ($@) {
71 1         4 return({%{$fonts->{$fname}}});
  1         20  
72             } else {
73 0         0 die "requested font '$fname' not installed ";
74             }
75             }
76              
77             # identical routine in Resource/CIDFont/TrueType/FontFile.pm
78             sub _look_for_cmap {
79 1     1   4 my $fname = lc(shift);
80              
81 1         8 $fname =~ s/[^a-z0-9]+//gi;
82 1 50       8 return ({%{$cmap->{$fname}}}) if defined $cmap->{$fname};
  0         0  
83 1         132 eval "require 'PDF/Builder/Resource/CIDFont/CMap/$fname.cmap'"; ## no critic
84 1 50       26 unless ($@) {
85 1         4 return({%{$cmap->{$fname}}});
  1         20  
86             } else {
87 0         0 die "requested cmap '$fname' not installed ";
88             }
89             }
90              
91             # compare to TrueType/FontFile.pm: .data and .cmap files are apparently
92             # required when using cjkfont(), so no looking at internal cmap tables
93             sub new {
94 1     1 1 4 my ($class, $pdf, $name, @opts) = @_;
95              
96 1         4 my %opts = ();
97 1 50       7 %opts = @opts if (scalar @opts)%2 == 0;
98 1   50     14 $opts{'-encode'} ||= 'ident';
99              
100 1         2 my $data = _look_for_font($name);
101              
102 1         8 my $cmap = _look_for_cmap($data->{'cmap'});
103              
104 1         3 $data->{'u2g'} = { %{$cmap->{'u2g'}} };
  1         37203  
105 1         3325 $data->{'g2u'} = [ @{$cmap->{'g2u'}} ];
  1         1047  
106              
107 1 50       13 $class = ref $class if ref $class;
108 1 50       21 my $self = $class->SUPER::new($pdf, (defined($data->{'apiname'})? $data->{'apiname'}: '').pdfkey());
109 1 50 33     9 $pdf->new_obj($self) if defined($pdf) && !$self->is_obj($pdf);
110              
111 1         4 $self->{' data'} = $data;
112              
113 1         10 my $des = $self->descrByData();
114              
115 1         4 my $de = $self->{' de'};
116              
117 1 50 33     13 if (defined $opts{'-encode'} && $opts{'-encode'} ne 'ident') {
118 0         0 $self->data->{'encode'} = $opts{'-encode'};
119             }
120              
121 1         13 my $emap = {
122             'reg' => 'Adobe',
123             'ord' => 'Identity',
124             'sup' => 0,
125             'map' => 'Identity',
126             'dir' => 'H',
127             'dec' => 'ident',
128             };
129              
130 1 50       7 if (defined $cmap->{'ccs'}) {
131 1         4 $emap->{'reg'} = $cmap->{'ccs'}->[0];
132 1         3 $emap->{'ord'} = $cmap->{'ccs'}->[1];
133 1         3 $emap->{'sup'} = $cmap->{'ccs'}->[2];
134             }
135              
136             #if (defined $cmap->{'cmap'} && defined $cmap->{'cmap'}->{$opts{'-encode'}} ) {
137             # $emap->{'dec'} = $cmap->{'cmap'}->{$opts{'-encode'}}->[0];
138             # $emap->{'map'} = $cmap->{'cmap'}->{$opts{'-encode'}}->[1];
139             #} elsif (defined $cmap->{'cmap'} && defined $cmap->{'cmap'}->{'utf8'}) {
140             # $emap->{'dec'} = $cmap->{'cmap'}->{'utf8'}->[0];
141             # $emap->{'map'} = $cmap->{'cmap'}->{'utf8'}->[1];
142             #}
143              
144 1         5 $self->data()->{'decode'} = $emap->{'dec'};
145              
146 1         6 $self->{'BaseFont'} = PDFName($self->fontname()."-$emap->{'map'}-$emap->{'dir'}");
147 1         5 $self->{'Encoding'} = PDFName("$emap->{'map'}-$emap->{'dir'}");
148              
149 1         3 $de->{'FontDescriptor'} = $des;
150 1         5 $de->{'Subtype'} = PDFName('CIDFontType0');
151 1         5 $de->{'BaseFont'} = PDFName($self->fontname());
152 1         5 $de->{'DW'} = PDFNum($self->missingwidth());
153 1         5 $de->{'CIDSystemInfo'}->{'Registry'} = PDFString($emap->{'reg'}, 'x');
154 1         5 $de->{'CIDSystemInfo'}->{'Ordering'} = PDFString($emap->{'ord'}, 'x');
155 1         5 $de->{'CIDSystemInfo'}->{'Supplement'} = PDFNum($emap->{'sup'});
156             ## $de->{'CIDToGIDMap'} = PDFName($emap->{'map'}); # ttf only
157              
158 1         9 return $self;
159             }
160              
161             sub tounicodemap {
162 0     0 0   my $self = shift @_;
163              
164             # no-op since PDF knows its char-collection
165 0           return $self;
166             }
167              
168             sub glyphByCId {
169 0     0 0   my ($self, $cid) = @_;
170              
171 0           my $uni = $self->uniByCId($cid);
172 0           return nameByUni($uni);
173             }
174              
175             sub outobjdeep {
176 0     0 1   my ($self, $fh, $pdf) = @_;
177              
178 0           my $notdefbefore = 1;
179              
180 0           my $wx = PDFArray();
181 0           $self->{' de'}->{'W'} = $wx;
182 0           my $ml;
183              
184 0           foreach my $w (0 .. (scalar @{$self->data()->{'g2u'}} - 1 )) {
  0            
185 0 0 0       if (ref($self->data()->{'wx'}) eq 'ARRAY' &&
    0 0        
    0 0        
    0 0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
186             (defined $self->data()->{'wx'}->[$w]) &&
187             ($self->data()->{'wx'}->[$w] != $self->missingwidth()) &&
188             $notdefbefore == 1) {
189 0           $notdefbefore = 0;
190 0           $ml = PDFArray();
191 0           $wx->add_elements(PDFNum($w), $ml);
192 0           $ml->add_elements(PDFNum($self->data()->{'wx'}->[$w]));
193             } elsif (ref($self->data()->{'wx'}) eq 'HASH' &&
194             (defined $self->data()->{'wx'}->{$w}) &&
195             ($self->data()->{'wx'}->{$w} != $self->missingwidth()) &&
196             $notdefbefore == 1) {
197 0           $notdefbefore = 0;
198 0           $ml = PDFArray();
199 0           $wx->add_elements(PDFNum($w), $ml);
200 0           $ml->add_elements(PDFNum($self->data()->{'wx'}->{$w}));
201             } elsif (ref($self->data()->{'wx'}) eq 'ARRAY' &&
202             (defined $self->data()->{'wx'}->[$w]) &&
203             ($self->data()->{'wx'}->[$w] != $self->missingwidth()) &&
204             $notdefbefore == 0) {
205 0           $notdefbefore = 0;
206 0           $ml->add_elements(PDFNum($self->data()->{'wx'}->[$w]));
207             } elsif (ref($self->data()->{'wx'}) eq 'HASH' &&
208             (defined $self->data()->{'wx'}->{$w}) &&
209             ($self->data()->{'wx'}->{$w} != $self->missingwidth()) &&
210             $notdefbefore == 0) {
211 0           $notdefbefore = 0;
212 0           $ml->add_elements(PDFNum($self->data()->{'wx'}->{$w}));
213             } else {
214 0           $notdefbefore = 1;
215             }
216             }
217              
218 0           return $self->SUPER::outobjdeep($fh, $pdf);
219             }
220              
221             BEGIN {
222              
223 2     2   37 $alias = {
224             'traditional' => 'adobemingstdlightacro',
225             'traditionalbold' => 'mingbold',
226             'traditionalitalic' => 'mingitalic',
227             'traditionalbolditalic' => 'mingbolditalic',
228             'ming' => 'adobemingstdlightacro',
229              
230             'simplified' => 'adobesongstdlightacro',
231             'simplifiedbold' => 'songbold',
232             'simplifieditalic' => 'songitalic',
233             'simplifiedbolditalic' => 'songbolditalic',
234             'song' => 'adobesongstdlightacro',
235              
236             'korean' => 'adobemyungjostdmediumacro',
237             'koreanbold' => 'myungjobold',
238             'koreanitalic' => 'myungjoitalic',
239             'koreanbolditalic' => 'myungjobolditalic',
240             'myungjo' => 'adobemyungjostdmediumacro',
241              
242             'japanese' => 'kozminproregularacro',
243             'japanesebold' => 'kozminbold',
244             'japaneseitalic' => 'kozminitalic',
245             'japanesebolditalic' => 'kozminbolditalic',
246             'kozmin' => 'kozminproregularacro',
247             'kozgo' => 'kozgopromediumacro',
248              
249             };
250 2         120 $subs = {
251             # Chinese Traditional (i.e., ROC/Taiwan) Fonts
252             'mingitalic' => {
253             '-alias' => 'adobemingstdlightacro',
254             '+fontname' => ',Italic',
255             },
256             'mingbold' => {
257             '-alias' => 'adobemingstdlightacro',
258             '+fontname' => ',Bold',
259             },
260             'mingbolditalic' => {
261             '-alias' => 'adobemingstdlightacro',
262             '+fontname' => ',BoldItalic',
263             },
264             # Chinese Simplified (i.e., PRC/Mainland China) Fonts
265             'songitalic' => {
266             '-alias' => 'adobesongstdlightacro',
267             '+fontname' => ',Italic',
268             },
269             'songbold' => {
270             '-alias' => 'adobesongstdlightacro',
271             '+fontname' => ',Bold',
272             },
273             'songbolditalic' => {
274             '-alias' => 'adobesongstdlightacro',
275             '+fontname' => ',BoldItalic',
276             },
277             # Japanese Gothic (i.e., sans serif) Fonts
278             'kozgoitalic' => {
279             '-alias' => 'kozgopromediumacro',
280             '+fontname' => ',Italic',
281             },
282             'kozgobold' => {
283             '-alias' => 'kozgopromediumacro',
284             '+fontname' => ',Bold',
285             },
286             'kozgobolditalic' => {
287             '-alias' => 'kozgopromediumacro',
288             '+fontname' => ',BoldItalic',
289             },
290             # Japanese Mincho (i.e., serif) Fonts
291             'kozminitalic' => {
292             '-alias' => 'kozminproregularacro',
293             '+fontname' => ',Italic',
294             },
295             'kozminbold' => {
296             '-alias' => 'kozminproregularacro',
297             '+fontname' => ',Bold',
298             },
299             'kozminbolditalic' => {
300             '-alias' => 'kozminproregularacro',
301             '+fontname' => ',BoldItalic',
302             },
303             # Korean Fonts
304             'myungjoitalic' => {
305             '-alias' => 'adobemyungjostdmediumacro',
306             '+fontname' => ',Italic',
307             },
308             'myungjobold' => {
309             '-alias' => 'adobemyungjostdmediumacro',
310             '+fontname' => ',Bold',
311             },
312             'myungjobolditalic' => {
313             '-alias' => 'adobemyungjostdmediumacro',
314             '+fontname' => ',BoldItalic',
315             },
316             };
317              
318             }
319              
320             =back
321              
322             =cut
323              
324             1;