PageRenderTime 26ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/admin/phpMyAdmin_old/libraries/fpdf/ufpdf.php

https://bitbucket.org/steve_delbar/iepsm-projet-de-d-veloppement-internet-2013
PHP | 483 lines | 384 code | 34 blank | 65 comment | 101 complexity | 754cac83e852daa8b6bb2a906488f4b8 MD5 | raw file
  1. <?php
  2. /*******************************************************************************
  3. * Software: UFPDF, Unicode Free PDF generator *
  4. * Version: 0.1 *
  5. * based on FPDF 1.52 by Olivier PLATHEY *
  6. * Date: 2004-09-01 *
  7. * Author: Steven Wittens <steven@acko.net> *
  8. * License: GPL *
  9. * *
  10. * UFPDF is a modification of FPDF to support Unicode through UTF-8. *
  11. * *
  12. *******************************************************************************/
  13. if(!class_exists('UFPDF'))
  14. {
  15. define('UFPDF_VERSION','0.1');
  16. include_once './libraries/fpdf/fpdf.php';
  17. class UFPDF extends FPDF
  18. {
  19. /*******************************************************************************
  20. * *
  21. * Public methods *
  22. * *
  23. *******************************************************************************/
  24. function UFPDF($orientation='P',$unit='mm',$format='A4')
  25. {
  26. FPDF::FPDF($orientation, $unit, $format);
  27. }
  28. function GetStringWidth($s)
  29. {
  30. //Get width of a string in the current font
  31. $s = (string)$s;
  32. $codepoints=$this->utf8_to_codepoints($s);
  33. $cw=&$this->CurrentFont['cw'];
  34. $w=0;
  35. foreach($codepoints as $cp)
  36. $w+=isset($cw[$cp])?$cw[$cp]:0;
  37. return $w*$this->FontSize/1000;
  38. }
  39. function AddFont($family,$style='',$file='')
  40. {
  41. //Add a TrueType or Type1 font
  42. $family=strtolower($family);
  43. if($family=='arial')
  44. $family='helvetica';
  45. $style=strtoupper($style);
  46. if($style=='IB')
  47. $style='BI';
  48. if(isset($this->fonts[$family.$style]))
  49. $this->Error('Font already added: '.$family.' '.$style);
  50. if($file=='')
  51. $file=str_replace(' ','',$family).strtolower($style).'.php';
  52. if(defined('FPDF_FONTPATH'))
  53. $file=FPDF_FONTPATH.$file;
  54. include($file);
  55. if(!isset($name))
  56. $this->Error('Could not include font definition file');
  57. $i=count($this->fonts)+1;
  58. $this->fonts[$family.$style]=array('i'=>$i,'type'=>$type,'name'=>$name,'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw,'file'=>$file,'ctg'=>$ctg);
  59. if($file)
  60. {
  61. if($type=='TrueTypeUnicode')
  62. $this->FontFiles[$file]=array('length1'=>$originalsize);
  63. else
  64. $this->FontFiles[$file]=array('length1'=>$size1,'length2'=>$size2);
  65. }
  66. }
  67. function Text($x,$y,$txt)
  68. {
  69. //Output a string
  70. $s=sprintf('BT %.2f %.2f Td %s Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escapetext($txt));
  71. if($this->underline and $txt!='')
  72. $s.=' '.$this->_dounderline($x,$y,$this->GetStringWidth($txt),$txt);
  73. if($this->ColorFlag)
  74. $s='q '.$this->TextColor.' '.$s.' Q';
  75. $this->_out($s);
  76. }
  77. function AcceptPageBreak()
  78. {
  79. //Accept automatic page break or not
  80. return $this->AutoPageBreak;
  81. }
  82. function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='')
  83. {
  84. //Output a cell
  85. $k=$this->k;
  86. if($this->y+$h>$this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak())
  87. {
  88. //Automatic page break
  89. $x=$this->x;
  90. $ws=$this->ws;
  91. if($ws>0)
  92. {
  93. $this->ws=0;
  94. $this->_out('0 Tw');
  95. }
  96. $this->AddPage($this->CurOrientation);
  97. $this->x=$x;
  98. if($ws>0)
  99. {
  100. $this->ws=$ws;
  101. $this->_out(sprintf('%.3f Tw',$ws*$k));
  102. }
  103. }
  104. if($w==0)
  105. $w=$this->w-$this->rMargin-$this->x;
  106. $s='';
  107. if($fill==1 or $border==1)
  108. {
  109. if($fill==1)
  110. $op=($border==1) ? 'B' : 'f';
  111. else
  112. $op='S';
  113. $s=sprintf('%.2f %.2f %.2f %.2f re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op);
  114. }
  115. if(is_string($border))
  116. {
  117. $x=$this->x;
  118. $y=$this->y;
  119. if(is_int(strpos($border,'L')))
  120. $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k);
  121. if(is_int(strpos($border,'T')))
  122. $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k);
  123. if(is_int(strpos($border,'R')))
  124. $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
  125. if(is_int(strpos($border,'B')))
  126. $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
  127. }
  128. if($txt!='')
  129. {
  130. $width = $this->GetStringWidth($txt);
  131. if($align=='R')
  132. $dx=$w-$this->cMargin-$width;
  133. elseif($align=='C')
  134. $dx=($w-$width)/2;
  135. else
  136. $dx=$this->cMargin;
  137. if($this->ColorFlag)
  138. $s.='q '.$this->TextColor.' ';
  139. $txtstring=$this->_escapetext($txt);
  140. $s.=sprintf('BT %.2f %.2f Td %s Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txtstring);
  141. if($this->underline)
  142. $s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$width,$txt);
  143. if($this->ColorFlag)
  144. $s.=' Q';
  145. if($link)
  146. $this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$width,$this->FontSize,$link);
  147. }
  148. if($s)
  149. $this->_out($s);
  150. $this->lasth=$h;
  151. if($ln>0)
  152. {
  153. //Go to next line
  154. $this->y+=$h;
  155. if($ln==1)
  156. $this->x=$this->lMargin;
  157. }
  158. else
  159. $this->x+=$w;
  160. }
  161. /*******************************************************************************
  162. * *
  163. * Protected methods *
  164. * *
  165. *******************************************************************************/
  166. function _puttruetypeunicode($font) {
  167. //Type0 Font
  168. $this->_newobj();
  169. $this->_out('<</Type /Font');
  170. $this->_out('/Subtype /Type0');
  171. $this->_out('/BaseFont /'. $font['name'] .'-UCS');
  172. $this->_out('/Encoding /Identity-H');
  173. $this->_out('/DescendantFonts ['. ($this->n + 1) .' 0 R]');
  174. $this->_out('>>');
  175. $this->_out('endobj');
  176. //CIDFont
  177. $this->_newobj();
  178. $this->_out('<</Type /Font');
  179. $this->_out('/Subtype /CIDFontType2');
  180. $this->_out('/BaseFont /'. $font['name']);
  181. $this->_out('/CIDSystemInfo <</Registry (Adobe) /Ordering (UCS) /Supplement 0>>');
  182. $this->_out('/FontDescriptor '. ($this->n + 1) .' 0 R');
  183. $c = 0;
  184. $widths = '';
  185. foreach ($font['cw'] as $i => $w) {
  186. $widths .= $i .' ['. $w.'] ';
  187. }
  188. $this->_out('/W ['. $widths .']');
  189. $this->_out('/CIDToGIDMap '. ($this->n + 2) .' 0 R');
  190. $this->_out('>>');
  191. $this->_out('endobj');
  192. //Font descriptor
  193. $this->_newobj();
  194. $this->_out('<</Type /FontDescriptor');
  195. $this->_out('/FontName /'.$font['name']);
  196. $s = '';
  197. foreach ($font['desc'] as $k => $v) {
  198. $s .= ' /'. $k .' '. $v;
  199. }
  200. if ($font['file']) {
  201. $s .= ' /FontFile2 '. $this->FontFiles[$font['file']]['n'] .' 0 R';
  202. }
  203. $this->_out($s);
  204. $this->_out('>>');
  205. $this->_out('endobj');
  206. //Embed CIDToGIDMap
  207. $this->_newobj();
  208. if(defined('FPDF_FONTPATH'))
  209. $file=FPDF_FONTPATH.$font['ctg'];
  210. else
  211. $file=$font['ctg'];
  212. $size=filesize($file);
  213. if(!$size)
  214. $this->Error('Font file not found');
  215. $this->_out('<</Length '.$size);
  216. if(substr($file,-2) == '.z')
  217. $this->_out('/Filter /FlateDecode');
  218. $this->_out('>>');
  219. $f = fopen($file,'rb');
  220. $this->_putstream(fread($f,$size));
  221. fclose($f);
  222. $this->_out('endobj');
  223. }
  224. function _dounderline($x,$y,$width,$txt)
  225. {
  226. //Underline text
  227. $up=$this->CurrentFont['up'];
  228. $ut=$this->CurrentFont['ut'];
  229. $w=$width+$this->ws*substr_count($txt,' ');
  230. return sprintf('%.2f %.2f %.2f %.2f re f',$x*$this->k,($this->h-($y-$up/1000*$this->FontSize))*$this->k,$w*$this->k,-$ut/1000*$this->FontSizePt);
  231. }
  232. function _textstring($s)
  233. {
  234. //Convert to UTF-16BE
  235. $s = $this->utf8_to_utf16be($s);
  236. //Escape necessary characters
  237. return '('. strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\')) .')';
  238. }
  239. function _strreplace($what, $to, $where) {
  240. $to = '' . $to;
  241. return str_replace($this->utf8_to_utf16be($what, false), $this->utf8_to_utf16be($to, false), $where);
  242. }
  243. function _escapetext($s)
  244. {
  245. //Convert to UTF-16BE
  246. $s = $this->utf8_to_utf16be($s, false);
  247. //Escape necessary characters
  248. return '('. strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\')) .')';
  249. }
  250. function _putinfo()
  251. {
  252. $this->_out('/Producer '.$this->_textstring('UFPDF '. UFPDF_VERSION));
  253. if(!empty($this->title))
  254. $this->_out('/Title '.$this->_textstring($this->title));
  255. if(!empty($this->subject))
  256. $this->_out('/Subject '.$this->_textstring($this->subject));
  257. if(!empty($this->author))
  258. $this->_out('/Author '.$this->_textstring($this->author));
  259. if(!empty($this->keywords))
  260. $this->_out('/Keywords '.$this->_textstring($this->keywords));
  261. if(!empty($this->creator))
  262. $this->_out('/Creator '.$this->_textstring($this->creator));
  263. $this->_out('/CreationDate '.$this->_textstring('D:'.date('YmdHis')));
  264. }
  265. // UTF-8 to UTF-16BE conversion.
  266. // Correctly handles all illegal UTF-8 sequences.
  267. function utf8_to_utf16be(&$txt, $bom = true) {
  268. $l = strlen($txt);
  269. $out = $bom ? "\xFE\xFF" : '';
  270. for ($i = 0; $i < $l; ++$i) {
  271. $c = ord($txt{$i});
  272. // ASCII
  273. if ($c < 0x80) {
  274. $out .= "\x00". $txt{$i};
  275. }
  276. // Lost continuation byte
  277. else if ($c < 0xC0) {
  278. $out .= "\xFF\xFD";
  279. continue;
  280. }
  281. // Multibyte sequence leading byte
  282. else {
  283. if ($c < 0xE0) {
  284. $s = 2;
  285. }
  286. else if ($c < 0xF0) {
  287. $s = 3;
  288. }
  289. else if ($c < 0xF8) {
  290. $s = 4;
  291. }
  292. // 5/6 byte sequences not possible for Unicode.
  293. else {
  294. $out .= "\xFF\xFD";
  295. while (ord($txt{$i + 1}) >= 0x80 && ord($txt{$i + 1}) < 0xC0) { ++$i; }
  296. continue;
  297. }
  298. $q = array($c);
  299. // Fetch rest of sequence
  300. $l = strlen($txt);
  301. while ($i + 1 < $l && ord($txt{$i + 1}) >= 0x80 && ord($txt{$i + 1}) < 0xC0) { ++$i; $q[] = ord($txt{$i}); }
  302. // Check length
  303. if (count($q) != $s) {
  304. $out .= "\xFF\xFD";
  305. continue;
  306. }
  307. switch ($s) {
  308. case 2:
  309. $cp = (($q[0] ^ 0xC0) << 6) | ($q[1] ^ 0x80);
  310. // Overlong sequence
  311. if ($cp < 0x80) {
  312. $out .= "\xFF\xFD";
  313. }
  314. else {
  315. $out .= chr($cp >> 8);
  316. $out .= chr($cp & 0xFF);
  317. }
  318. continue;
  319. case 3:
  320. $cp = (($q[0] ^ 0xE0) << 12) | (($q[1] ^ 0x80) << 6) | ($q[2] ^ 0x80);
  321. // Overlong sequence
  322. if ($cp < 0x800) {
  323. $out .= "\xFF\xFD";
  324. }
  325. // Check for UTF-8 encoded surrogates (caused by a bad UTF-8 encoder)
  326. else if ($c > 0xD800 && $c < 0xDFFF) {
  327. $out .= "\xFF\xFD";
  328. }
  329. else {
  330. $out .= chr($cp >> 8);
  331. $out .= chr($cp & 0xFF);
  332. }
  333. continue;
  334. case 4:
  335. $cp = (($q[0] ^ 0xF0) << 18) | (($q[1] ^ 0x80) << 12) | (($q[2] ^ 0x80) << 6) | ($q[3] ^ 0x80);
  336. // Overlong sequence
  337. if ($cp < 0x10000) {
  338. $out .= "\xFF\xFD";
  339. }
  340. // Outside of the Unicode range
  341. else if ($cp >= 0x10FFFF) {
  342. $out .= "\xFF\xFD";
  343. }
  344. else {
  345. // Use surrogates
  346. $cp -= 0x10000;
  347. $s1 = 0xD800 | ($cp >> 10);
  348. $s2 = 0xDC00 | ($cp & 0x3FF);
  349. $out .= chr($s1 >> 8);
  350. $out .= chr($s1 & 0xFF);
  351. $out .= chr($s2 >> 8);
  352. $out .= chr($s2 & 0xFF);
  353. }
  354. continue;
  355. }
  356. }
  357. }
  358. return $out;
  359. }
  360. // UTF-8 to codepoint array conversion.
  361. // Correctly handles all illegal UTF-8 sequences.
  362. function utf8_to_codepoints(&$txt) {
  363. $l = strlen($txt);
  364. $out = array();
  365. for ($i = 0; $i < $l; ++$i) {
  366. $c = ord($txt{$i});
  367. // ASCII
  368. if ($c < 0x80) {
  369. $out[] = ord($txt{$i});
  370. }
  371. // Lost continuation byte
  372. else if ($c < 0xC0) {
  373. $out[] = 0xFFFD;
  374. continue;
  375. }
  376. // Multibyte sequence leading byte
  377. else {
  378. if ($c < 0xE0) {
  379. $s = 2;
  380. }
  381. else if ($c < 0xF0) {
  382. $s = 3;
  383. }
  384. else if ($c < 0xF8) {
  385. $s = 4;
  386. }
  387. // 5/6 byte sequences not possible for Unicode.
  388. else {
  389. $out[] = 0xFFFD;
  390. while (ord($txt{$i + 1}) >= 0x80 && ord($txt{$i + 1}) < 0xC0) { ++$i; }
  391. continue;
  392. }
  393. $q = array($c);
  394. // Fetch rest of sequence
  395. $l = strlen($txt);
  396. while ($i + 1 < $l && ord($txt{$i + 1}) >= 0x80 && ord($txt{$i + 1}) < 0xC0) { ++$i; $q[] = ord($txt{$i}); }
  397. // Check length
  398. if (count($q) != $s) {
  399. $out[] = 0xFFFD;
  400. continue;
  401. }
  402. switch ($s) {
  403. case 2:
  404. $cp = (($q[0] ^ 0xC0) << 6) | ($q[1] ^ 0x80);
  405. // Overlong sequence
  406. if ($cp < 0x80) {
  407. $out[] = 0xFFFD;
  408. }
  409. else {
  410. $out[] = $cp;
  411. }
  412. continue;
  413. case 3:
  414. $cp = (($q[0] ^ 0xE0) << 12) | (($q[1] ^ 0x80) << 6) | ($q[2] ^ 0x80);
  415. // Overlong sequence
  416. if ($cp < 0x800) {
  417. $out[] = 0xFFFD;
  418. }
  419. // Check for UTF-8 encoded surrogates (caused by a bad UTF-8 encoder)
  420. else if ($c > 0xD800 && $c < 0xDFFF) {
  421. $out[] = 0xFFFD;
  422. }
  423. else {
  424. $out[] = $cp;
  425. }
  426. continue;
  427. case 4:
  428. $cp = (($q[0] ^ 0xF0) << 18) | (($q[1] ^ 0x80) << 12) | (($q[2] ^ 0x80) << 6) | ($q[3] ^ 0x80);
  429. // Overlong sequence
  430. if ($cp < 0x10000) {
  431. $out[] = 0xFFFD;
  432. }
  433. // Outside of the Unicode range
  434. else if ($cp >= 0x10FFFF) {
  435. $out[] = 0xFFFD;
  436. }
  437. else {
  438. $out[] = $cp;
  439. }
  440. continue;
  441. }
  442. }
  443. }
  444. return $out;
  445. }
  446. //End of class
  447. }
  448. }
  449. ?>