2 require_once 'Chinese.php';
4 define ('FPDF_UNICODE_ENCODING', 'UCS-2BE');
6 class FPDF_Unicode extends FPDF_Chinese
8 var $charset; // input charset. User must add proper fonts by add font functions like AddUniCNShwFont
9 var $isUnicode; // whether charset belongs to Unicode
11 function PDF_Unicode ($charset = 'UTF-8')
13 $this->FPDF('P', 'mm', 'A4');
14 $this->charset = strtoupper(str_replace ('-', '', $charset));
15 $this->isUnicode = in_array ($this->charset, array ('UTF8', 'UTF16', 'UCS2'));
18 function AddUniCNShwFont ($family='Uni', $name='PMingLiU') // name for Kai font is DFKai-SB
20 //Add Unicode font with half-witdh Latin, character code must be utf16be
22 for($i=32;$i<=126;$i++)
24 //$CMap='UniCNS-UCS2-H'; // for compatible with PDF 1.3 (Adobe-CNS1-0), 1.4 (Adobe-CNS1-3), 1.5 (Adobe-CNS1-3)
25 $CMap='UniCNS-UTF8-H'; // for compatible with 1.5 (Adobe-CNS1-4)
26 $registry=array('ordering'=>'CNS1','supplement'=>0);
27 $this->AddCIDFonts($family,$name,$cw,$CMap,$registry);
30 function AddUniCNSFont ($family='Uni', $cname='PMingLiU')
32 //Add Unicode font with propotional Latin, character code must be utf16be
33 //$cw=$GLOBALS['Big5_widths'];
34 // require 'font/helvetica.php';
37 $CMap='UniCNS-UTF8-H';
38 $registry=array('ordering'=>'CNS1','supplement'=>0);
39 $this->AddCIDFonts($family,$cname,$cw,$CMap,$registry);
42 function AddUniGBhwFont ($family='uGB', $name='AdobeSongStd-Light')
44 //Add Unicode font with half-witdh Latin, character code must be utf16be
45 for($i=32;$i<=126;$i++)
48 $registry=array('ordering'=>'GB1','supplement'=>4);
49 $this->AddCIDFonts($family,$name,$cw,$CMap,$registry);
52 function AddUniGBFont ($family='uGB', $name='AdobeSongStd-Light')
54 //Add Unicode font with propotional Latin, character code must be utf16be
55 $cw=$GLOBALS['GB_widths'];
57 $registry=array('ordering'=>'GB1','supplement'=>4);
58 $this->AddCIDFonts($family,$name,$cw,$CMap,$registry);
61 // redefinition of FPDF functions
63 function GetStringWidth ($s)
65 //Get width of a string in the current font
66 if ($this->isUnicode) {
67 $txt = mb_convert_encoding ($s, FPDF_UNICODE_ENCODING, $this->charset);
68 $oEnc = mb_internal_encoding();
69 mb_internal_encoding (FPDF_UNICODE_ENCODING);
70 $w = $this->GetUniStringWidth ($txt);
71 mb_internal_encoding ($oEnc);
74 return parent::GetStringWidth($s);
77 function Text ($x, $y, $txt)
79 if ($this->isUnicode) {
80 $txt = mb_convert_encoding ($txt, FPDF_UNICODE_ENCODING, $this->charset);
81 $oEnc = mb_internal_encoding();
82 mb_internal_encoding (FPDF_UNICODE_ENCODING);
83 $this->UniText ($x, $y, $txt);
84 mb_internal_encoding ($oEnc);
86 parent::Text ($x, $y, $txt);
89 function Cell ($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='')
91 if ($this->isUnicode) {
92 $txt = mb_convert_encoding ($txt, FPDF_UNICODE_ENCODING, $this->charset);
93 $oEnc = mb_internal_encoding();
94 mb_internal_encoding (FPDF_UNICODE_ENCODING);
95 $this->UniCell ($w, $h, $txt, $border, $ln, $align, $fill, $link);
96 mb_internal_encoding ($oEnc);
98 parent::Cell ($w, $h, $txt, $border, $ln, $align, $fill, $link);
101 function MultiCell ($w,$h,$txt,$border=0,$align='J',$fill=0)
103 if ($this->isUnicode) {
104 $txt = mb_convert_encoding ($txt, FPDF_UNICODE_ENCODING, $this->charset);
105 $oEnc = mb_internal_encoding();
106 mb_internal_encoding (FPDF_UNICODE_ENCODING);
107 $this->UniMultiCell ($w, $h, $txt, $border, $align, $fill);
108 mb_internal_encoding ($oEnc);
110 parent::MultiCell ($w, $h, $txt, $border, $align, $fill);
114 function Write ($h,$txt,$link='')
116 if ($this->isUnicode) {
117 $txt = mb_convert_encoding ($txt, FPDF_UNICODE_ENCODING, $this->charset);
118 $oEnc = mb_internal_encoding();
119 mb_internal_encoding (FPDF_UNICODE_ENCODING);
120 $this->UniWrite ($h, $txt, $link);
121 mb_internal_encoding ($oEnc);
123 parent::Write ($h, $txt, $link);
127 // implementation in Unicode version
129 function GetUniStringWidth ($s)
131 //Unicode version of GetStringWidth()
133 $cw=&$this->CurrentFont['cw'];
137 $c=mb_substr($s,$i,1);
138 $ord = hexdec(bin2hex($c));
146 return $l*$this->FontSize/1000;
149 function UniText ($x, $y, $txt)
151 // copied from parent::Text but just modify the line below
152 $s=sprintf('BT %.2f %.2f Td <%s> Tj ET',$x*$this->k,($this->h-$y)*$this->k, bin2hex($txt));
154 if($this->underline && $txt!='')
155 $s.=' '.$this->_dounderline($x,$y,$txt);
157 $s='q '.$this->TextColor.' '.$s.' Q';
161 function UniCell ($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='')
163 // copied from parent::Text but just modify the line with an output "BT %.2f %.2f Td <%s> Tj ET" ...
165 if($this->y+$h>$this->PageBreakTrigger && !$this->InFooter && $this->AcceptPageBreak())
167 //Automatic page break
175 $this->AddPage($this->CurOrientation);
180 $this->_out(sprintf('%.3f Tw',$ws*$k));
184 $w=$this->w-$this->rMargin-$this->x;
186 if($fill==1 || $border==1)
189 $op=($border==1) ? 'B' : 'f';
192 $s=sprintf('%.2f %.2f %.2f %.2f re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op);
194 if(is_string($border))
198 if(strpos($border,'L')!==false)
199 $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k);
200 if(strpos($border,'T')!==false)
201 $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k);
202 if(strpos($border,'R')!==false)
203 $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
204 if(strpos($border,'B')!==false)
205 $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
210 $dx=$w-$this->cMargin-$this->GetUniStringWidth($txt);
212 $dx=($w-$this->GetUniStringWidth($txt))/2;
216 $s.='q '.$this->TextColor.' ';
217 $s.=sprintf('BT %.2f %.2f Td <%s> Tj ET',($this->x+$dx)*$k,
218 ($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,bin2hex($txt));
220 $s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt);
224 $this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$this->GetUniStringWidth($txt),$this->FontSize,$link);
234 $this->x=$this->lMargin;
240 function UniMultiCell($w,$h,$txt,$border=0,$align='L',$fill=0)
242 //Unicode version of MultiCell()
244 $enc = mb_internal_encoding();
246 $cw=&$this->CurrentFont['cw'];
248 $w=$this->w-$this->rMargin-$this->x;
249 $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
252 if ($nb>0 && mb_substr($s,-1)==mb_convert_encoding("\n", $enc, $this->charset))
266 if(is_int(strpos($border,'L')))
268 if(is_int(strpos($border,'R')))
270 $b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
281 $c=mb_substr($s,$i,1);
282 $ord = hexdec(bin2hex($c));
283 $ascii = ($ord < 128);
284 if($c==mb_convert_encoding("\n", $enc, $this->charset))
286 //Explicit line break
287 $this->UniCell($w,$h,mb_substr($s,$j,$i-$j),$b,2,$align,$fill);
293 if($border && $nl==2)
297 if(!$ascii || $c==mb_convert_encoding(' ', $enc, $this->charset))
302 $l+=$ascii ? $cw[chr($ord)] : 1000;
305 //Automatic line break
306 if($sep==-1 || $i==$j)
309 $i++; //=$ascii ? 1 : 2;
310 $this->UniCell($w,$h,mb_substr($s,$j,$i-$j),$b,2,$align,$fill);
314 $this->UniCell($w,$h,mb_substr($s,$j,$sep-$j),$b,2,$align,$fill);
315 $i=(mb_substr($s,$sep,1)==mb_convert_encoding(' ', $enc, $this->charset)) ? $sep+1 : $sep;
321 if($border && $nl==2)
325 $i++; //=$ascii ? 1 : 2;
328 if($border && is_int(strpos($border,'B')))
330 $this->UniCell($w,$h,mb_substr($s,$j,$i-$j),$b,2,$align,$fill);
331 $this->x=$this->lMargin;
334 function UniWrite($h,$txt,$link='')
336 //Unicode version of Write()
337 $enc = mb_internal_encoding();
338 $cw=&$this->CurrentFont['cw'];
339 $w=$this->w-$this->rMargin-$this->x;
340 $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
352 $c=mb_substr($s,$i,1);
353 //Check if ASCII or MB
354 $ord = hexdec(bin2hex($c));
356 if($c==mb_convert_encoding("\n", $enc, $this->charset))
358 //Explicit line break
359 $this->UniCell($w,$h,mb_substr($s,$j,$i-$j),0,2,'',0,$link);
366 $this->x=$this->lMargin;
367 $w=$this->w-$this->rMargin-$this->x;
368 $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
373 if(!$ascii || $c==mb_convert_encoding(' ', $enc, $this->charset))
375 $l+=$ascii ? $cw[chr($ord)] : 1000;
378 //Automatic line break
379 if($sep==-1 || $i==$j)
381 if($this->x>$this->lMargin)
384 $this->x=$this->lMargin;
386 $w=$this->w-$this->rMargin-$this->x;
387 $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
393 $i++; //=$ascii ? 1 : 2;
394 $this->UniCell($w,$h,mb_substr($s,$j,$i-$j),0,2,'',0,$link);
398 $this->UniCell($w,$h,mb_substr($s,$j,$sep-$j),0,2,'',0,$link);
399 $i=(mb_substr($s,$sep,1)==mb_convert_encoding(' ', $enc, $this->charset)) ? $sep+1 : $sep;
406 $this->x=$this->lMargin;
407 $w=$this->w-$this->rMargin-$this->x;
408 $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
413 $i++; //=$ascii ? 1 : 2;
417 $this->UniCell($l/1000*$this->FontSize,$h,mb_substr($s,$j,$i-$j),0,0,'',0,$link);