PluginProbe
Welcart e-Commerce / 2.12.4
Welcart e-Commerce v2.12.4
2.12.4 2.12.3 2.11.35 2.12.2 2.12.1 2.11.34 2.11.33 2.11.32 2.11.31 2.11.30 1.3.16 1.3.17 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 All 292 releases
← All changes | classes/fpdf/mbfpdf.php +592 -592 1.3.72.12.4 View file →
@@ -1,592 +1,592 @@
1 -<?php
2 -//-------------------------------------------------------------------------
3 -// Multi-Byte FPDF version: 1.0b
4 -//-------------------------------------------------------------------------
5 -// Usage: AddMBFont(FontName,Encoding);
6 -//
7 -// Example:
8 -// Chinese: AddMBFont(BIG5 ,'BIG5');
9 -// Japanese: AddMBFont(GOTHIC,'SJIS');
10 -
11 -require(USCES_PLUGIN_DIR.'/classes/fpdf/fpdf.php'); // Original Class
12 -require(USCES_PLUGIN_DIR.'/classes/fpdf/font/mbttfdef.php'); // Multi-Byte TrueType Font Define
13 -
14 -// FPDF Version Check
15 -if ((float) FPDF_VERSION < 1.51) die("You need FPDF version 1.51");
16 -
17 -// Encoding & CMap List (CMap information from Acrobat Reader Resource/CMap folder)
18 -$MBCMAP['BIG5'] = array ('CMap'=>'ETenms-B5-H' ,'Ordering'=>'CNS1' ,'Supplement'=>0);
19 -$MBCMAP['GB'] = array ('CMap'=>'GBKp-EUC-H' ,'Ordering'=>'GB1' ,'Supplement'=>2);
20 -$MBCMAP['SJIS'] = array ('CMap'=>'90msp-RKSJ-H' ,'Ordering'=>'Japan1','Supplement'=>2);
21 -$MBCMAP['UNIJIS'] = array ('CMap'=>'UniJIS-UTF16-H','Ordering'=>'Japan1','Supplement'=>5);
22 -$MBCMAP['EUC-JP'] = array ('CMap'=>'EUC-H' ,'Ordering'=>'Japan1','Supplement'=>1);
23 -// EUC-JP has *problem* of underline and not support half-pitch characters.
24 -
25 -// if you want convert encoding to SJIS from EUC-JP, you must change $EUC2SJIS to true.
26 -$EUC2SJIS = false;
27 -
28 -// Short Font Name ------------------------------------------------------------
29 -// For Acrobat Reader (Windows, MacOS, Linux, Solaris etc)
30 -DEFINE("BIG5", 'MSungStd-Light-Acro');
31 -DEFINE("GB", 'STSongStd-Light-Acro');
32 -DEFINE("KOZMIN", 'KozMinPro-Regular-Acro');
33 -// For Japanese Windows Only
34 -DEFINE("GOTHIC", 'MS-Gothic');
35 -DEFINE("PGOTHIC", 'MS-PGothic');
36 -DEFINE("UIGOTHIC",'MS-UIGothic');
37 -DEFINE("MINCHO", 'MS-Mincho');
38 -DEFINE("PMINCHO", 'MS-PMincho');
39 -
40 -class MBFPDF extends FPDF
41 -{
42 -
43 -// For Outline, Title, Sub-Title and ETC Multi-Byte Encoding
44 -function _unicode($txt)
45 -{
46 - if (function_exists('mb_detect_encoding')) {
47 - if (mb_detect_encoding($txt) != "ASCII") {
48 - $txt = chr(254).chr(255).mb_convert_encoding($txt,"UTF-16","auto");
49 - }
50 - }
51 - return $txt;
52 -}
53 -
54 -function AddCIDFont($family,$style,$name,$cw,$CMap,$registry,$ut,$up)
55 -{
56 - $i=count($this->fonts)+1;
57 - $fontkey=strtolower($family).strtoupper($style);
58 - $this->fonts[$fontkey] =
59 - array('i'=>$i,'type'=>'Type0','name'=>$name,'up'=>$up,'ut'=>$ut,'cw'=>$cw,'CMap'=>$CMap,'registry'=>$registry);
60 -}
61 -
62 -function AddMBFont($family='',$enc='')
63 -{
64 - global $MBTTFDEF,$MBCMAP;
65 - $gt=$MBTTFDEF;
66 - $gc=$MBCMAP;
67 - if ($enc == '' || isset($gc[$enc]) == false) {
68 - die("AddMBFont: ERROR Encoding [$enc] Undefine.");
69 - }
70 - if (isset($gt[$family])) {
71 - $ut=$gt[$family]['ut'];
72 - $up=$gt[$family]['up'];
73 - $cw=$gt[$family]['cw'];
74 - $cm=$gc[$enc]['CMap'];
75 - $od=$gc[$enc]['Ordering'];
76 - $sp=$gc[$enc]['Supplement'];
77 - $registry=array('ordering'=>$od,'supplement'=>$sp);
78 - $this->AddCIDFont($family,'' ,"$family" ,$cw,$cm,$registry,$ut,$up);
79 - $this->AddCIDFont($family,'B' ,"$family,Bold" ,$cw,$cm,$registry,$ut,$up);
80 - $this->AddCIDFont($family,'I' ,"$family,Italic" ,$cw,$cm,$registry,$ut,$up);
81 - $this->AddCIDFont($family,'BI',"$family,BoldItalic",$cw,$cm,$registry,$ut,$up);
82 - } else {
83 - die("AddMBFont: ERROR FontName [$family] Undefine.");
84 - }
85 -}
86 -
87 -function GetStringWidth($s)
88 -{
89 - if($this->CurrentFont['type']=='Type0')
90 - return $this->GetMBStringWidth($s);
91 - else
92 - return parent::GetStringWidth($s);
93 -}
94 -
95 -function GetMBStringWidth($s)
96 -{
97 - //Multi-byte version of GetStringWidth()
98 - $l=0;
99 - $cw=&$this->CurrentFont['cw'];
100 - $japanese = ($this->CurrentFont['registry']['ordering'] == 'Japan1');
101 - $nb=strlen($s);
102 - $i=0;
103 - while($i<$nb)
104 - {
105 - $c=$s[$i];
106 - if(ord($c)<128)
107 - {
108 - $l+=$cw[$c];
109 - $i++;
110 - }
111 - else
112 - {
113 - $hwkana = ($japanese && ord($c)==142);
114 - $l+=$hwkana ? 500 : 1000;
115 - $i+=2;
116 - }
117 - }
118 - return $l*$this->FontSize/1000;
119 -}
120 -
121 -// Function Cell override for Encode Change.
122 -function Cell($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = 0, $link = '')
123 -{
124 -
125 - $k = $this->k;
126 -
127 - if ($this->y + $h > $this->PageBreakTrigger
128 - && !$this->InFooter
129 - && $this->AcceptPageBreak()) {
130 - $x = $this->x;
131 - $ws = $this->ws;
132 - if ($ws > 0) {
133 - $this->ws = 0;
134 - $this->_out('0 Tw');
135 - }
136 - $this->AddPage($this->CurOrientation);
137 - $this->x = $x;
138 - if ($ws > 0) {
139 - $this->ws = $ws;
140 - $this->_out(sprintf('%.3f Tw', $ws * $k));
141 - }
142 - } // end if
143 -
144 - if ($w == 0) {
145 - $w = $this->w - $this->rMargin - $this->x;
146 - }
147 -
148 - $s = '';
149 - if ($fill == 1 || $border == 1) {
150 - if ($fill == 1) {
151 - $op = ($border == 1) ? 'B' : 'f';
152 - } else {
153 - $op = 'S';
154 - }
155 - $s = sprintf('%.2f %.2f %.2f %.2f re %s ', $this->x * $k, ($this->h - $this->y) * $k, $w * $k, -$h * $k, $op);
156 - } // end if
157 -
158 - if (is_string($border)) {
159 - $x = $this->x;
160 - $y = $this->y;
161 - if (strpos(' ' . $border, 'L')) {
162 - $s .= sprintf('%.2f %.2f m %.2f %.2f l S ', $x * $k, ($this->h - $y) * $k, $x * $k, ($this->h - ($y+$h)) * $k);
163 - }
164 - if (strpos(' ' . $border, 'T')) {
165 - $s .= sprintf('%.2f %.2f m %.2f %.2f l S ', $x * $k, ($this->h - $y) * $k, ($x + $w) * $k, ($this->h - $y) * $k);
166 - }
167 - if (strpos(' ' . $border, 'R')) {
168 - $s .= sprintf('%.2f %.2f m %.2f %.2f l S ', ($x + $w) * $k, ($this->h - $y) * $k, ($x + $w) * $k, ($this->h - ($y + $h)) * $k);
169 - }
170 - if (strpos(' ' . $border, 'B')) {
171 - $s .= sprintf('%.2f %.2f m %.2f %.2f l S ', $x * $k, ($this->h - ($y + $h)) * $k, ($x + $w) * $k, ($this->h - ($y + $h)) * $k);
172 - }
173 - } // end if
174 -
175 - if ($txt != '') {
176 - if ($align == 'R') {
177 - $dx = $w - $this->cMargin - $this->GetStringWidth($txt);
178 - }
179 - else if ($align == 'C') {
180 - $dx = ($w - $this->GetStringWidth($txt)) / 2;
181 - }
182 - else {
183 - $dx = $this->cMargin;
184 - }
185 - // For Japanese Encode Change
186 - global $EUC2SJIS;
187 - if ($EUC2SJIS && function_exists('mb_convert_encoding')) {
188 - $txt = mb_convert_encoding($txt,"SJIS","EUC-JP");
189 - }
190 - $txt = str_replace(')', '\\)', str_replace('(', '\\(', str_replace('\\', '\\\\', $txt)));
191 - if ($this->ColorFlag) {
192 - $s .= 'q ' . $this->TextColor . ' ';
193 - }
194 - $s .= sprintf('BT %.2f %.2f Td (%s) Tj ET', ($this->x + $dx) * $k, ($this->h - ($this->y + .5 * $h + .3 * $this->FontSize)) * $k, $txt);
195 - $txt = stripslashes($txt);
196 - if ($this->underline) {
197 - $s .= ' ' . $this->_dounderline($this->x+$dx, $this->y + .5 * $h + .3 * $this->FontSize, $txt);
198 - }
199 - if ($this->ColorFlag) {
200 - $s .= ' Q';
201 - }
202 - if ($link) {
203 - $this->Link($this->x + $dx, $this->y + .5 * $h - .5 * $this->FontSize, $this->GetStringWidth($txt), $this->FontSize, $link);
204 - }
205 - } // end if
206 -
207 - if ($s) {
208 - $this->_out($s);
209 - }
210 - $this->lasth = $h;
211 -
212 - if ($ln > 0) {
213 - // Go to next line
214 - $this->y += $h;
215 - if ($ln == 1) {
216 - $this->x = $this->lMargin;
217 - }
218 - } else {
219 - $this->x += $w;
220 - }
221 -} // end of the "Cell()" method
222 -
223 -function MultiCell($w,$h,$txt,$border=0,$align='L',$fill=0)
224 -{
225 - if($this->CurrentFont['type']=='Type0')
226 - $this->MBMultiCell($w,$h,$txt,$border,$align,$fill);
227 - else
228 - parent::MultiCell($w,$h,$txt,$border,$align,$fill);
229 -}
230 -
231 -function MBMultiCell($w,$h,$txt,$border=0,$align='L',$fill=0)
232 -{
233 - //Multi-byte version of MultiCell()
234 - $cw=&$this->CurrentFont['cw'];
235 - $japanese = ($this->CurrentFont['registry']['ordering'] == 'Japan1');
236 - if($w==0)
237 - $w=$this->w-$this->rMargin-$this->x;
238 - $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
239 - $s=str_replace("\r",'',$txt);
240 - $nb=strlen($s);
241 - if($nb>0 and $s[$nb-1]=="\n")
242 - $nb--;
243 - $b=0;
244 - if($border)
245 - {
246 - if($border==1)
247 - {
248 - $border='LTRB';
249 - $b='LRT';
250 - $b2='LR';
251 - }
252 - else
253 - {
254 - $b2='';
255 - if(is_int(strpos($border,'L')))
256 - $b2.='L';
257 - if(is_int(strpos($border,'R')))
258 - $b2.='R';
259 - $b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
260 - }
261 - }
262 - $sep=-1;
263 - $i=0;
264 - $j=0;
265 - $l=0;
266 - $ns=0;
267 - $nl=1;
268 - $ascii=true;
269 - while($i<$nb)
270 - {
271 - //Get next character
272 - $c=$s[$i];
273 - //Check if ASCII or MB
274 - $prev_ascii=$ascii;
275 - $ascii=(ord($c)<128);
276 - $hwkana = ($japanese && ord($c)==142);
277 - if($c=="\n")
278 - {
279 - //Explicit line break
280 - if($this->ws>0)
281 - {
282 - $this->ws=0;
283 - $this->_out('0 Tw');
284 - }
285 - $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
286 - $i++;
287 - $sep=-1;
288 - $j=$i;
289 - $l=0;
290 - $ns=0;
291 - $nl++;
292 - if($border and $nl==2)
293 - $b=$b2;
294 - continue;
295 - }
296 - if(!($ascii && $prev_ascii) && $i != $j)
297 - {
298 - $sep=$i;
299 - $ls=$l;
300 - }
301 - elseif($c==' ')
302 - {
303 - $sep=$i;
304 - $ls=$l;
305 - $ns++;
306 - }
307 - $l+=$ascii ? $cw[$c] : $hwkana ? 500 : 1000;
308 - if($l>$wmax)
309 - {
310 - //Automatic line break
311 - if($sep==-1)
312 - {
313 - if($i==$j)
314 - $i+=$ascii ? 1 : 2;
315 - if($this->ws>0)
316 - {
317 - $this->ws=0;
318 - $this->_out('0 Tw');
319 - }
320 - $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
321 - }
322 - else
323 - {
324 - if($align=='J')
325 - {
326 - if($s[$sep]==' ')
327 - $ns--;
328 - if($s[$i-1]==' ')
329 - {
330 - $ns--;
331 - $ls-=$cw[' '];
332 - }
333 - $this->ws=($ns>0) ? ($wmax-$ls)/1000*$this->FontSize/$ns : 0;
334 - $this->_out(sprintf('%.3f Tw',$this->ws*$this->k));
335 - }
336 - $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill);
337 - $i=($s[$sep]==' ') ? $sep+1 : $sep;
338 - }
339 - $sep=-1;
340 - $j=$i;
341 - $l=0;
342 - $ns=0;
343 - $nl++;
344 - if($border and $nl==2)
345 - $b=$b2;
346 - }
347 - else
348 - $i+=$ascii ? 1 : 2;
349 - }
350 - //Last chunk
351 - if($this->ws>0)
352 - {
353 - $this->ws=0;
354 - $this->_out('0 Tw');
355 - }
356 - if($border and is_int(strpos($border,'B')))
357 - $b.='B';
358 - $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
359 - $this->x=$this->lMargin;
360 -}
361 -
362 -function Write($h,$txt,$link='')
363 -{
364 - if($this->CurrentFont['type']=='Type0')
365 - $this->MBWrite($h,$txt,$link);
366 - else
367 - parent::Write($h,$txt,$link);
368 -}
369 -
370 -function MBWrite($h,$txt,$link)
371 -{
372 - //Multi-byte version of Write()
373 - $cw=&$this->CurrentFont['cw'];
374 - $japanese = ($this->CurrentFont['registry']['ordering'] == 'Japan1');
375 - $w=$this->w-$this->rMargin-$this->x;
376 - $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
377 - $s=str_replace("\r",'',$txt);
378 - $nb=strlen($s);
379 - $sep=-1;
380 - $i=0;
381 - $j=0;
382 - $l=0;
383 - $nl=1;
384 - while($i<$nb)
385 - {
386 - //Get next character
387 - $c=$s[$i];
388 - //Check if ASCII or MB
389 - $ascii=(ord($c)<128);
390 - $hwkana = ($japanese && ord($c)==142);
391 - if($c=="\n")
392 - {
393 - //Explicit line break
394 - $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
395 - $i++;
396 - $sep=-1;
397 - $j=$i;
398 - $l=0;
399 - if($nl==1)
400 - {
401 - $this->x=$this->lMargin;
402 - $w=$this->w-$this->rMargin-$this->x;
403 - $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
404 - }
405 - $nl++;
406 - continue;
407 - }
408 - if(!$ascii or $c==' ')
409 - $sep=$i;
410 - $l+=$ascii ? $cw[$c] : $hwkana ? 500 : 1000;
411 - if($l>$wmax)
412 - {
413 - //Automatic line break
414 - if($sep==-1 or $i==$j)
415 - {
416 - if($this->x>$this->lMargin)
417 - {
418 - //Move to next line
419 - $this->x=$this->lMargin;
420 - $this->y+=$h;
421 - $w=$this->w-$this->rMargin-$this->x;
422 - $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
423 - $i++;
424 - $nl++;
425 - continue;
426 - }
427 - if($i==$j)
428 - $i+=$ascii ? 1 : 2;
429 - $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
430 - }
431 - else
432 - {
433 - $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link);
434 - $i=($s[$sep]==' ') ? $sep+1 : $sep;
435 - }
436 - $sep=-1;
437 - $j=$i;
438 - $l=0;
439 - if($nl==1)
440 - {
441 - $this->x=$this->lMargin;
442 - $w=$this->w-$this->rMargin-$this->x;
443 - $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
444 - }
445 - $nl++;
446 - }
447 - else
448 - $i+=$ascii ? 1 : 2;
449 - }
450 - //Last chunk
451 - if($i!=$j)
452 - $this->Cell($l/1000*$this->FontSize,$h,substr($s,$j,$i-$j),0,0,'',0,$link);
453 -}
454 -
455 -function _putfonts()
456 -{
457 - $nf=$this->n;
458 - foreach($this->diffs as $diff)
459 - {
460 - //Encodings
461 - $this->_newobj();
462 - $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
463 - $this->_out('endobj');
464 - }
465 -// $mqr=get_magic_quotes_runtime();
466 -// set_magic_quotes_runtime(0);
467 - foreach($this->FontFiles as $file=>$info)
468 - {
469 - //Font file embedding
470 - $this->_newobj();
471 - $this->FontFiles[$file]['n']=$this->n;
472 - if(defined('FPDF_FONTPATH'))
473 - $file=FPDF_FONTPATH.$file;
474 - $size=filesize($file);
475 - if(!$size)
476 - $this->Error('Font file not found');
477 - $this->_out('<</Length '.$size);
478 - if(substr($file,-2)=='.z')
479 - $this->_out('/Filter /FlateDecode');
480 - $this->_out('/Length1 '.$info['length1']);
481 - if(isset($info['length2']))
482 - $this->_out('/Length2 '.$info['length2'].' /Length3 0');
483 - $this->_out('>>');
484 - $f=fopen($file,'rb');
485 - $this->_putstream(fread($f,$size));
486 - fclose($f);
487 - $this->_out('endobj');
488 - }
489 -// set_magic_quotes_runtime($mqr);
490 - foreach($this->fonts as $k=>$font)
491 - {
492 - //Font objects
493 - $this->_newobj();
494 - $this->fonts[$k]['n']=$this->n;
495 - $this->_out('<</Type /Font');
496 - if($font['type']=='Type0')
497 - $this->_putType0($font);
498 - else
499 - {
500 - $name=$font['name'];
501 - $this->_out('/BaseFont /'.$name);
502 - if($font['type']=='core')
503 - {
504 - //Standard font
505 - $this->_out('/Subtype /Type1');
506 - if($name!='Symbol' and $name!='ZapfDingbats')
507 - $this->_out('/Encoding /WinAnsiEncoding');
508 - }
509 - else
510 - {
511 - //Additional font
512 - $this->_out('/Subtype /'.$font['type']);
513 - $this->_out('/FirstChar 32');
514 - $this->_out('/LastChar 255');
515 - $this->_out('/Widths '.($this->n+1).' 0 R');
516 - $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
517 - if($font['enc'])
518 - {
519 - if(isset($font['diff']))
520 - $this->_out('/Encoding '.($nf+$font['diff']).' 0 R');
521 - else
522 - $this->_out('/Encoding /WinAnsiEncoding');
523 - }
524 - }
525 - $this->_out('>>');
526 - $this->_out('endobj');
527 - if($font['type']!='core')
528 - {
529 - //Widths
530 - $this->_newobj();
531 - $cw=&$font['cw'];
532 - $s='[';
533 - for($i=32;$i<=255;$i++)
534 - $s.=$cw[chr($i)].' ';
535 - $this->_out($s.']');
536 - $this->_out('endobj');
537 - //Descriptor
538 - $this->_newobj();
539 - $s='<</Type /FontDescriptor /FontName /'.$name;
540 - foreach($font['desc'] as $k=>$v)
541 - $s.=' /'.$k.' '.$v;
542 - $file=$font['file'];
543 - if($file)
544 - $s.=' /FontFile'.($font['type']=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R';
545 - $this->_out($s.'>>');
546 - $this->_out('endobj');
547 - }
548 - }
549 - }
550 -}
551 -
552 -function _putType0($font)
553 -{
554 - //Type0
555 - $this->_out('/Subtype /Type0');
556 - $this->_out('/BaseFont /'.$font['name'].'-'.$font['CMap']);
557 - $this->_out('/Encoding /'.$font['CMap']);
558 - $this->_out('/DescendantFonts ['.($this->n+1).' 0 R]');
559 - $this->_out('>>');
560 - $this->_out('endobj');
561 - //CIDFont
562 - $this->_newobj();
563 - $this->_out('<</Type /Font');
564 - $this->_out('/Subtype /CIDFontType0');
565 - $this->_out('/BaseFont /'.$font['name']);
566 - $this->_out('/CIDSystemInfo <</Registry (Adobe) /Ordering ('.$font['registry']['ordering'].') /Supplement '.$font['registry']['supplement'].'>>');
567 - $this->_out('/FontDescriptor '.($this->n+1).' 0 R');
568 - $W='/W [1 [';
569 - foreach($font['cw'] as $w)
570 - $W.=$w.' ';
571 - $this->_out($W.']');
572 - if($font['registry']['ordering'] == 'Japan1')
573 - $this->_out(' 231 325 500 631 [500] 326 389 500');
574 - $this->_out(']');
575 - $this->_out('>>');
576 - $this->_out('endobj');
577 - //Font descriptor
578 - $this->_newobj();
579 - $this->_out('<</Type /FontDescriptor');
580 - $this->_out('/FontName /'.$font['name']);
581 - $this->_out('/Flags 6');
582 - $this->_out('/FontBBox [0 0 1000 1000]');
583 - $this->_out('/ItalicAngle 0');
584 - $this->_out('/Ascent 1000');
585 - $this->_out('/Descent 0');
586 - $this->_out('/CapHeight 1000');
587 - $this->_out('/StemV 10');
588 - $this->_out('>>');
589 - $this->_out('endobj');
590 -}
591 -}
592 -?>
1 +<?php
2 +//-------------------------------------------------------------------------
3 +// Multi-Byte FPDF version: 1.0b
4 +//-------------------------------------------------------------------------
5 +// Usage: AddMBFont(FontName,Encoding);
6 +//
7 +// Example:
8 +// Chinese: AddMBFont(BIG5 ,'BIG5');
9 +// Japanese: AddMBFont(GOTHIC,'SJIS');
10 +
11 +require(USCES_PLUGIN_DIR.'/classes/fpdf/fpdf.php'); // Original Class
12 +require(USCES_PLUGIN_DIR.'/classes/fpdf/font/mbttfdef.php'); // Multi-Byte TrueType Font Define
13 +
14 +// FPDF Version Check
15 +if ((float) FPDF_VERSION < 1.51) die("You need FPDF version 1.51");
16 +
17 +// Encoding & CMap List (CMap information from Acrobat Reader Resource/CMap folder)
18 +$MBCMAP['BIG5'] = array ('CMap'=>'ETenms-B5-H' ,'Ordering'=>'CNS1' ,'Supplement'=>0);
19 +$MBCMAP['GB'] = array ('CMap'=>'GBKp-EUC-H' ,'Ordering'=>'GB1' ,'Supplement'=>2);
20 +$MBCMAP['SJIS'] = array ('CMap'=>'90msp-RKSJ-H' ,'Ordering'=>'Japan1','Supplement'=>2);
21 +$MBCMAP['UNIJIS'] = array ('CMap'=>'UniJIS-UTF16-H','Ordering'=>'Japan1','Supplement'=>5);
22 +$MBCMAP['EUC-JP'] = array ('CMap'=>'EUC-H' ,'Ordering'=>'Japan1','Supplement'=>1);
23 +// EUC-JP has *problem* of underline and not support half-pitch characters.
24 +
25 +// if you want convert encoding to SJIS from EUC-JP, you must change $EUC2SJIS to true.
26 +$EUC2SJIS = false;
27 +
28 +// Short Font Name ------------------------------------------------------------
29 +// For Acrobat Reader (Windows, MacOS, Linux, Solaris etc)
30 +DEFINE("BIG5", 'MSungStd-Light-Acro');
31 +DEFINE("GB", 'STSongStd-Light-Acro');
32 +DEFINE("KOZMIN", 'KozMinPro-Regular-Acro');
33 +// For Japanese Windows Only
34 +DEFINE("GOTHIC", 'MS-Gothic');
35 +DEFINE("PGOTHIC", 'MS-PGothic');
36 +DEFINE("UIGOTHIC",'MS-UIGothic');
37 +DEFINE("MINCHO", 'MS-Mincho');
38 +DEFINE("PMINCHO", 'MS-PMincho');
39 +
40 +class MBFPDF extends FPDF
41 +{
42 +
43 +// For Outline, Title, Sub-Title and ETC Multi-Byte Encoding
44 +function _unicode($txt)
45 +{
46 + if (function_exists('mb_detect_encoding')) {
47 + if (mb_detect_encoding($txt) != "ASCII") {
48 + $txt = chr(254).chr(255).mb_convert_encoding($txt,"UTF-16","auto");
49 + }
50 + }
51 + return $txt;
52 +}
53 +
54 +function AddCIDFont($family,$style,$name,$cw,$CMap,$registry,$ut,$up)
55 +{
56 + $i=count($this->fonts)+1;
57 + $fontkey=strtolower($family).strtoupper($style);
58 + $this->fonts[$fontkey] =
59 + array('i'=>$i,'type'=>'Type0','name'=>$name,'up'=>$up,'ut'=>$ut,'cw'=>$cw,'CMap'=>$CMap,'registry'=>$registry);
60 +}
61 +
62 +function AddMBFont($family='',$enc='')
63 +{
64 + global $MBTTFDEF,$MBCMAP;
65 + $gt=$MBTTFDEF;
66 + $gc=$MBCMAP;
67 + if ($enc == '' || isset($gc[$enc]) == false) {
68 + die("AddMBFont: ERROR Encoding [$enc] Undefine.");
69 + }
70 + if (isset($gt[$family])) {
71 + $ut=$gt[$family]['ut'];
72 + $up=$gt[$family]['up'];
73 + $cw=$gt[$family]['cw'];
74 + $cm=$gc[$enc]['CMap'];
75 + $od=$gc[$enc]['Ordering'];
76 + $sp=$gc[$enc]['Supplement'];
77 + $registry=array('ordering'=>$od,'supplement'=>$sp);
78 + $this->AddCIDFont($family,'' ,"$family" ,$cw,$cm,$registry,$ut,$up);
79 + $this->AddCIDFont($family,'B' ,"$family,Bold" ,$cw,$cm,$registry,$ut,$up);
80 + $this->AddCIDFont($family,'I' ,"$family,Italic" ,$cw,$cm,$registry,$ut,$up);
81 + $this->AddCIDFont($family,'BI',"$family,BoldItalic",$cw,$cm,$registry,$ut,$up);
82 + } else {
83 + die("AddMBFont: ERROR FontName [$family] Undefine.");
84 + }
85 +}
86 +
87 +function GetStringWidth($s)
88 +{
89 + if($this->CurrentFont['type']=='Type0')
90 + return $this->GetMBStringWidth($s);
91 + else
92 + return parent::GetStringWidth($s);
93 +}
94 +
95 +function GetMBStringWidth($s)
96 +{
97 + //Multi-byte version of GetStringWidth()
98 + $l=0;
99 + $cw=&$this->CurrentFont['cw'];
100 + $japanese = ($this->CurrentFont['registry']['ordering'] == 'Japan1');
101 + $nb=strlen($s);
102 + $i=0;
103 + while($i<$nb)
104 + {
105 + $c=$s[$i];
106 + if(ord($c)<128)
107 + {
108 + $l+=$cw[$c];
109 + $i++;
110 + }
111 + else
112 + {
113 + $hwkana = ($japanese && ord($c)==142);
114 + $l+=$hwkana ? 500 : 1000;
115 + $i+=2;
116 + }
117 + }
118 + return $l*$this->FontSize/1000;
119 +}
120 +
121 +// Function Cell override for Encode Change.
122 +function Cell($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = 0, $link = '')
123 +{
124 +
125 + $k = $this->k;
126 +
127 + if ($this->y + $h > $this->PageBreakTrigger
128 + && !$this->InFooter
129 + && $this->AcceptPageBreak()) {
130 + $x = $this->x;
131 + $ws = $this->ws;
132 + if ($ws > 0) {
133 + $this->ws = 0;
134 + $this->_out('0 Tw');
135 + }
136 + $this->AddPage($this->CurOrientation);
137 + $this->x = $x;
138 + if ($ws > 0) {
139 + $this->ws = $ws;
140 + $this->_out(sprintf('%.3f Tw', $ws * $k));
141 + }
142 + } // end if
143 +
144 + if ($w == 0) {
145 + $w = $this->w - $this->rMargin - $this->x;
146 + }
147 +
148 + $s = '';
149 + if ($fill == 1 || $border == 1) {
150 + if ($fill == 1) {
151 + $op = ($border == 1) ? 'B' : 'f';
152 + } else {
153 + $op = 'S';
154 + }
155 + $s = sprintf('%.2f %.2f %.2f %.2f re %s ', $this->x * $k, ($this->h - $this->y) * $k, $w * $k, -$h * $k, $op);
156 + } // end if
157 +
158 + if (is_string($border)) {
159 + $x = $this->x;
160 + $y = $this->y;
161 + if (strpos(' ' . $border, 'L')) {
162 + $s .= sprintf('%.2f %.2f m %.2f %.2f l S ', $x * $k, ($this->h - $y) * $k, $x * $k, ($this->h - ($y+$h)) * $k);
163 + }
164 + if (strpos(' ' . $border, 'T')) {
165 + $s .= sprintf('%.2f %.2f m %.2f %.2f l S ', $x * $k, ($this->h - $y) * $k, ($x + $w) * $k, ($this->h - $y) * $k);
166 + }
167 + if (strpos(' ' . $border, 'R')) {
168 + $s .= sprintf('%.2f %.2f m %.2f %.2f l S ', ($x + $w) * $k, ($this->h - $y) * $k, ($x + $w) * $k, ($this->h - ($y + $h)) * $k);
169 + }
170 + if (strpos(' ' . $border, 'B')) {
171 + $s .= sprintf('%.2f %.2f m %.2f %.2f l S ', $x * $k, ($this->h - ($y + $h)) * $k, ($x + $w) * $k, ($this->h - ($y + $h)) * $k);
172 + }
173 + } // end if
174 +
175 + if ($txt != '') {
176 + if ($align == 'R') {
177 + $dx = $w - $this->cMargin - $this->GetStringWidth($txt);
178 + }
179 + else if ($align == 'C') {
180 + $dx = ($w - $this->GetStringWidth($txt)) / 2;
181 + }
182 + else {
183 + $dx = $this->cMargin;
184 + }
185 + // For Japanese Encode Change
186 + global $EUC2SJIS;
187 + if ($EUC2SJIS && function_exists('mb_convert_encoding')) {
188 + $txt = mb_convert_encoding($txt,"SJIS","EUC-JP");
189 + }
190 + $txt = str_replace(')', '\\)', str_replace('(', '\\(', str_replace('\\', '\\\\', $txt)));
191 + if ($this->ColorFlag) {
192 + $s .= 'q ' . $this->TextColor . ' ';
193 + }
194 + $s .= sprintf('BT %.2f %.2f Td (%s) Tj ET', ($this->x + $dx) * $k, ($this->h - ($this->y + .5 * $h + .3 * $this->FontSize)) * $k, $txt);
195 + $txt = stripslashes($txt);
196 + if ($this->underline) {
197 + $s .= ' ' . $this->_dounderline($this->x+$dx, $this->y + .5 * $h + .3 * $this->FontSize, $txt);
198 + }
199 + if ($this->ColorFlag) {
200 + $s .= ' Q';
201 + }
202 + if ($link) {
203 + $this->Link($this->x + $dx, $this->y + .5 * $h - .5 * $this->FontSize, $this->GetStringWidth($txt), $this->FontSize, $link);
204 + }
205 + } // end if
206 +
207 + if ($s) {
208 + $this->_out($s);
209 + }
210 + $this->lasth = $h;
211 +
212 + if ($ln > 0) {
213 + // Go to next line
214 + $this->y += $h;
215 + if ($ln == 1) {
216 + $this->x = $this->lMargin;
217 + }
218 + } else {
219 + $this->x += $w;
220 + }
221 +} // end of the "Cell()" method
222 +
223 +function MultiCell($w,$h,$txt,$border=0,$align='L',$fill=0)
224 +{
225 + if($this->CurrentFont['type']=='Type0')
226 + $this->MBMultiCell($w,$h,$txt,$border,$align,$fill);
227 + else
228 + parent::MultiCell($w,$h,$txt,$border,$align,$fill);
229 +}
230 +
231 +function MBMultiCell($w,$h,$txt,$border=0,$align='L',$fill=0)
232 +{
233 + //Multi-byte version of MultiCell()
234 + $cw=&$this->CurrentFont['cw'];
235 + $japanese = ($this->CurrentFont['registry']['ordering'] == 'Japan1');
236 + if($w==0)
237 + $w=$this->w-$this->rMargin-$this->x;
238 + $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
239 + $s=str_replace("\r",'',$txt);
240 + $nb=strlen($s);
241 + if($nb>0 and $s[$nb-1]=="\n")
242 + $nb--;
243 + $b=0;
244 + if($border)
245 + {
246 + if($border==1)
247 + {
248 + $border='LTRB';
249 + $b='LRT';
250 + $b2='LR';
251 + }
252 + else
253 + {
254 + $b2='';
255 + if(is_int(strpos($border,'L')))
256 + $b2.='L';
257 + if(is_int(strpos($border,'R')))
258 + $b2.='R';
259 + $b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
260 + }
261 + }
262 + $sep=-1;
263 + $i=0;
264 + $j=0;
265 + $l=0;
266 + $ns=0;
267 + $nl=1;
268 + $ascii=true;
269 + while($i<$nb)
270 + {
271 + //Get next character
272 + $c=$s[$i];
273 + //Check if ASCII or MB
274 + $prev_ascii=$ascii;
275 + $ascii=(ord($c)<128);
276 + $hwkana = ($japanese && ord($c)==142);
277 + if($c=="\n")
278 + {
279 + //Explicit line break
280 + if($this->ws>0)
281 + {
282 + $this->ws=0;
283 + $this->_out('0 Tw');
284 + }
285 + $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
286 + $i++;
287 + $sep=-1;
288 + $j=$i;
289 + $l=0;
290 + $ns=0;
291 + $nl++;
292 + if($border and $nl==2)
293 + $b=$b2;
294 + continue;
295 + }
296 + if(!($ascii && $prev_ascii) && $i != $j)
297 + {
298 + $sep=$i;
299 + $ls=$l;
300 + }
301 + elseif($c==' ')
302 + {
303 + $sep=$i;
304 + $ls=$l;
305 + $ns++;
306 + }
307 + $l+=$ascii ? $cw[$c] : $hwkana ? 500 : 1000;
308 + if($l>$wmax)
309 + {
310 + //Automatic line break
311 + if($sep==-1)
312 + {
313 + if($i==$j)
314 + $i+=$ascii ? 1 : 2;
315 + if($this->ws>0)
316 + {
317 + $this->ws=0;
318 + $this->_out('0 Tw');
319 + }
320 + $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
321 + }
322 + else
323 + {
324 + if($align=='J')
325 + {
326 + if($s[$sep]==' ')
327 + $ns--;
328 + if($s[$i-1]==' ')
329 + {
330 + $ns--;
331 + $ls-=$cw[' '];
332 + }
333 + $this->ws=($ns>0) ? ($wmax-$ls)/1000*$this->FontSize/$ns : 0;
334 + $this->_out(sprintf('%.3f Tw',$this->ws*$this->k));
335 + }
336 + $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill);
337 + $i=($s[$sep]==' ') ? $sep+1 : $sep;
338 + }
339 + $sep=-1;
340 + $j=$i;
341 + $l=0;
342 + $ns=0;
343 + $nl++;
344 + if($border and $nl==2)
345 + $b=$b2;
346 + }
347 + else
348 + $i+=$ascii ? 1 : 2;
349 + }
350 + //Last chunk
351 + if($this->ws>0)
352 + {
353 + $this->ws=0;
354 + $this->_out('0 Tw');
355 + }
356 + if($border and is_int(strpos($border,'B')))
357 + $b.='B';
358 + $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
359 + $this->x=$this->lMargin;
360 +}
361 +
362 +function Write($h,$txt,$link='')
363 +{
364 + if($this->CurrentFont['type']=='Type0')
365 + $this->MBWrite($h,$txt,$link);
366 + else
367 + parent::Write($h,$txt,$link);
368 +}
369 +
370 +function MBWrite($h,$txt,$link)
371 +{
372 + //Multi-byte version of Write()
373 + $cw=&$this->CurrentFont['cw'];
374 + $japanese = ($this->CurrentFont['registry']['ordering'] == 'Japan1');
375 + $w=$this->w-$this->rMargin-$this->x;
376 + $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
377 + $s=str_replace("\r",'',$txt);
378 + $nb=strlen($s);
379 + $sep=-1;
380 + $i=0;
381 + $j=0;
382 + $l=0;
383 + $nl=1;
384 + while($i<$nb)
385 + {
386 + //Get next character
387 + $c=$s[$i];
388 + //Check if ASCII or MB
389 + $ascii=(ord($c)<128);
390 + $hwkana = ($japanese && ord($c)==142);
391 + if($c=="\n")
392 + {
393 + //Explicit line break
394 + $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
395 + $i++;
396 + $sep=-1;
397 + $j=$i;
398 + $l=0;
399 + if($nl==1)
400 + {
401 + $this->x=$this->lMargin;
402 + $w=$this->w-$this->rMargin-$this->x;
403 + $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
404 + }
405 + $nl++;
406 + continue;
407 + }
408 + if(!$ascii or $c==' ')
409 + $sep=$i;
410 + $l+=$ascii ? $cw[$c] : $hwkana ? 500 : 1000;
411 + if($l>$wmax)
412 + {
413 + //Automatic line break
414 + if($sep==-1 or $i==$j)
415 + {
416 + if($this->x>$this->lMargin)
417 + {
418 + //Move to next line
419 + $this->x=$this->lMargin;
420 + $this->y+=$h;
421 + $w=$this->w-$this->rMargin-$this->x;
422 + $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
423 + $i++;
424 + $nl++;
425 + continue;
426 + }
427 + if($i==$j)
428 + $i+=$ascii ? 1 : 2;
429 + $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
430 + }
431 + else
432 + {
433 + $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link);
434 + $i=($s[$sep]==' ') ? $sep+1 : $sep;
435 + }
436 + $sep=-1;
437 + $j=$i;
438 + $l=0;
439 + if($nl==1)
440 + {
441 + $this->x=$this->lMargin;
442 + $w=$this->w-$this->rMargin-$this->x;
443 + $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
444 + }
445 + $nl++;
446 + }
447 + else
448 + $i+=$ascii ? 1 : 2;
449 + }
450 + //Last chunk
451 + if($i!=$j)
452 + $this->Cell($l/1000*$this->FontSize,$h,substr($s,$j,$i-$j),0,0,'',0,$link);
453 +}
454 +
455 +function _putfonts()
456 +{
457 + $nf=$this->n;
458 + foreach($this->diffs as $diff)
459 + {
460 + //Encodings
461 + $this->_newobj();
462 + $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
463 + $this->_out('endobj');
464 + }
465 +// $mqr=get_magic_quotes_runtime();
466 +// set_magic_quotes_runtime(0);
467 + foreach($this->FontFiles as $file=>$info)
468 + {
469 + //Font file embedding
470 + $this->_newobj();
471 + $this->FontFiles[$file]['n']=$this->n;
472 + if(defined('FPDF_FONTPATH'))
473 + $file=FPDF_FONTPATH.$file;
474 + $size=filesize($file);
475 + if(!$size)
476 + $this->Error('Font file not found');
477 + $this->_out('<</Length '.$size);
478 + if(substr($file,-2)=='.z')
479 + $this->_out('/Filter /FlateDecode');
480 + $this->_out('/Length1 '.$info['length1']);
481 + if(isset($info['length2']))
482 + $this->_out('/Length2 '.$info['length2'].' /Length3 0');
483 + $this->_out('>>');
484 + $f=fopen($file,'rb');
485 + $this->_putstream(fread($f,$size));
486 + fclose($f);
487 + $this->_out('endobj');
488 + }
489 +// set_magic_quotes_runtime($mqr);
490 + foreach($this->fonts as $k=>$font)
491 + {
492 + //Font objects
493 + $this->_newobj();
494 + $this->fonts[$k]['n']=$this->n;
495 + $this->_out('<</Type /Font');
496 + if($font['type']=='Type0')
497 + $this->_putType0($font);
498 + else
499 + {
500 + $name=$font['name'];
501 + $this->_out('/BaseFont /'.$name);
502 + if($font['type']=='core')
503 + {
504 + //Standard font
505 + $this->_out('/Subtype /Type1');
506 + if($name!='Symbol' and $name!='ZapfDingbats')
507 + $this->_out('/Encoding /WinAnsiEncoding');
508 + }
509 + else
510 + {
511 + //Additional font
512 + $this->_out('/Subtype /'.$font['type']);
513 + $this->_out('/FirstChar 32');
514 + $this->_out('/LastChar 255');
515 + $this->_out('/Widths '.($this->n+1).' 0 R');
516 + $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
517 + if($font['enc'])
518 + {
519 + if(isset($font['diff']))
520 + $this->_out('/Encoding '.($nf+$font['diff']).' 0 R');
521 + else
522 + $this->_out('/Encoding /WinAnsiEncoding');
523 + }
524 + }
525 + $this->_out('>>');
526 + $this->_out('endobj');
527 + if($font['type']!='core')
528 + {
529 + //Widths
530 + $this->_newobj();
531 + $cw=&$font['cw'];
532 + $s='[';
533 + for($i=32;$i<=255;$i++)
534 + $s.=$cw[chr($i)].' ';
535 + $this->_out($s.']');
536 + $this->_out('endobj');
537 + //Descriptor
538 + $this->_newobj();
539 + $s='<</Type /FontDescriptor /FontName /'.$name;
540 + foreach($font['desc'] as $k=>$v)
541 + $s.=' /'.$k.' '.$v;
542 + $file=$font['file'];
543 + if($file)
544 + $s.=' /FontFile'.($font['type']=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R';
545 + $this->_out($s.'>>');
546 + $this->_out('endobj');
547 + }
548 + }
549 + }
550 +}
551 +
552 +function _putType0($font)
553 +{
554 + //Type0
555 + $this->_out('/Subtype /Type0');
556 + $this->_out('/BaseFont /'.$font['name'].'-'.$font['CMap']);
557 + $this->_out('/Encoding /'.$font['CMap']);
558 + $this->_out('/DescendantFonts ['.($this->n+1).' 0 R]');
559 + $this->_out('>>');
560 + $this->_out('endobj');
561 + //CIDFont
562 + $this->_newobj();
563 + $this->_out('<</Type /Font');
564 + $this->_out('/Subtype /CIDFontType0');
565 + $this->_out('/BaseFont /'.$font['name']);
566 + $this->_out('/CIDSystemInfo <</Registry (Adobe) /Ordering ('.$font['registry']['ordering'].') /Supplement '.$font['registry']['supplement'].'>>');
567 + $this->_out('/FontDescriptor '.($this->n+1).' 0 R');
568 + $W='/W [1 [';
569 + foreach($font['cw'] as $w)
570 + $W.=$w.' ';
571 + $this->_out($W.']');
572 + if($font['registry']['ordering'] == 'Japan1')
573 + $this->_out(' 231 325 500 631 [500] 326 389 500');
574 + $this->_out(']');
575 + $this->_out('>>');
576 + $this->_out('endobj');
577 + //Font descriptor
578 + $this->_newobj();
579 + $this->_out('<</Type /FontDescriptor');
580 + $this->_out('/FontName /'.$font['name']);
581 + $this->_out('/Flags 6');
582 + $this->_out('/FontBBox [0 0 1000 1000]');
583 + $this->_out('/ItalicAngle 0');
584 + $this->_out('/Ascent 1000');
585 + $this->_out('/Descent 0');
586 + $this->_out('/CapHeight 1000');
587 + $this->_out('/StemV 10');
588 + $this->_out('>>');
589 + $this->_out('endobj');
590 +}
591 +}
592 +?>