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