File Coverage

blib/lib/PDF/API2/Resource/CIDFont/CJKFont.pm
Criterion Covered Total %
statement 66 105 62.8
branch 10 32 31.2
condition 4 22 18.1
subroutine 9 12 75.0
pod 2 4 50.0
total 91 175 52.0


line stmt bran cond sub pod time code
1             package PDF::API2::Resource::CIDFont::CJKFont;
2              
3 2     2   1611 use base 'PDF::API2::Resource::CIDFont';
  2         4  
  2         620  
4              
5 2     2   15 use strict;
  2         5  
  2         41  
6 2     2   9 use warnings;
  2         6  
  2         79  
7              
8             our $VERSION = '2.045'; # VERSION
9              
10 2     2   12 use PDF::API2::Util;
  2         4  
  2         273  
11 2     2   16 use PDF::API2::Basic::PDF::Utils;
  2         3  
  2         3109  
12              
13             our $fonts = {};
14             our $cmap = {};
15             our $alias;
16             our $subs;
17              
18             =encoding UTF-8
19              
20             =head1 NAME
21              
22             PDF::API2::Resource::CIDFont::CJKFont - Deprecated base class for CJK fonts
23              
24             =head1 DESCRIPTION
25              
26             This is not the CJK font support you are looking for. It dates back to the days
27             when Unicode was young and poorly supported. PDFs created using this class are
28             not portable.
29              
30             Instead, use a regular TrueType or OpenType font that includes Unicode support
31             and create your PDF normally:
32              
33             use PDF::API2;
34             use utf8;
35              
36             my $pdf = PDF::API2->new();
37             my $font = $pdf->font('/path/to/font.ttf');
38             my $page = $pdf->page();
39             my $content = $page->text();
40             $content->font($font, 24);
41              
42             # Chinese
43             $content->translate(72, 72 * 9);
44             $content->text('你好');
45              
46             # Japanese
47             $content->distance(0, -72);
48             $content->text('こんにちは');
49              
50             # Korean
51             $content->distance(0, -72);
52             $content->text('안녕하세요');
53              
54             $pdf->save('hello.pdf');
55              
56             Note: The maintainer is not familiar with CJK languages and has deprecated this
57             class based on his current understanding of Unicode and from reading many bug
58             reports. If you are successfully using the CJK support from this class and
59             think it should not be deprecated, please contact him to discuss.
60              
61             =head1 DEPRECATED METHODS
62              
63             =over
64              
65             =item $font = $class->new($pdf, $cjk_font_name, %options)
66              
67             Returns a CJK font object. The requested font will not be embedded in the PDF,
68             so it will only be readable on computers that have the font installed.
69              
70             Available fonts:
71              
72             =over
73              
74             =item Chinese (Traditional)
75              
76             Ming, Ming-Bold, Ming-Italic, and Ming-BoldItalic
77              
78             =item Chinese (Simplified)
79              
80             Song, Song-Bold, Song-Italic, and Song-BoldItalic
81              
82             =item Korean
83              
84             MyungJo, MyungJo-Bold, MyungJo-Italic, and MyungJo-BoldItalic
85              
86             =item Japanese (Mincho Serif)
87              
88             KozMin, KozMin-Bold, KozMin-Italic, and KozMin-BoldItalic
89              
90             =item Japanese (Gothic Sans Serif)
91              
92             KozGo, KozGo-Bold, KozGo-Italic, KozGo-BoldItalic
93              
94             =back
95              
96             If the text isn't UTF-8, include an C<-encode> option with the encoding to be
97             used.
98              
99             =cut
100              
101             sub _look_for_font {
102 1     1   4 my $fname = lc(shift);
103 1         3 $fname =~ s/[^a-z0-9]+//gi;
104 1 50       4 $fname = $alias->{$fname} if defined $alias->{$fname};
105 1 50       3 return { %{$fonts->{$fname}} } if defined $fonts->{$fname};
  0         0  
106              
107 1 50       13 if (defined $subs->{$fname}) {
108 0         0 my $data = _look_for_font($subs->{$fname}->{'-alias'});
109 0         0 foreach my $k (keys %{$subs->{$fname}}) {
  0         0  
110 0 0       0 next if $k =~ /^\-/;
111 0 0       0 if (substr($k, 0, 1) eq '+') {
112 0         0 $data->{substr($k, 1)} .= $subs->{$fname}->{$k};
113             }
114             else {
115 0         0 $data->{$k} = $subs->{$fname}->{$k};
116             }
117             }
118 0         0 $fonts->{$fname} = $data;
119 0         0 return { %$data };
120             }
121              
122 1         61 eval "require 'PDF/API2/Resource/CIDFont/CJKFont/$fname.data'";
123 1 50       13 unless ($@) {
124 1         4 return { %{$fonts->{$fname}} };
  1         21  
125             }
126             else {
127 0         0 die "requested font '$fname' not installed";
128             }
129             }
130              
131             sub _look_for_cmap {
132 1     1   3 my $map = shift();
133 1         4 my $filename = lc($map);
134 1         5 $filename =~ s/[^a-z0-9]+//gi;
135 1 50       7 return { %{$cmap->{$filename}} } if defined $cmap->{$filename};
  0         0  
136 1         91 eval "require 'PDF/API2/Resource/CIDFont/CMap/$filename.cmap'";
137 1 50       24 unless ($@) {
138 1         3 return { %{$cmap->{$filename}} };
  1         18  
139             }
140             else {
141 0         0 die "requested cmap '$map' not installed";
142             }
143             }
144              
145             sub new {
146 1     1 1 4 my ($class, $pdf, $name, %opts) = @_;
147 1   50     7 $opts{'-encode'} //= 'ident';
148              
149 1         3 my $data = _look_for_font($name);
150              
151 1         6 my $cmap = _look_for_cmap($data->{'cmap'});
152              
153 1         2 $data->{'u2g'} = { %{$cmap->{'u2g'}} };
  1         15843  
154 1         1089 $data->{'g2u'} = [ @{$cmap->{'g2u'}} ];
  1         858  
155              
156 1 50       11 $class = ref($class) if ref($class);
157 1   50     19 my $key = ($data->{'apiname'} // '') . pdfkey();
158 1         27 my $self = $class->SUPER::new($pdf, $key);
159 1 50 33     7 $pdf->new_obj($self) if defined($pdf) and not $self->is_obj($pdf);
160              
161 1         4 $self->{' data'} = $data;
162              
163 1 50 33     13 if (defined $opts{'-encode'} and $opts{'-encode'} ne 'ident') {
164 0         0 $self->data->{'encode'} = $opts{'-encode'};
165             }
166              
167 1         7 my $emap = {
168             'reg' => 'Adobe',
169             'ord' => 'Identity',
170             'sup' => 0,
171             'map' => 'Identity',
172             'dir' => 'H',
173             'dec' => 'ident',
174             };
175              
176 1 50       5 if (defined $cmap->{'ccs'}) {
177 1         3 $emap->{'reg'} = $cmap->{'ccs'}->[0];
178 1         4 $emap->{'ord'} = $cmap->{'ccs'}->[1];
179 1         4 $emap->{'sup'} = $cmap->{'ccs'}->[2];
180             }
181              
182             # if (defined $cmap->{'cmap'} and defined $cmap->{'cmap'}->{$opts{'-encode'}} ) {
183             # $emap->{'dec'} = $cmap->{'cmap'}->{$opts{'-encode'}}->[0];
184             # $emap->{'map'} = $cmap->{'cmap'}->{$opts{'-encode'}}->[1];
185             # }
186             # elsif (defined $cmap->{'cmap'} and defined $cmap->{'cmap'}->{'utf8'} ) {
187             # $emap->{'dec'} = $cmap->{'cmap'}->{'utf8'}->[0];
188             # $emap->{'map'} = $cmap->{'cmap'}->{'utf8'}->[1];
189             # }
190              
191 1         8 $self->data->{'decode'} = $emap->{'dec'};
192              
193             $self->{'BaseFont'} = PDFName(join('-',
194             $self->fontname(),
195             $emap->{'map'},
196 1         8 $emap->{'dir'}));
197 1         8 $self->{'Encoding'} = PDFName($emap->{'map'} . '-' . $emap->{'dir'});
198              
199 1         8 my $des = $self->descrByData();
200 1         3 my $de = $self->{' de'};
201              
202 1         3 $de->{'FontDescriptor'} = $des;
203 1         3 $de->{'Subtype'} = PDFName('CIDFontType0');
204 1         4 $de->{'BaseFont'} = PDFName($self->fontname());
205 1         3 $de->{'DW'} = PDFNum($self->missingwidth());
206 1         6 $de->{'CIDSystemInfo'}->{'Registry'} = PDFStr($emap->{'reg'});
207 1         3 $de->{'CIDSystemInfo'}->{'Ordering'} = PDFStr($emap->{'ord'});
208 1         4 $de->{'CIDSystemInfo'}->{'Supplement'} = PDFNum($emap->{'sup'});
209             # $de->{'CIDToGIDMap'} = PDFName($emap->{'map'}); # ttf only
210              
211 1         7 return $self;
212             }
213              
214             sub tounicodemap {
215 0     0 0   my $self = shift();
216             # noop since pdf knows its char-collection
217 0           return $self;
218             }
219              
220             sub glyphByCId {
221 0     0 0   my ($self, $cid) = @_;
222 0           my $uni = $self->uniByCId($cid);
223 0           return nameByUni($uni);
224             }
225              
226             sub outobjdeep {
227 0     0 1   my ($self, $fh, $pdf) = @_;
228              
229 0           my $notdefbefore = 1;
230              
231 0           my $wx = PDFArray();
232 0           $self->{' de'}->{'W'} = $wx;
233 0           my $ml;
234              
235 0           foreach my $i (0 .. (scalar @{$self->data->{'g2u'}} - 1)) {
  0            
236 0 0 0       if (ref($self->data->{'wx'}) eq 'ARRAY'
    0 0        
      0        
      0        
237             and defined $self->data->{'wx'}->[$i]
238             and $self->data->{'wx'}->[$i] != $self->missingwidth())
239             {
240 0 0         if ($notdefbefore) {
241 0           $notdefbefore = 0;
242 0           $ml = PDFArray();
243 0           $wx->add_elements(PDFNum($i), $ml);
244             }
245 0           $ml->add_elements(PDFNum($self->data->{'wx'}->[$i]));
246             }
247             elsif (ref($self->data->{'wx'}) eq 'HASH'
248             and defined $self->data->{'wx'}->{$i}
249             and $self->data->{'wx'}->{$i} != $self->missingwidth())
250             {
251 0 0         if ($notdefbefore) {
252 0           $notdefbefore = 0;
253 0           $ml = PDFArray();
254 0           $wx->add_elements(PDFNum($i), $ml);
255             }
256 0           $ml->add_elements(PDFNum($self->data->{'wx'}->{$i}));
257             }
258             else {
259 0           $notdefbefore = 1;
260             }
261             }
262              
263 0           $self->SUPER::outobjdeep($fh, $pdf);
264             }
265              
266             BEGIN {
267 2     2   61 $alias = {
268             'traditional' => 'adobemingstdlightacro',
269             'traditionalbold' => 'mingbold',
270             'traditionalitalic' => 'mingitalic',
271             'traditionalbolditalic' => 'mingbolditalic',
272             'ming' => 'adobemingstdlightacro',
273              
274             'simplified' => 'adobesongstdlightacro',
275             'simplifiedbold' => 'songbold',
276             'simplifieditalic' => 'songitalic',
277             'simplifiedbolditalic' => 'songbolditalic',
278             'song' => 'adobesongstdlightacro',
279              
280             'korean' => 'adobemyungjostdmediumacro',
281             'koreanbold' => 'myungjobold',
282             'koreanitalic' => 'myungjoitalic',
283             'koreanbolditalic' => 'myungjobolditalic',
284             'myungjo' => 'adobemyungjostdmediumacro',
285              
286             'japanese' => 'kozminproregularacro',
287             'japanesebold' => 'kozminbold',
288             'japaneseitalic' => 'kozminitalic',
289             'japanesebolditalic' => 'kozminbolditalic',
290             'kozmin' => 'kozminproregularacro',
291             'kozgo' => 'kozgopromediumacro',
292             };
293              
294 2         107 $subs = {
295             # Chinese Traditional (Taiwan) Fonts
296             'mingitalic' => {
297             '-alias' => 'adobemingstdlightacro',
298             '+fontname' => ',Italic',
299             },
300             'mingbold' => {
301             '-alias' => 'adobemingstdlightacro',
302             '+fontname' => ',Bold',
303             },
304             'mingbolditalic' => {
305             '-alias' => 'adobemingstdlightacro',
306             '+fontname' => ',BoldItalic',
307             },
308              
309             # Chinese Simplified (Mainland China) Fonts
310             'songitalic' => {
311             '-alias' => 'adobesongstdlightacro',
312             '+fontname' => ',Italic',
313             },
314             'songbold' => {
315             '-alias' => 'adobesongstdlightacro',
316             '+fontname' => ',Bold',
317             },
318             'songbolditalic' => {
319             '-alias' => 'adobesongstdlightacro',
320             '+fontname' => ',BoldItalic',
321             },
322              
323             # Japanese Gothic (sans serif) Fonts
324             'kozgoitalic' => {
325             '-alias' => 'kozgopromediumacro',
326             '+fontname' => ',Italic',
327             },
328             'kozgobold' => {
329             '-alias' => 'kozgopromediumacro',
330             '+fontname' => ',Bold',
331             },
332             'kozgobolditalic' => {
333             '-alias' => 'kozgopromediumacro',
334             '+fontname' => ',BoldItalic',
335             },
336              
337             # Japanese Mincho (serif) Fonts
338             'kozminitalic' => {
339             '-alias' => 'kozminproregularacro',
340             '+fontname' => ',Italic',
341             },
342             'kozminbold' => {
343             '-alias' => 'kozminproregularacro',
344             '+fontname' => ',Bold',
345             },
346             'kozminbolditalic' => {
347             '-alias' => 'kozminproregularacro',
348             '+fontname' => ',BoldItalic',
349             },
350              
351             # Korean Fonts
352             'myungjoitalic' => {
353             '-alias' => 'adobemyungjostdmediumacro',
354             '+fontname' => ',Italic',
355             },
356             'myungjobold' => {
357             '-alias' => 'adobemyungjostdmediumacro',
358             '+fontname' => ',Bold',
359             },
360             'myungjobolditalic' => {
361             '-alias' => 'adobemyungjostdmediumacro',
362             '+fontname' => ',BoldItalic',
363             },
364             };
365             }
366              
367             =back
368              
369             =cut
370              
371             1;