Documentation TYPO3 par Ameos

ufpdf.php

00001 <?php
00002 /*******************************************************************************
00003 * Software: UFPDF, Unicode Free PDF generator                                  *
00004 * Version:  0.1                                                                *
00005 *           based on FPDF 1.52 by Olivier PLATHEY                              *
00006 * Date:     2004-09-01                                                         *
00007 * Author:   Steven Wittens <steven@acko.net>                                   *
00008 * License:  GPL                                                                *
00009 *                                                                              *
00010 * UFPDF is a modification of FPDF to support Unicode through UTF-8.            *
00011 *                                                                              *
00012 *******************************************************************************/
00013 
00014 if(!class_exists('UFPDF'))
00015 {
00016 define('UFPDF_VERSION','0.1');
00017 
00018 include_once './libraries/fpdf/fpdf.php';
00019 
00020 class UFPDF extends FPDF
00021 {
00022 
00023 /*******************************************************************************
00024 *                                                                              *
00025 *                               Public methods                                 *
00026 *                                                                              *
00027 *******************************************************************************/
00028 function UFPDF($orientation='P',$unit='mm',$format='A4')
00029 {
00030   FPDF::FPDF($orientation, $unit, $format);
00031 }
00032 
00033 function GetStringWidth($s)
00034 {
00035   //Get width of a string in the current font
00036   $s = (string)$s;
00037   $codepoints=$this->utf8_to_codepoints($s);
00038   $cw=&$this->CurrentFont['cw'];
00039   $w=0;
00040   foreach($codepoints as $cp)
00041     $w+=isset($cw[$cp])?$cw[$cp]:0;
00042   return $w*$this->FontSize/1000;
00043 }
00044 
00045 function AddFont($family,$style='',$file='')
00046 {
00047   //Add a TrueType or Type1 font
00048   $family=strtolower($family);
00049   if($family=='arial')
00050     $family='helvetica';
00051   $style=strtoupper($style);
00052   if($style=='IB')
00053     $style='BI';
00054   if(isset($this->fonts[$family.$style]))
00055     $this->Error('Font already added: '.$family.' '.$style);
00056   if($file=='')
00057     $file=str_replace(' ','',$family).strtolower($style).'.php';
00058   if(defined('FPDF_FONTPATH'))
00059     $file=FPDF_FONTPATH.$file;
00060   include($file);
00061   if(!isset($name))
00062     $this->Error('Could not include font definition file');
00063   $i=count($this->fonts)+1;
00064   $this->fonts[$family.$style]=array('i'=>$i,'type'=>$type,'name'=>$name,'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw,'file'=>$file,'ctg'=>$ctg);
00065   if($file)
00066   {
00067     if($type=='TrueTypeUnicode')
00068       $this->FontFiles[$file]=array('length1'=>$originalsize);
00069     else
00070       $this->FontFiles[$file]=array('length1'=>$size1,'length2'=>$size2);
00071   }
00072 }
00073 
00074 function Text($x,$y,$txt)
00075 {
00076   //Output a string
00077   $s=sprintf('BT %.2f %.2f Td %s Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escapetext($txt));
00078   if($this->underline and $txt!='')
00079     $s.=' '.$this->_dounderline($x,$y,$this->GetStringWidth($txt),$txt);
00080   if($this->ColorFlag)
00081     $s='q '.$this->TextColor.' '.$s.' Q';
00082   $this->_out($s);
00083 }
00084 
00085 function AcceptPageBreak()
00086 {
00087   //Accept automatic page break or not
00088   return $this->AutoPageBreak;
00089 }
00090 
00091 function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='')
00092 {
00093   //Output a cell
00094   $k=$this->k;
00095   if($this->y+$h>$this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak())
00096   {
00097     //Automatic page break
00098     $x=$this->x;
00099     $ws=$this->ws;
00100     if($ws>0)
00101     {
00102       $this->ws=0;
00103       $this->_out('0 Tw');
00104     }
00105     $this->AddPage($this->CurOrientation);
00106     $this->x=$x;
00107     if($ws>0)
00108     {
00109       $this->ws=$ws;
00110       $this->_out(sprintf('%.3f Tw',$ws*$k));
00111     }
00112   }
00113   if($w==0)
00114     $w=$this->w-$this->rMargin-$this->x;
00115   $s='';
00116   if($fill==1 or $border==1)
00117   {
00118     if($fill==1)
00119       $op=($border==1) ? 'B' : 'f';
00120     else
00121       $op='S';
00122     $s=sprintf('%.2f %.2f %.2f %.2f re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op);
00123   }
00124   if(is_string($border))
00125   {
00126     $x=$this->x;
00127     $y=$this->y;
00128     if(is_int(strpos($border,'L')))
00129       $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k);
00130     if(is_int(strpos($border,'T')))
00131       $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k);
00132     if(is_int(strpos($border,'R')))
00133       $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
00134     if(is_int(strpos($border,'B')))
00135       $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
00136   }
00137   if($txt!='')
00138   {
00139     $width = $this->GetStringWidth($txt);
00140     if($align=='R')
00141       $dx=$w-$this->cMargin-$width;
00142     elseif($align=='C')
00143       $dx=($w-$width)/2;
00144     else
00145       $dx=$this->cMargin;
00146     if($this->ColorFlag)
00147       $s.='q '.$this->TextColor.' ';
00148     $txtstring=$this->_escapetext($txt);
00149     $s.=sprintf('BT %.2f %.2f Td %s Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txtstring);
00150     if($this->underline)
00151       $s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$width,$txt);
00152     if($this->ColorFlag)
00153       $s.=' Q';
00154     if($link)
00155       $this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$width,$this->FontSize,$link);
00156   }
00157   if($s)
00158     $this->_out($s);
00159   $this->lasth=$h;
00160   if($ln>0)
00161   {
00162     //Go to next line
00163     $this->y+=$h;
00164     if($ln==1)
00165       $this->x=$this->lMargin;
00166   }
00167   else
00168     $this->x+=$w;
00169 }
00170 
00171 /*******************************************************************************
00172 *                                                                              *
00173 *                              Protected methods                               *
00174 *                                                                              *
00175 *******************************************************************************/
00176 
00177 function _puttruetypeunicode($font) {
00178   //Type0 Font
00179   $this->_newobj();
00180   $this->_out('<</Type /Font');
00181   $this->_out('/Subtype /Type0');
00182   $this->_out('/BaseFont /'. $font['name'] .'-UCS');
00183   $this->_out('/Encoding /Identity-H');
00184   $this->_out('/DescendantFonts ['. ($this->n + 1) .' 0 R]');
00185   $this->_out('>>');
00186   $this->_out('endobj');
00187 
00188   //CIDFont
00189   $this->_newobj();
00190   $this->_out('<</Type /Font');
00191   $this->_out('/Subtype /CIDFontType2');
00192   $this->_out('/BaseFont /'. $font['name']);
00193   $this->_out('/CIDSystemInfo <</Registry (Adobe) /Ordering (UCS) /Supplement 0>>');
00194   $this->_out('/FontDescriptor '. ($this->n + 1) .' 0 R');
00195   $c = 0;
00196   $widths = '';
00197   foreach ($font['cw'] as $i => $w) {
00198     $widths .= $i .' ['. $w.'] ';
00199   }
00200   $this->_out('/W ['. $widths .']');
00201   $this->_out('/CIDToGIDMap '. ($this->n + 2) .' 0 R');
00202   $this->_out('>>');
00203   $this->_out('endobj');
00204 
00205   //Font descriptor
00206   $this->_newobj();
00207   $this->_out('<</Type /FontDescriptor');
00208   $this->_out('/FontName /'.$font['name']);
00209   $s = '';
00210   foreach ($font['desc'] as $k => $v) {
00211     $s .= ' /'. $k .' '. $v;
00212   }
00213   if ($font['file']) {
00214                 $s .= ' /FontFile2 '. $this->FontFiles[$font['file']]['n'] .' 0 R';
00215   }
00216   $this->_out($s);
00217   $this->_out('>>');
00218   $this->_out('endobj');
00219 
00220   //Embed CIDToGIDMap
00221   $this->_newobj();
00222   if(defined('FPDF_FONTPATH'))
00223     $file=FPDF_FONTPATH.$font['ctg'];
00224   else
00225     $file=$font['ctg'];
00226   $size=filesize($file);
00227   if(!$size)
00228     $this->Error('Font file not found');
00229   $this->_out('<</Length '.$size);
00230         if(substr($file,-2) == '.z')
00231     $this->_out('/Filter /FlateDecode');
00232   $this->_out('>>');
00233   $f = fopen($file,'rb');
00234   $this->_putstream(fread($f,$size));
00235   fclose($f);
00236   $this->_out('endobj');
00237 }
00238 
00239 function _dounderline($x,$y,$width,$txt)
00240 {
00241   //Underline text
00242   $up=$this->CurrentFont['up'];
00243   $ut=$this->CurrentFont['ut'];
00244   $w=$width+$this->ws*substr_count($txt,' ');
00245   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);
00246 }
00247 
00248 function _textstring($s)
00249 {
00250   //Convert to UTF-16BE
00251   $s = $this->utf8_to_utf16be($s);
00252   //Escape necessary characters
00253   return '('. strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\')) .')';
00254 }
00255 
00256 function _strreplace($what, $to, $where) {
00257     $to = '' . $to;
00258     return str_replace($this->utf8_to_utf16be($what, false), $this->utf8_to_utf16be($to, false), $where);
00259 }
00260 
00261 function _escapetext($s)
00262 {
00263   //Convert to UTF-16BE
00264   $s = $this->utf8_to_utf16be($s, false);
00265   //Escape necessary characters
00266   return '('. strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\')) .')';
00267 }
00268 
00269 function _putinfo()
00270 {
00271         $this->_out('/Producer '.$this->_textstring('UFPDF '. UFPDF_VERSION));
00272         if(!empty($this->title))
00273                 $this->_out('/Title '.$this->_textstring($this->title));
00274         if(!empty($this->subject))
00275                 $this->_out('/Subject '.$this->_textstring($this->subject));
00276         if(!empty($this->author))
00277                 $this->_out('/Author '.$this->_textstring($this->author));
00278         if(!empty($this->keywords))
00279                 $this->_out('/Keywords '.$this->_textstring($this->keywords));
00280         if(!empty($this->creator))
00281                 $this->_out('/Creator '.$this->_textstring($this->creator));
00282         $this->_out('/CreationDate '.$this->_textstring('D:'.date('YmdHis')));
00283 }
00284 
00285 // UTF-8 to UTF-16BE conversion.
00286 // Correctly handles all illegal UTF-8 sequences.
00287 function utf8_to_utf16be(&$txt, $bom = true) {
00288   $l = strlen($txt);
00289   $out = $bom ? "\xFE\xFF" : '';
00290   for ($i = 0; $i < $l; ++$i) {
00291     $c = ord($txt{$i});
00292     // ASCII
00293     if ($c < 0x80) {
00294       $out .= "\x00". $txt{$i};
00295     }
00296     // Lost continuation byte
00297     else if ($c < 0xC0) {
00298       $out .= "\xFF\xFD";
00299       continue;
00300     }
00301     // Multibyte sequence leading byte
00302     else {
00303       if ($c < 0xE0) {
00304         $s = 2;
00305       }
00306       else if ($c < 0xF0) {
00307         $s = 3;
00308       }
00309       else if ($c < 0xF8) {
00310         $s = 4;
00311       }
00312       // 5/6 byte sequences not possible for Unicode.
00313       else {
00314         $out .= "\xFF\xFD";
00315         while (ord($txt{$i + 1}) >= 0x80 && ord($txt{$i + 1}) < 0xC0) { ++$i; }
00316         continue;
00317       }
00318 
00319       $q = array($c);
00320       // Fetch rest of sequence
00321       $l = strlen($txt);
00322       while ($i + 1 < $l && ord($txt{$i + 1}) >= 0x80 && ord($txt{$i + 1}) < 0xC0) { ++$i; $q[] = ord($txt{$i}); }
00323 
00324       // Check length
00325       if (count($q) != $s) {
00326         $out .= "\xFF\xFD";
00327         continue;
00328       }
00329 
00330       switch ($s) {
00331         case 2:
00332           $cp = (($q[0] ^ 0xC0) << 6) | ($q[1] ^ 0x80);
00333           // Overlong sequence
00334           if ($cp < 0x80) {
00335             $out .= "\xFF\xFD";
00336           }
00337           else {
00338             $out .= chr($cp >> 8);
00339             $out .= chr($cp & 0xFF);
00340           }
00341           continue;
00342 
00343         case 3:
00344           $cp = (($q[0] ^ 0xE0) << 12) | (($q[1] ^ 0x80) << 6) | ($q[2] ^ 0x80);
00345           // Overlong sequence
00346           if ($cp < 0x800) {
00347             $out .= "\xFF\xFD";
00348           }
00349           // Check for UTF-8 encoded surrogates (caused by a bad UTF-8 encoder)
00350           else if ($c > 0xD800 && $c < 0xDFFF) {
00351             $out .= "\xFF\xFD";
00352           }
00353           else {
00354             $out .= chr($cp >> 8);
00355             $out .= chr($cp & 0xFF);
00356           }
00357           continue;
00358 
00359         case 4:
00360           $cp = (($q[0] ^ 0xF0) << 18) | (($q[1] ^ 0x80) << 12) | (($q[2] ^ 0x80) << 6) | ($q[3] ^ 0x80);
00361           // Overlong sequence
00362           if ($cp < 0x10000) {
00363             $out .= "\xFF\xFD";
00364           }
00365           // Outside of the Unicode range
00366           else if ($cp >= 0x10FFFF) {
00367             $out .= "\xFF\xFD";
00368           }
00369           else {
00370             // Use surrogates
00371             $cp -= 0x10000;
00372             $s1 = 0xD800 | ($cp >> 10);
00373             $s2 = 0xDC00 | ($cp & 0x3FF);
00374 
00375             $out .= chr($s1 >> 8);
00376             $out .= chr($s1 & 0xFF);
00377             $out .= chr($s2 >> 8);
00378             $out .= chr($s2 & 0xFF);
00379           }
00380           continue;
00381       }
00382     }
00383   }
00384   return $out;
00385 }
00386 
00387 // UTF-8 to codepoint array conversion.
00388 // Correctly handles all illegal UTF-8 sequences.
00389 function utf8_to_codepoints(&$txt) {
00390   $l = strlen($txt);
00391   $out = array();
00392   for ($i = 0; $i < $l; ++$i) {
00393     $c = ord($txt{$i});
00394     // ASCII
00395     if ($c < 0x80) {
00396       $out[] = ord($txt{$i});
00397     }
00398     // Lost continuation byte
00399     else if ($c < 0xC0) {
00400       $out[] = 0xFFFD;
00401       continue;
00402     }
00403     // Multibyte sequence leading byte
00404     else {
00405       if ($c < 0xE0) {
00406         $s = 2;
00407       }
00408       else if ($c < 0xF0) {
00409         $s = 3;
00410       }
00411       else if ($c < 0xF8) {
00412         $s = 4;
00413       }
00414       // 5/6 byte sequences not possible for Unicode.
00415       else {
00416         $out[] = 0xFFFD;
00417         while (ord($txt{$i + 1}) >= 0x80 && ord($txt{$i + 1}) < 0xC0) { ++$i; }
00418         continue;
00419       }
00420 
00421       $q = array($c);
00422       // Fetch rest of sequence
00423       $l = strlen($txt);
00424       while ($i + 1 < $l && ord($txt{$i + 1}) >= 0x80 && ord($txt{$i + 1}) < 0xC0) { ++$i; $q[] = ord($txt{$i}); }
00425 
00426       // Check length
00427       if (count($q) != $s) {
00428         $out[] = 0xFFFD;
00429         continue;
00430       }
00431 
00432       switch ($s) {
00433         case 2:
00434           $cp = (($q[0] ^ 0xC0) << 6) | ($q[1] ^ 0x80);
00435           // Overlong sequence
00436           if ($cp < 0x80) {
00437             $out[] = 0xFFFD;
00438           }
00439           else {
00440             $out[] = $cp;
00441           }
00442           continue;
00443 
00444         case 3:
00445           $cp = (($q[0] ^ 0xE0) << 12) | (($q[1] ^ 0x80) << 6) | ($q[2] ^ 0x80);
00446           // Overlong sequence
00447           if ($cp < 0x800) {
00448             $out[] = 0xFFFD;
00449           }
00450           // Check for UTF-8 encoded surrogates (caused by a bad UTF-8 encoder)
00451           else if ($c > 0xD800 && $c < 0xDFFF) {
00452             $out[] = 0xFFFD;
00453           }
00454           else {
00455             $out[] = $cp;
00456           }
00457           continue;
00458 
00459         case 4:
00460           $cp = (($q[0] ^ 0xF0) << 18) | (($q[1] ^ 0x80) << 12) | (($q[2] ^ 0x80) << 6) | ($q[3] ^ 0x80);
00461           // Overlong sequence
00462           if ($cp < 0x10000) {
00463             $out[] = 0xFFFD;
00464           }
00465           // Outside of the Unicode range
00466           else if ($cp >= 0x10FFFF) {
00467             $out[] = 0xFFFD;
00468           }
00469           else {
00470             $out[] = $cp;
00471           }
00472           continue;
00473       }
00474     }
00475   }
00476   return $out;
00477 }
00478 
00479 //End of class
00480 }
00481 
00482 }
00483 ?>


Généré par Les experts TYPO3 avec  doxygen 1.4.6