package PDF::API2::Resource::CIDFont::CJKFont; use base 'PDF::API2::Resource::CIDFont'; use strict; use warnings; our $VERSION = '2.043'; # VERSION use PDF::API2::Util; use PDF::API2::Basic::PDF::Utils; our $fonts = {}; our $cmap = {}; our $alias; our $subs; =encoding UTF-8 =head1 NAME PDF::API2::Resource::CIDFont::CJKFont - Deprecated base class for CJK fonts =head1 DESCRIPTION This is not the CJK font support you are looking for. It dates back to the days when Unicode was young and poorly supported. PDFs created using this class are not portable. Instead, use a regular TrueType or OpenType font that includes Unicode support and create your PDF normally: use PDF::API2; use utf8; my $pdf = PDF::API2->new(); my $font = $pdf->font('/path/to/font.ttf'); my $page = $pdf->page(); my $content = $page->text(); $content->font($font, 24); # Chinese $content->translate(72, 72 * 9); $content->text('你好'); # Japanese $content->distance(0, -72); $content->text('こんにちは'); # Korean $content->distance(0, -72); $content->text('안녕하세요'); $pdf->save('hello.pdf'); Note: The maintainer is not familiar with CJK languages and has deprecated this class based on his current understanding of Unicode and from reading many bug reports. If you are successfully using the CJK support from this class and think it should not be deprecated, please contact him to discuss. =head1 DEPRECATED METHODS =over =item $font = $class->new($pdf, $cjk_font_name, %options) Returns a CJK font object. The requested font will not be embedded in the PDF, so it will only be readable on computers that have the font installed. Available fonts: =over =item Chinese (Traditional) Ming, Ming-Bold, Ming-Italic, and Ming-BoldItalic =item Chinese (Simplified) Song, Song-Bold, Song-Italic, and Song-BoldItalic =item Korean MyungJo, MyungJo-Bold, MyungJo-Italic, and MyungJo-BoldItalic =item Japanese (Mincho Serif) KozMin, KozMin-Bold, KozMin-Italic, and KozMin-BoldItalic =item Japanese (Gothic Sans Serif) KozGo, KozGo-Bold, KozGo-Italic, KozGo-BoldItalic =back If the text isn't UTF-8, include an C<-encode> option with the encoding to be used. =cut sub _look_for_font { my $fname = lc(shift); $fname =~ s/[^a-z0-9]+//gi; $fname = $alias->{$fname} if defined $alias->{$fname}; return { %{$fonts->{$fname}} } if defined $fonts->{$fname}; if (defined $subs->{$fname}) { my $data = _look_for_font($subs->{$fname}->{'-alias'}); foreach my $k (keys %{$subs->{$fname}}) { next if $k =~ /^\-/; if (substr($k, 0, 1) eq '+') { $data->{substr($k, 1)} .= $subs->{$fname}->{$k}; } else { $data->{$k} = $subs->{$fname}->{$k}; } } $fonts->{$fname} = $data; return { %$data }; } eval "require 'PDF/API2/Resource/CIDFont/CJKFont/$fname.data'"; unless ($@) { return { %{$fonts->{$fname}} }; } else { die "requested font '$fname' not installed"; } } sub _look_for_cmap { my $map = shift(); my $filename = lc($map); $filename =~ s/[^a-z0-9]+//gi; return { %{$cmap->{$filename}} } if defined $cmap->{$filename}; eval "require 'PDF/API2/Resource/CIDFont/CMap/$filename.cmap'"; unless ($@) { return { %{$cmap->{$filename}} }; } else { die "requested cmap '$map' not installed"; } } sub new { my ($class, $pdf, $name, %opts) = @_; $opts{'-encode'} //= 'ident'; my $data = _look_for_font($name); my $cmap = _look_for_cmap($data->{'cmap'}); $data->{'u2g'} = { %{$cmap->{'u2g'}} }; $data->{'g2u'} = [ @{$cmap->{'g2u'}} ]; $class = ref($class) if ref($class); my $key = ($data->{'apiname'} // '') . pdfkey(); my $self = $class->SUPER::new($pdf, $key); $pdf->new_obj($self) if defined($pdf) and not $self->is_obj($pdf); $self->{' data'} = $data; if (defined $opts{'-encode'} and $opts{'-encode'} ne 'ident') { $self->data->{'encode'} = $opts{'-encode'}; } my $emap = { 'reg' => 'Adobe', 'ord' => 'Identity', 'sup' => 0, 'map' => 'Identity', 'dir' => 'H', 'dec' => 'ident', }; if (defined $cmap->{'ccs'}) { $emap->{'reg'} = $cmap->{'ccs'}->[0]; $emap->{'ord'} = $cmap->{'ccs'}->[1]; $emap->{'sup'} = $cmap->{'ccs'}->[2]; } # if (defined $cmap->{'cmap'} and defined $cmap->{'cmap'}->{$opts{'-encode'}} ) { # $emap->{'dec'} = $cmap->{'cmap'}->{$opts{'-encode'}}->[0]; # $emap->{'map'} = $cmap->{'cmap'}->{$opts{'-encode'}}->[1]; # } # elsif (defined $cmap->{'cmap'} and defined $cmap->{'cmap'}->{'utf8'} ) { # $emap->{'dec'} = $cmap->{'cmap'}->{'utf8'}->[0]; # $emap->{'map'} = $cmap->{'cmap'}->{'utf8'}->[1]; # } $self->data->{'decode'} = $emap->{'dec'}; $self->{'BaseFont'} = PDFName(join('-', $self->fontname(), $emap->{'map'}, $emap->{'dir'})); $self->{'Encoding'} = PDFName($emap->{'map'} . '-' . $emap->{'dir'}); my $des = $self->descrByData(); my $de = $self->{' de'}; $de->{'FontDescriptor'} = $des; $de->{'Subtype'} = PDFName('CIDFontType0'); $de->{'BaseFont'} = PDFName($self->fontname()); $de->{'DW'} = PDFNum($self->missingwidth()); $de->{'CIDSystemInfo'}->{'Registry'} = PDFStr($emap->{'reg'}); $de->{'CIDSystemInfo'}->{'Ordering'} = PDFStr($emap->{'ord'}); $de->{'CIDSystemInfo'}->{'Supplement'} = PDFNum($emap->{'sup'}); # $de->{'CIDToGIDMap'} = PDFName($emap->{'map'}); # ttf only return $self; } sub tounicodemap { my $self = shift(); # noop since pdf knows its char-collection return $self; } sub glyphByCId { my ($self, $cid) = @_; my $uni = $self->uniByCId($cid); return nameByUni($uni); } sub outobjdeep { my ($self, $fh, $pdf) = @_; my $notdefbefore = 1; my $wx = PDFArray(); $self->{' de'}->{'W'} = $wx; my $ml; foreach my $i (0 .. (scalar @{$self->data->{'g2u'}} - 1)) { if (ref($self->data->{'wx'}) eq 'ARRAY' and defined $self->data->{'wx'}->[$i] and $self->data->{'wx'}->[$i] != $self->missingwidth()) { if ($notdefbefore) { $notdefbefore = 0; $ml = PDFArray(); $wx->add_elements(PDFNum($i), $ml); } $ml->add_elements(PDFNum($self->data->{'wx'}->[$i])); } elsif (ref($self->data->{'wx'}) eq 'HASH' and defined $self->data->{'wx'}->{$i} and $self->data->{'wx'}->{$i} != $self->missingwidth()) { if ($notdefbefore) { $notdefbefore = 0; $ml = PDFArray(); $wx->add_elements(PDFNum($i), $ml); } $ml->add_elements(PDFNum($self->data->{'wx'}->{$i})); } else { $notdefbefore = 1; } } $self->SUPER::outobjdeep($fh, $pdf); } BEGIN { $alias = { 'traditional' => 'adobemingstdlightacro', 'traditionalbold' => 'mingbold', 'traditionalitalic' => 'mingitalic', 'traditionalbolditalic' => 'mingbolditalic', 'ming' => 'adobemingstdlightacro', 'simplified' => 'adobesongstdlightacro', 'simplifiedbold' => 'songbold', 'simplifieditalic' => 'songitalic', 'simplifiedbolditalic' => 'songbolditalic', 'song' => 'adobesongstdlightacro', 'korean' => 'adobemyungjostdmediumacro', 'koreanbold' => 'myungjobold', 'koreanitalic' => 'myungjoitalic', 'koreanbolditalic' => 'myungjobolditalic', 'myungjo' => 'adobemyungjostdmediumacro', 'japanese' => 'kozminproregularacro', 'japanesebold' => 'kozminbold', 'japaneseitalic' => 'kozminitalic', 'japanesebolditalic' => 'kozminbolditalic', 'kozmin' => 'kozminproregularacro', 'kozgo' => 'kozgopromediumacro', }; $subs = { # Chinese Traditional (Taiwan) Fonts 'mingitalic' => { '-alias' => 'adobemingstdlightacro', '+fontname' => ',Italic', }, 'mingbold' => { '-alias' => 'adobemingstdlightacro', '+fontname' => ',Bold', }, 'mingbolditalic' => { '-alias' => 'adobemingstdlightacro', '+fontname' => ',BoldItalic', }, # Chinese Simplified (Mainland China) Fonts 'songitalic' => { '-alias' => 'adobesongstdlightacro', '+fontname' => ',Italic', }, 'songbold' => { '-alias' => 'adobesongstdlightacro', '+fontname' => ',Bold', }, 'songbolditalic' => { '-alias' => 'adobesongstdlightacro', '+fontname' => ',BoldItalic', }, # Japanese Gothic (sans serif) Fonts 'kozgoitalic' => { '-alias' => 'kozgopromediumacro', '+fontname' => ',Italic', }, 'kozgobold' => { '-alias' => 'kozgopromediumacro', '+fontname' => ',Bold', }, 'kozgobolditalic' => { '-alias' => 'kozgopromediumacro', '+fontname' => ',BoldItalic', }, # Japanese Mincho (serif) Fonts 'kozminitalic' => { '-alias' => 'kozminproregularacro', '+fontname' => ',Italic', }, 'kozminbold' => { '-alias' => 'kozminproregularacro', '+fontname' => ',Bold', }, 'kozminbolditalic' => { '-alias' => 'kozminproregularacro', '+fontname' => ',BoldItalic', }, # Korean Fonts 'myungjoitalic' => { '-alias' => 'adobemyungjostdmediumacro', '+fontname' => ',Italic', }, 'myungjobold' => { '-alias' => 'adobemyungjostdmediumacro', '+fontname' => ',Bold', }, 'myungjobolditalic' => { '-alias' => 'adobemyungjostdmediumacro', '+fontname' => ',BoldItalic', }, }; } =back =cut 1;