Changeset 19716


Ignore:
Timestamp:
2010/12/11 12:15:20 (13 years ago)
Author:
Seasoft
Message:

#403(インクルードしているライブラリ群をバージョンアップする)

  • FPDF関連 (PHP4について、動作環境無く未確認)
Location:
branches/version-2_5-dev/data
Files:
7 added
2 deleted
1 edited
8 moved

Legend:

Unmodified
Added
Removed
  • branches/version-2_5-dev/data/class/SC_Fpdf.php

    r19680 r19716  
    2828 */ 
    2929 
    30 require(DATA_PATH . 'pdf/japanese.php'); 
     30require(DATA_PATH . 'module/fpdf/fpdf.php'); 
     31require(DATA_PATH . 'module/fpdf/japanese.php'); 
    3132define('PDF_TEMPLATE_DIR', DATA_PATH . 'pdf/'); 
    3233 
  • branches/version-2_5-dev/data/module/fpdf/fpdf.php

    r17259 r19716  
    11<?php 
    22/******************************************************************************* 
    3 * Software: FPDF                                                               * 
    4 * Version:  1.53                                                               * 
    5 * Date:     2004-12-31                                                         * 
    6 * Author:   Olivier PLATHEY                                                    * 
    7 * License:  Freeware                                                           * 
     3* FPDF                                                                         * 
    84*                                                                              * 
    9 * You may use, modify and redistribute this software as you wish.              * 
     5* Version: 1.6                                                                 * 
     6* Date:    2008-08-03                                                          * 
     7* Author:  Olivier PLATHEY                                                     * 
    108*******************************************************************************/ 
    119 
    12 if(!class_exists('FPDF')) 
    13 { 
    14 define('FPDF_VERSION','1.53'); 
     10define('FPDF_VERSION','1.6'); 
    1511 
    1612class FPDF 
    1713{ 
    18 //Private properties 
    1914var $page;               //current page number 
    2015var $n;                  //current object number 
     
    2419var $state;              //current document state 
    2520var $compress;           //compression flag 
     21var $k;                  //scale factor (number of points in user unit) 
    2622var $DefOrientation;     //default orientation 
    2723var $CurOrientation;     //current orientation 
    28 var $OrientationChanges; //array indicating orientation changes 
    29 var $k;                  //scale factor (number of points in user unit) 
    30 var $fwPt,$fhPt;         //dimensions of page format in points 
    31 var $fw,$fh;             //dimensions of page format in user unit 
    32 var $wPt,$hPt;           //current dimensions of page in points 
    33 var $w,$h;               //current dimensions of page in user unit 
     24var $PageFormats;        //available page formats 
     25var $DefPageFormat;      //default page format 
     26var $CurPageFormat;      //current page format 
     27var $PageSizes;          //array storing non-default page sizes 
     28var $wPt,$hPt;           //dimensions of current page in points 
     29var $w,$h;               //dimensions of current page in user unit 
    3430var $lMargin;            //left margin 
    3531var $tMargin;            //top margin 
     
    3733var $bMargin;            //page break margin 
    3834var $cMargin;            //cell margin 
    39 var $x,$y;               //current position in user unit for cell positioning 
    40 var $lasth;              //height of last cell printed 
     35var $x,$y;               //current position in user unit 
     36var $lasth;              //height of last printed cell 
    4137var $LineWidth;          //line width in user unit 
    4238var $CoreFonts;          //array of standard font names 
     
    4440var $FontFiles;          //array of font files 
    4541var $diffs;              //array of encoding differences 
    46 var $images;             //array of used images 
    47 var $PageLinks;          //array of links in pages 
    48 var $links;              //array of internal links 
    4942var $FontFamily;         //current font family 
    5043var $FontStyle;          //current font style 
     
    5851var $ColorFlag;          //indicates whether fill and text colors are different 
    5952var $ws;                 //word spacing 
     53var $images;             //array of used images 
     54var $PageLinks;          //array of links in pages 
     55var $links;              //array of internal links 
    6056var $AutoPageBreak;      //automatic page breaking 
    6157var $PageBreakTrigger;   //threshold used to trigger page breaks 
     58var $InHeader;           //flag set when processing header 
    6259var $InFooter;           //flag set when processing footer 
    6360var $ZoomMode;           //zoom display mode 
     
    7673*                                                                              * 
    7774*******************************************************************************/ 
    78 function FPDF($orientation='P',$unit='mm',$format='A4') 
     75function FPDF($orientation='P', $unit='mm', $format='A4') 
    7976{ 
    8077    //Some checks 
     
    8582    $this->buffer=''; 
    8683    $this->pages=array(); 
    87     $this->OrientationChanges=array(); 
     84    $this->PageSizes=array(); 
    8885    $this->state=0; 
    8986    $this->fonts=array(); 
     
    9289    $this->images=array(); 
    9390    $this->links=array(); 
     91    $this->InHeader=false; 
    9492    $this->InFooter=false; 
    9593    $this->lasth=0; 
     
    104102    $this->ws=0; 
    105103    //Standard fonts 
    106     $this->CoreFonts=array('courier'=>'Courier','courierB'=>'Courier-Bold','courierI'=>'Courier-Oblique','courierBI'=>'Courier-BoldOblique', 
    107         'helvetica'=>'Helvetica','helveticaB'=>'Helvetica-Bold','helveticaI'=>'Helvetica-Oblique','helveticaBI'=>'Helvetica-BoldOblique', 
    108         'times'=>'Times-Roman','timesB'=>'Times-Bold','timesI'=>'Times-Italic','timesBI'=>'Times-BoldItalic', 
    109         'symbol'=>'Symbol','zapfdingbats'=>'ZapfDingbats'); 
     104    $this->CoreFonts=array('courier'=>'Courier', 'courierB'=>'Courier-Bold', 'courierI'=>'Courier-Oblique', 'courierBI'=>'Courier-BoldOblique', 
     105        'helvetica'=>'Helvetica', 'helveticaB'=>'Helvetica-Bold', 'helveticaI'=>'Helvetica-Oblique', 'helveticaBI'=>'Helvetica-BoldOblique', 
     106        'times'=>'Times-Roman', 'timesB'=>'Times-Bold', 'timesI'=>'Times-Italic', 'timesBI'=>'Times-BoldItalic', 
     107        'symbol'=>'Symbol', 'zapfdingbats'=>'ZapfDingbats'); 
    110108    //Scale factor 
    111109    if($unit=='pt') 
     
    120118        $this->Error('Incorrect unit: '.$unit); 
    121119    //Page format 
     120    $this->PageFormats=array('a3'=>array(841.89,1190.55), 'a4'=>array(595.28,841.89), 'a5'=>array(420.94,595.28), 
     121        'letter'=>array(612,792), 'legal'=>array(612,1008)); 
    122122    if(is_string($format)) 
    123     { 
    124         $format=strtolower($format); 
    125         if($format=='a3') 
    126             $format=array(841.89,1190.55); 
    127         elseif($format=='a4') 
    128             $format=array(595.28,841.89); 
    129         elseif($format=='a5') 
    130             $format=array(420.94,595.28); 
    131         elseif($format=='letter') 
    132             $format=array(612,792); 
    133         elseif($format=='legal') 
    134             $format=array(612,1008); 
    135         else 
    136             $this->Error('Unknown page format: '.$format); 
    137         $this->fwPt=$format[0]; 
    138         $this->fhPt=$format[1]; 
    139     } 
    140     else 
    141     { 
    142         $this->fwPt=$format[0]*$this->k; 
    143         $this->fhPt=$format[1]*$this->k; 
    144     } 
    145     $this->fw=$this->fwPt/$this->k; 
    146     $this->fh=$this->fhPt/$this->k; 
     123        $format=$this->_getpageformat($format); 
     124    $this->DefPageFormat=$format; 
     125    $this->CurPageFormat=$format; 
    147126    //Page orientation 
    148127    $orientation=strtolower($orientation); 
     
    150129    { 
    151130        $this->DefOrientation='P'; 
    152         $this->wPt=$this->fwPt; 
    153         $this->hPt=$this->fhPt; 
     131        $this->w=$this->DefPageFormat[0]; 
     132        $this->h=$this->DefPageFormat[1]; 
    154133    } 
    155134    elseif($orientation=='l' || $orientation=='landscape') 
    156135    { 
    157136        $this->DefOrientation='L'; 
    158         $this->wPt=$this->fhPt; 
    159         $this->hPt=$this->fwPt; 
     137        $this->w=$this->DefPageFormat[1]; 
     138        $this->h=$this->DefPageFormat[0]; 
    160139    } 
    161140    else 
    162141        $this->Error('Incorrect orientation: '.$orientation); 
    163142    $this->CurOrientation=$this->DefOrientation; 
    164     $this->w=$this->wPt/$this->k; 
    165     $this->h=$this->hPt/$this->k; 
     143    $this->wPt=$this->w*$this->k; 
     144    $this->hPt=$this->h*$this->k; 
    166145    //Page margins (1 cm) 
    167146    $margin=28.35/$this->k; 
     
    181160} 
    182161 
    183 function SetMargins($left,$top,$right=-1) 
     162function SetMargins($left, $top, $right=null) 
    184163{ 
    185164    //Set left, top and right margins 
    186165    $this->lMargin=$left; 
    187166    $this->tMargin=$top; 
    188     if($right==-1) 
     167    if($right===null) 
    189168        $right=$left; 
    190169    $this->rMargin=$right; 
     
    211190} 
    212191 
    213 function SetAutoPageBreak($auto,$margin=0) 
     192function SetAutoPageBreak($auto, $margin=0) 
    214193{ 
    215194    //Set auto page break mode and triggering margin 
     
    219198} 
    220199 
    221 function SetDisplayMode($zoom,$layout='continuous') 
     200function SetDisplayMode($zoom, $layout='continuous') 
    222201{ 
    223202    //Set display mode in viewer 
     
    241220} 
    242221 
    243 function SetTitle($title) 
     222function SetTitle($title, $isUTF8=false) 
    244223{ 
    245224    //Title of document 
     225    if($isUTF8) 
     226        $title=$this->_UTF8toUTF16($title); 
    246227    $this->title=$title; 
    247228} 
    248229 
    249 function SetSubject($subject) 
     230function SetSubject($subject, $isUTF8=false) 
    250231{ 
    251232    //Subject of document 
     233    if($isUTF8) 
     234        $subject=$this->_UTF8toUTF16($subject); 
    252235    $this->subject=$subject; 
    253236} 
    254237 
    255 function SetAuthor($author) 
     238function SetAuthor($author, $isUTF8=false) 
    256239{ 
    257240    //Author of document 
     241    if($isUTF8) 
     242        $author=$this->_UTF8toUTF16($author); 
    258243    $this->author=$author; 
    259244} 
    260245 
    261 function SetKeywords($keywords) 
     246function SetKeywords($keywords, $isUTF8=false) 
    262247{ 
    263248    //Keywords of document 
     249    if($isUTF8) 
     250        $keywords=$this->_UTF8toUTF16($keywords); 
    264251    $this->keywords=$keywords; 
    265252} 
    266253 
    267 function SetCreator($creator) 
     254function SetCreator($creator, $isUTF8=false) 
    268255{ 
    269256    //Creator of document 
     257    if($isUTF8) 
     258        $creator=$this->_UTF8toUTF16($creator); 
    270259    $this->creator=$creator; 
    271260} 
     
    280269{ 
    281270    //Fatal error 
    282     die('<B>FPDF error: </B>'.$msg); 
     271    die('<b>FPDF error:</b> '.$msg); 
    283272} 
    284273 
     
    306295} 
    307296 
    308 function AddPage($orientation='') 
     297function AddPage($orientation='', $format='') 
    309298{ 
    310299    //Start a new page 
     
    329318    } 
    330319    //Start new page 
    331     $this->_beginpage($orientation); 
     320    $this->_beginpage($orientation,$format); 
    332321    //Set line cap style to square 
    333322    $this->_out('2 J'); 
    334323    //Set line width 
    335324    $this->LineWidth=$lw; 
    336     $this->_out(sprintf('%.2f w',$lw*$this->k)); 
     325    $this->_out(sprintf('%.2F w',$lw*$this->k)); 
    337326    //Set font 
    338327    if($family) 
     
    348337    $this->ColorFlag=$cf; 
    349338    //Page header 
     339    $this->InHeader=true; 
    350340    $this->Header(); 
     341    $this->InHeader=false; 
    351342    //Restore line width 
    352343    if($this->LineWidth!=$lw) 
    353344    { 
    354345        $this->LineWidth=$lw; 
    355         $this->_out(sprintf('%.2f w',$lw*$this->k)); 
     346        $this->_out(sprintf('%.2F w',$lw*$this->k)); 
    356347    } 
    357348    //Restore font 
     
    389380} 
    390381 
    391 function SetDrawColor($r,$g=-1,$b=-1) 
     382function SetDrawColor($r, $g=null, $b=null) 
    392383{ 
    393384    //Set color for all stroking operations 
    394     if(($r==0 && $g==0 && $b==0) || $g==-1) 
    395         $this->DrawColor=sprintf('%.3f G',$r/255); 
    396     else 
    397         $this->DrawColor=sprintf('%.3f %.3f %.3f RG',$r/255,$g/255,$b/255); 
     385    if(($r==0 && $g==0 && $b==0) || $g===null) 
     386        $this->DrawColor=sprintf('%.3F G',$r/255); 
     387    else 
     388        $this->DrawColor=sprintf('%.3F %.3F %.3F RG',$r/255,$g/255,$b/255); 
    398389    if($this->page>0) 
    399390        $this->_out($this->DrawColor); 
    400391} 
    401392 
    402 function SetFillColor($r,$g=-1,$b=-1) 
     393function SetFillColor($r, $g=null, $b=null) 
    403394{ 
    404395    //Set color for all filling operations 
    405     if(($r==0 && $g==0 && $b==0) || $g==-1) 
    406         $this->FillColor=sprintf('%.3f g',$r/255); 
    407     else 
    408         $this->FillColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255); 
     396    if(($r==0 && $g==0 && $b==0) || $g===null) 
     397        $this->FillColor=sprintf('%.3F g',$r/255); 
     398    else 
     399        $this->FillColor=sprintf('%.3F %.3F %.3F rg',$r/255,$g/255,$b/255); 
    409400    $this->ColorFlag=($this->FillColor!=$this->TextColor); 
    410401    if($this->page>0) 
     
    412403} 
    413404 
    414 function SetTextColor($r,$g=-1,$b=-1) 
     405function SetTextColor($r, $g=null, $b=null) 
    415406{ 
    416407    //Set color for text 
    417     if(($r==0 && $g==0 && $b==0) || $g==-1) 
    418         $this->TextColor=sprintf('%.3f g',$r/255); 
    419     else 
    420         $this->TextColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255); 
     408    if(($r==0 && $g==0 && $b==0) || $g===null) 
     409        $this->TextColor=sprintf('%.3F g',$r/255); 
     410    else 
     411        $this->TextColor=sprintf('%.3F %.3F %.3F rg',$r/255,$g/255,$b/255); 
    421412    $this->ColorFlag=($this->FillColor!=$this->TextColor); 
    422413} 
     
    430421    $l=strlen($s); 
    431422    for($i=0;$i<$l;$i++) 
    432         $w+=$cw[$s{$i}]; 
     423        $w+=$cw[$s[$i]]; 
    433424    return $w*$this->FontSize/1000; 
    434425} 
     
    439430    $this->LineWidth=$width; 
    440431    if($this->page>0) 
    441         $this->_out(sprintf('%.2f w',$width*$this->k)); 
    442 } 
    443  
    444 function Line($x1,$y1,$x2,$y2) 
     432        $this->_out(sprintf('%.2F w',$width*$this->k)); 
     433} 
     434 
     435function Line($x1, $y1, $x2, $y2) 
    445436{ 
    446437    //Draw a line 
    447     $this->_out(sprintf('%.2f %.2f m %.2f %.2f l S',$x1*$this->k,($this->h-$y1)*$this->k,$x2*$this->k,($this->h-$y2)*$this->k)); 
    448 } 
    449  
    450 function Rect($x,$y,$w,$h,$style='') 
     438    $this->_out(sprintf('%.2F %.2F m %.2F %.2F l S',$x1*$this->k,($this->h-$y1)*$this->k,$x2*$this->k,($this->h-$y2)*$this->k)); 
     439} 
     440 
     441function Rect($x, $y, $w, $h, $style='') 
    451442{ 
    452443    //Draw a rectangle 
     
    457448    else 
    458449        $op='S'; 
    459     $this->_out(sprintf('%.2f %.2f %.2f %.2f re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op)); 
    460 } 
    461  
    462 function AddFont($family,$style='',$file='') 
     450    $this->_out(sprintf('%.2F %.2F %.2F %.2F re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op)); 
     451} 
     452 
     453function AddFont($family, $style='', $file='') 
    463454{ 
    464455    //Add a TrueType or Type1 font 
     
    473464    $fontkey=$family.$style; 
    474465    if(isset($this->fonts[$fontkey])) 
    475         $this->Error('Font already added: '.$family.' '.$style); 
     466        return; 
    476467    include($this->_getfontpath().$file); 
    477468    if(!isset($name)) 
    478469        $this->Error('Could not include font definition file'); 
    479470    $i=count($this->fonts)+1; 
    480     $this->fonts[$fontkey]=array('i'=>$i,'type'=>$type,'name'=>$name,'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw,'enc'=>$enc,'file'=>$file); 
     471    $this->fonts[$fontkey]=array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'up'=>$up, 'ut'=>$ut, 'cw'=>$cw, 'enc'=>$enc, 'file'=>$file); 
    481472    if($diff) 
    482473    { 
     
    504495            $this->FontFiles[$file]=array('length1'=>$originalsize); 
    505496        else 
    506             $this->FontFiles[$file]=array('length1'=>$size1,'length2'=>$size2); 
    507     } 
    508 } 
    509  
    510 function SetFont($family,$style='',$size=0) 
     497            $this->FontFiles[$file]=array('length1'=>$size1, 'length2'=>$size2); 
     498    } 
     499} 
     500 
     501function SetFont($family, $style='', $size=0) 
    511502{ 
    512503    //Select a font; size given in points 
     
    553544            } 
    554545            $i=count($this->fonts)+1; 
    555             $this->fonts[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts[$fontkey],'up'=>-100,'ut'=>50,'cw'=>$fpdf_charwidths[$fontkey]); 
     546            $name=$this->CoreFonts[$fontkey]; 
     547            $cw=$fpdf_charwidths[$fontkey]; 
     548            $this->fonts[$fontkey]=array('i'=>$i, 'type'=>'core', 'name'=>$name, 'up'=>-100, 'ut'=>50, 'cw'=>$cw); 
    556549        } 
    557550        else 
     
    565558    $this->CurrentFont=&$this->fonts[$fontkey]; 
    566559    if($this->page>0) 
    567         $this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt)); 
     560        $this->_out(sprintf('BT /F%d %.2F Tf ET',$this->CurrentFont['i'],$this->FontSizePt)); 
    568561} 
    569562 
     
    576569    $this->FontSize=$size/$this->k; 
    577570    if($this->page>0) 
    578         $this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt)); 
     571        $this->_out(sprintf('BT /F%d %.2F Tf ET',$this->CurrentFont['i'],$this->FontSizePt)); 
    579572} 
    580573 
     
    583576    //Create a new internal link 
    584577    $n=count($this->links)+1; 
    585     $this->links[$n]=array(0,0); 
     578    $this->links[$n]=array(0, 0); 
    586579    return $n; 
    587580} 
    588581 
    589 function SetLink($link,$y=0,$page=-1) 
     582function SetLink($link, $y=0, $page=-1) 
    590583{ 
    591584    //Set destination of internal link 
     
    594587    if($page==-1) 
    595588        $page=$this->page; 
    596     $this->links[$link]=array($page,$y); 
    597 } 
    598  
    599 function Link($x,$y,$w,$h,$link) 
     589    $this->links[$link]=array($page, $y); 
     590} 
     591 
     592function Link($x, $y, $w, $h, $link) 
    600593{ 
    601594    //Put a link on the page 
    602     $this->PageLinks[$this->page][]=array($x*$this->k,$this->hPt-$y*$this->k,$w*$this->k,$h*$this->k,$link); 
    603 } 
    604  
    605 function Text($x,$y,$txt) 
     595    $this->PageLinks[$this->page][]=array($x*$this->k, $this->hPt-$y*$this->k, $w*$this->k, $h*$this->k, $link); 
     596} 
     597 
     598function Text($x, $y, $txt) 
    606599{ 
    607600    //Output a string 
    608     $s=sprintf('BT %.2f %.2f Td (%s) Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escape($txt)); 
     601    $s=sprintf('BT %.2F %.2F Td (%s) Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escape($txt)); 
    609602    if($this->underline && $txt!='') 
    610603        $s.=' '.$this->_dounderline($x,$y,$txt); 
     
    620613} 
    621614 
    622 function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='') 
     615function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='') 
    623616{ 
    624617    //Output a cell 
    625618    $k=$this->k; 
    626     if($this->y+$h>$this->PageBreakTrigger && !$this->InFooter && $this->AcceptPageBreak()) 
     619    if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak()) 
    627620    { 
    628621        //Automatic page break 
     
    634627            $this->_out('0 Tw'); 
    635628        } 
    636         $this->AddPage($this->CurOrientation); 
     629        $this->AddPage($this->CurOrientation,$this->CurPageFormat); 
    637630        $this->x=$x; 
    638631        if($ws>0) 
    639632        { 
    640633            $this->ws=$ws; 
    641             $this->_out(sprintf('%.3f Tw',$ws*$k)); 
     634            $this->_out(sprintf('%.3F Tw',$ws*$k)); 
    642635        } 
    643636    } 
     
    645638        $w=$this->w-$this->rMargin-$this->x; 
    646639    $s=''; 
    647     if($fill==1 || $border==1) 
    648     { 
    649         if($fill==1) 
     640    if($fill || $border==1) 
     641    { 
     642        if($fill) 
    650643            $op=($border==1) ? 'B' : 'f'; 
    651644        else 
    652645            $op='S'; 
    653         $s=sprintf('%.2f %.2f %.2f %.2f re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op); 
     646        $s=sprintf('%.2F %.2F %.2F %.2F re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op); 
    654647    } 
    655648    if(is_string($border)) 
     
    658651        $y=$this->y; 
    659652        if(strpos($border,'L')!==false) 
    660             $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k); 
     653            $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k); 
    661654        if(strpos($border,'T')!==false) 
    662             $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k); 
     655            $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k); 
    663656        if(strpos($border,'R')!==false) 
    664             $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k); 
     657            $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k); 
    665658        if(strpos($border,'B')!==false) 
    666             $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k); 
     659            $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k); 
    667660    } 
    668661    if($txt!=='') 
     
    677670            $s.='q '.$this->TextColor.' '; 
    678671        $txt2=str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt))); 
    679         $s.=sprintf('BT %.2f %.2f Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt2); 
     672        $s.=sprintf('BT %.2F %.2F Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt2); 
    680673        if($this->underline) 
    681674            $s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt); 
     
    699692} 
    700693 
    701 function MultiCell($w,$h,$txt,$border=0,$align='J',$fill=0, $ln = 2) 
     694function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false) 
    702695{ 
    703696    //Output text with automatic or explicit line breaks 
     
    735728    $ns=0; 
    736729    $nl=1; 
    737     $this->rise_h = 0; //‚‚³ŒvŽZ—p 
    738      
    739730    while($i<$nb) 
    740731    { 
    741732        //Get next character 
    742         $c=$s{$i}; 
     733        $c=$s[$i]; 
    743734        if($c=="\n") 
    744735        { 
     
    756747            $ns=0; 
    757748            $nl++; 
    758             $this->rise_h += $h; //‚‚³ŒvŽZ—p 
    759              
    760749            if($border && $nl==2) 
    761750                $b=$b2; 
     
    788777                { 
    789778                    $this->ws=($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0; 
    790                     $this->_out(sprintf('%.3f Tw',$this->ws*$this->k)); 
     779                    $this->_out(sprintf('%.3F Tw',$this->ws*$this->k)); 
    791780                } 
    792781                $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill); 
    793782                $i=$sep+1; 
    794783            } 
    795             $this->rise_h += $h; //‚‚³ŒvŽZ—p 
    796784            $sep=-1; 
    797785            $j=$i; 
     
    813801    if($border && strpos($border,'B')!==false) 
    814802        $b.='B'; 
    815     $this->Cell($w,$h,substr($s,$j,$i-$j),$b,$ln,$align,$fill); 
    816     $this->rise_h += $h; //‘‰Á•ª‚̍‚‚³‚ðŒvŽZ 
    817     //‰üs‚È‚µÝ’è‚©‚A‚‚³‚ª‹K’è‚̍‚‚³ˆÈã‚Å‚ ‚ê‚ÎYŽ²‚ðÝ’肵‚È‚¨‚·B 
    818     if($ln == 0 and $h < $this->rise_h) { 
    819       $this->y = $this->y - $this->rise_h + $h; 
    820     } 
    821      
    822     //$this->x=$this->lMargin; 
    823 } 
    824  
    825 function Write($h,$txt,$link='') 
     803    $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill); 
     804    $this->x=$this->lMargin; 
     805} 
     806 
     807function Write($h, $txt, $link='') 
    826808{ 
    827809    //Output text in flowing mode 
     
    839821    { 
    840822        //Get next character 
    841         $c=$s{$i}; 
     823        $c=$s[$i]; 
    842824        if($c=="\n") 
    843825        { 
     
    904886} 
    905887 
    906 function Image($file,$x,$y,$w=0,$h=0,$type='',$link='') 
     888function Ln($h=null) 
     889{ 
     890    //Line feed; default value is last cell height 
     891    $this->x=$this->lMargin; 
     892    if($h===null) 
     893        $this->y+=$this->lasth; 
     894    else 
     895        $this->y+=$h; 
     896} 
     897 
     898function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='') 
    907899{ 
    908900    //Put an image on the page 
    909901    if(!isset($this->images[$file])) 
    910902    { 
    911         //First use of image, get info 
     903        //First use of this image, get info 
    912904        if($type=='') 
    913905        { 
     
    918910        } 
    919911        $type=strtolower($type); 
    920         $mqr=get_magic_quotes_runtime(); 
    921         set_magic_quotes_runtime(0); 
    922         if($type=='jpg' || $type=='jpeg') 
    923             $info=$this->_parsejpg($file); 
    924         elseif($type=='png') 
    925             $info=$this->_parsepng($file); 
    926         else 
    927         { 
    928             //Allow for additional formats 
    929             $mtd='_parse'.$type; 
    930             if(!method_exists($this,$mtd)) 
    931                 $this->Error('Unsupported image type: '.$type); 
    932             $info=$this->$mtd($file); 
    933         } 
    934         set_magic_quotes_runtime($mqr); 
     912        if($type=='jpeg') 
     913            $type='jpg'; 
     914        $mtd='_parse'.$type; 
     915        if(!method_exists($this,$mtd)) 
     916            $this->Error('Unsupported image type: '.$type); 
     917        $info=$this->$mtd($file); 
    935918        $info['i']=count($this->images)+1; 
    936919        $this->images[$file]=$info; 
     
    945928        $h=$info['h']/$this->k; 
    946929    } 
    947     if($w==0) 
     930    elseif($w==0) 
    948931        $w=$h*$info['w']/$info['h']; 
    949     if($h==0) 
     932    elseif($h==0) 
    950933        $h=$w*$info['h']/$info['w']; 
    951     $this->_out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q',$w*$this->k,$h*$this->k,$x*$this->k,($this->h-($y+$h))*$this->k,$info['i'])); 
     934    //Flowing mode 
     935    if($y===null) 
     936    { 
     937        if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak()) 
     938        { 
     939            //Automatic page break 
     940            $x2=$this->x; 
     941            $this->AddPage($this->CurOrientation,$this->CurPageFormat); 
     942            $this->x=$x2; 
     943        } 
     944        $y=$this->y; 
     945        $this->y+=$h; 
     946    } 
     947    if($x===null) 
     948        $x=$this->x; 
     949    $this->_out(sprintf('q %.2F 0 0 %.2F %.2F %.2F cm /I%d Do Q',$w*$this->k,$h*$this->k,$x*$this->k,($this->h-($y+$h))*$this->k,$info['i'])); 
    952950    if($link) 
    953951        $this->Link($x,$y,$w,$h,$link); 
    954 } 
    955  
    956 function Ln($h='') 
    957 { 
    958     //Line feed; default value is last cell height 
    959     $this->x=$this->lMargin; 
    960     if(is_string($h)) 
    961         $this->y+=$this->lasth; 
    962     else 
    963         $this->y+=$h; 
    964952} 
    965953 
     
    995983} 
    996984 
    997 function SetXY($x,$y) 
     985function SetXY($x, $y) 
    998986{ 
    999987    //Set x and y positions 
     
    1002990} 
    1003991 
    1004 function Output($name='',$dest='') 
     992function Output($name='', $dest='') 
    1005993{ 
    1006994    //Output PDF to some destination 
    1007     //Finish document if necessary 
    1008995    if($this->state<3) 
    1009996        $this->Close(); 
    1010     //Normalize parameters 
    1011     if(is_bool($dest)) 
    1012         $dest=$dest ? 'D' : 'F'; 
    1013997    $dest=strtoupper($dest); 
    1014998    if($dest=='') 
     
    10261010        case 'I': 
    10271011            //Send to standard output 
    1028             if(ob_get_contents()) 
     1012            if(ob_get_length()) 
    10291013                $this->Error('Some data has already been output, can\'t send PDF file'); 
    10301014            if(php_sapi_name()!='cli') 
    10311015            { 
    10321016                //We send to a browser 
    1033                 if(isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) { header('Pragma:'); } 
    10341017                header('Content-Type: application/pdf'); 
    10351018                if(headers_sent()) 
    1036                     $this->Error('Some data has already been output to browser, can\'t send PDF file'); 
     1019                    $this->Error('Some data has already been output, can\'t send PDF file'); 
    10371020                header('Content-Length: '.strlen($this->buffer)); 
    1038                 header('Content-disposition: inline; filename="'.$name.'"'); 
     1021                header('Content-Disposition: inline; filename="'.$name.'"'); 
     1022                header('Cache-Control: private, max-age=0, must-revalidate'); 
     1023                header('Pragma: public'); 
     1024                ini_set('zlib.output_compression','0'); 
    10391025            } 
    10401026            echo $this->buffer; 
     
    10421028        case 'D': 
    10431029            //Download file 
    1044             if(ob_get_contents()) 
     1030            if(ob_get_length()) 
    10451031                $this->Error('Some data has already been output, can\'t send PDF file'); 
    1046             if(isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) { 
    1047                 header('Pragma:'); 
    1048                 header('Content-Type: application/force-download'); 
    1049             } 
    1050             else 
    1051                 header('Content-Type: application/octet-stream'); 
     1032            header('Content-Type: application/x-download'); 
    10521033            if(headers_sent()) 
    1053                 $this->Error('Some data has already been output to browser, can\'t send PDF file'); 
     1034                $this->Error('Some data has already been output, can\'t send PDF file'); 
    10541035            header('Content-Length: '.strlen($this->buffer)); 
    1055             header('Content-disposition: attachment; filename="'.$name.'"'); 
     1036            header('Content-Disposition: attachment; filename="'.$name.'"'); 
     1037            header('Cache-Control: private, max-age=0, must-revalidate'); 
     1038            header('Pragma: public'); 
     1039            ini_set('zlib.output_compression','0'); 
    10561040            echo $this->buffer; 
    10571041            break; 
     
    10801064function _dochecks() 
    10811065{ 
    1082     //Check for locale-related bug 
    1083     if(1.1==1) 
    1084         $this->Error('Don\'t alter the locale before including class file'); 
    1085     //Check for decimal separator 
    1086     if(sprintf('%.1f',1.0)!='1.0') 
    1087         setlocale(LC_NUMERIC,'C'); 
     1066    //Check availability of %F 
     1067    if(sprintf('%.1F',1.0)!='1.0') 
     1068        $this->Error('This version of PHP is not supported'); 
     1069    //Check mbstring overloading 
     1070    if(ini_get('mbstring.func_overload') & 2) 
     1071        $this->Error('mbstring overloading must be disabled'); 
     1072    //Disable runtime magic quotes 
     1073    if(get_magic_quotes_runtime()) 
     1074        @set_magic_quotes_runtime(0); 
     1075} 
     1076 
     1077function _getpageformat($format) 
     1078{ 
     1079    $format=strtolower($format); 
     1080    if(!isset($this->PageFormats[$format])) 
     1081        $this->Error('Unknown page format: '.$format); 
     1082    $a=$this->PageFormats[$format]; 
     1083    return array($a[0]/$this->k, $a[1]/$this->k); 
    10881084} 
    10891085 
     
    10951091} 
    10961092 
     1093function _beginpage($orientation, $format) 
     1094{ 
     1095    $this->page++; 
     1096    $this->pages[$this->page]=''; 
     1097    $this->state=2; 
     1098    $this->x=$this->lMargin; 
     1099    $this->y=$this->tMargin; 
     1100    $this->FontFamily=''; 
     1101    //Check page size 
     1102    if($orientation=='') 
     1103        $orientation=$this->DefOrientation; 
     1104    else 
     1105        $orientation=strtoupper($orientation[0]); 
     1106    if($format=='') 
     1107        $format=$this->DefPageFormat; 
     1108    else 
     1109    { 
     1110        if(is_string($format)) 
     1111            $format=$this->_getpageformat($format); 
     1112    } 
     1113    if($orientation!=$this->CurOrientation || $format[0]!=$this->CurPageFormat[0] || $format[1]!=$this->CurPageFormat[1]) 
     1114    { 
     1115        //New size 
     1116        if($orientation=='P') 
     1117        { 
     1118            $this->w=$format[0]; 
     1119            $this->h=$format[1]; 
     1120        } 
     1121        else 
     1122        { 
     1123            $this->w=$format[1]; 
     1124            $this->h=$format[0]; 
     1125        } 
     1126        $this->wPt=$this->w*$this->k; 
     1127        $this->hPt=$this->h*$this->k; 
     1128        $this->PageBreakTrigger=$this->h-$this->bMargin; 
     1129        $this->CurOrientation=$orientation; 
     1130        $this->CurPageFormat=$format; 
     1131    } 
     1132    if($orientation!=$this->DefOrientation || $format[0]!=$this->DefPageFormat[0] || $format[1]!=$this->DefPageFormat[1]) 
     1133        $this->PageSizes[$this->page]=array($this->wPt, $this->hPt); 
     1134} 
     1135 
     1136function _endpage() 
     1137{ 
     1138    $this->state=1; 
     1139} 
     1140 
     1141function _escape($s) 
     1142{ 
     1143    //Escape special characters in strings 
     1144    $s=str_replace('\\','\\\\',$s); 
     1145    $s=str_replace('(','\\(',$s); 
     1146    $s=str_replace(')','\\)',$s); 
     1147    $s=str_replace("\r",'\\r',$s); 
     1148    return $s; 
     1149} 
     1150 
     1151function _textstring($s) 
     1152{ 
     1153    //Format a text string 
     1154    return '('.$this->_escape($s).')'; 
     1155} 
     1156 
     1157function _UTF8toUTF16($s) 
     1158{ 
     1159    //Convert UTF-8 to UTF-16BE with BOM 
     1160    $res="\xFE\xFF"; 
     1161    $nb=strlen($s); 
     1162    $i=0; 
     1163    while($i<$nb) 
     1164    { 
     1165        $c1=ord($s[$i++]); 
     1166        if($c1>=224) 
     1167        { 
     1168            //3-byte character 
     1169            $c2=ord($s[$i++]); 
     1170            $c3=ord($s[$i++]); 
     1171            $res.=chr((($c1 & 0x0F)<<4) + (($c2 & 0x3C)>>2)); 
     1172            $res.=chr((($c2 & 0x03)<<6) + ($c3 & 0x3F)); 
     1173        } 
     1174        elseif($c1>=192) 
     1175        { 
     1176            //2-byte character 
     1177            $c2=ord($s[$i++]); 
     1178            $res.=chr(($c1 & 0x1C)>>2); 
     1179            $res.=chr((($c1 & 0x03)<<6) + ($c2 & 0x3F)); 
     1180        } 
     1181        else 
     1182        { 
     1183            //Single-byte character 
     1184            $res.="\0".chr($c1); 
     1185        } 
     1186    } 
     1187    return $res; 
     1188} 
     1189 
     1190function _dounderline($x, $y, $txt) 
     1191{ 
     1192    //Underline text 
     1193    $up=$this->CurrentFont['up']; 
     1194    $ut=$this->CurrentFont['ut']; 
     1195    $w=$this->GetStringWidth($txt)+$this->ws*substr_count($txt,' '); 
     1196    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); 
     1197} 
     1198 
     1199function _parsejpg($file) 
     1200{ 
     1201    //Extract info from a JPEG file 
     1202    $a=GetImageSize($file); 
     1203    if(!$a) 
     1204        $this->Error('Missing or incorrect image file: '.$file); 
     1205    if($a[2]!=2) 
     1206        $this->Error('Not a JPEG file: '.$file); 
     1207    if(!isset($a['channels']) || $a['channels']==3) 
     1208        $colspace='DeviceRGB'; 
     1209    elseif($a['channels']==4) 
     1210        $colspace='DeviceCMYK'; 
     1211    else 
     1212        $colspace='DeviceGray'; 
     1213    $bpc=isset($a['bits']) ? $a['bits'] : 8; 
     1214    //Read whole file 
     1215    $f=fopen($file,'rb'); 
     1216    $data=''; 
     1217    while(!feof($f)) 
     1218        $data.=fread($f,8192); 
     1219    fclose($f); 
     1220    return array('w'=>$a[0], 'h'=>$a[1], 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'DCTDecode', 'data'=>$data); 
     1221} 
     1222 
     1223function _parsepng($file) 
     1224{ 
     1225    //Extract info from a PNG file 
     1226    $f=fopen($file,'rb'); 
     1227    if(!$f) 
     1228        $this->Error('Can\'t open image file: '.$file); 
     1229    //Check signature 
     1230    if($this->_readstream($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) 
     1231        $this->Error('Not a PNG file: '.$file); 
     1232    //Read header chunk 
     1233    $this->_readstream($f,4); 
     1234    if($this->_readstream($f,4)!='IHDR') 
     1235        $this->Error('Incorrect PNG file: '.$file); 
     1236    $w=$this->_readint($f); 
     1237    $h=$this->_readint($f); 
     1238    $bpc=ord($this->_readstream($f,1)); 
     1239    if($bpc>8) 
     1240        $this->Error('16-bit depth not supported: '.$file); 
     1241    $ct=ord($this->_readstream($f,1)); 
     1242    if($ct==0) 
     1243        $colspace='DeviceGray'; 
     1244    elseif($ct==2) 
     1245        $colspace='DeviceRGB'; 
     1246    elseif($ct==3) 
     1247        $colspace='Indexed'; 
     1248    else 
     1249        $this->Error('Alpha channel not supported: '.$file); 
     1250    if(ord($this->_readstream($f,1))!=0) 
     1251        $this->Error('Unknown compression method: '.$file); 
     1252    if(ord($this->_readstream($f,1))!=0) 
     1253        $this->Error('Unknown filter method: '.$file); 
     1254    if(ord($this->_readstream($f,1))!=0) 
     1255        $this->Error('Interlacing not supported: '.$file); 
     1256    $this->_readstream($f,4); 
     1257    $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>'; 
     1258    //Scan chunks looking for palette, transparency and image data 
     1259    $pal=''; 
     1260    $trns=''; 
     1261    $data=''; 
     1262    do 
     1263    { 
     1264        $n=$this->_readint($f); 
     1265        $type=$this->_readstream($f,4); 
     1266        if($type=='PLTE') 
     1267        { 
     1268            //Read palette 
     1269            $pal=$this->_readstream($f,$n); 
     1270            $this->_readstream($f,4); 
     1271        } 
     1272        elseif($type=='tRNS') 
     1273        { 
     1274            //Read transparency info 
     1275            $t=$this->_readstream($f,$n); 
     1276            if($ct==0) 
     1277                $trns=array(ord(substr($t,1,1))); 
     1278            elseif($ct==2) 
     1279                $trns=array(ord(substr($t,1,1)), ord(substr($t,3,1)), ord(substr($t,5,1))); 
     1280            else 
     1281            { 
     1282                $pos=strpos($t,chr(0)); 
     1283                if($pos!==false) 
     1284                    $trns=array($pos); 
     1285            } 
     1286            $this->_readstream($f,4); 
     1287        } 
     1288        elseif($type=='IDAT') 
     1289        { 
     1290            //Read image data block 
     1291            $data.=$this->_readstream($f,$n); 
     1292            $this->_readstream($f,4); 
     1293        } 
     1294        elseif($type=='IEND') 
     1295            break; 
     1296        else 
     1297            $this->_readstream($f,$n+4); 
     1298    } 
     1299    while($n); 
     1300    if($colspace=='Indexed' && empty($pal)) 
     1301        $this->Error('Missing palette in '.$file); 
     1302    fclose($f); 
     1303    return array('w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'FlateDecode', 'parms'=>$parms, 'pal'=>$pal, 'trns'=>$trns, 'data'=>$data); 
     1304} 
     1305 
     1306function _readstream($f, $n) 
     1307{ 
     1308    //Read n bytes from stream 
     1309    $res=''; 
     1310    while($n>0 && !feof($f)) 
     1311    { 
     1312        $s=fread($f,$n); 
     1313        if($s===false) 
     1314            $this->Error('Error while reading stream'); 
     1315        $n-=strlen($s); 
     1316        $res.=$s; 
     1317    } 
     1318    if($n>0) 
     1319        $this->Error('Unexpected end of stream'); 
     1320    return $res; 
     1321} 
     1322 
     1323function _readint($f) 
     1324{ 
     1325    //Read a 4-byte integer from stream 
     1326    $a=unpack('Ni',$this->_readstream($f,4)); 
     1327    return $a['i']; 
     1328} 
     1329 
     1330function _parsegif($file) 
     1331{ 
     1332    //Extract info from a GIF file (via PNG conversion) 
     1333    if(!function_exists('imagepng')) 
     1334        $this->Error('GD extension is required for GIF support'); 
     1335    if(!function_exists('imagecreatefromgif')) 
     1336        $this->Error('GD has no GIF read support'); 
     1337    $im=imagecreatefromgif($file); 
     1338    if(!$im) 
     1339        $this->Error('Missing or incorrect image file: '.$file); 
     1340    imageinterlace($im,0); 
     1341    $tmp=tempnam('.','gif'); 
     1342    if(!$tmp) 
     1343        $this->Error('Unable to create a temporary file'); 
     1344    if(!imagepng($im,$tmp)) 
     1345        $this->Error('Error while saving to temporary file'); 
     1346    imagedestroy($im); 
     1347    $info=$this->_parsepng($tmp); 
     1348    unlink($tmp); 
     1349    return $info; 
     1350} 
     1351 
     1352function _newobj() 
     1353{ 
     1354    //Begin a new object 
     1355    $this->n++; 
     1356    $this->offsets[$this->n]=strlen($this->buffer); 
     1357    $this->_out($this->n.' 0 obj'); 
     1358} 
     1359 
     1360function _putstream($s) 
     1361{ 
     1362    $this->_out('stream'); 
     1363    $this->_out($s); 
     1364    $this->_out('endstream'); 
     1365} 
     1366 
     1367function _out($s) 
     1368{ 
     1369    //Add a line to the document 
     1370    if($this->state==2) 
     1371        $this->pages[$this->page].=$s."\n"; 
     1372    else 
     1373        $this->buffer.=$s."\n"; 
     1374} 
     1375 
    10971376function _putpages() 
    10981377{ 
     
    11061385    if($this->DefOrientation=='P') 
    11071386    { 
    1108         $wPt=$this->fwPt; 
    1109         $hPt=$this->fhPt; 
    1110     } 
    1111     else 
    1112     { 
    1113         $wPt=$this->fhPt; 
    1114         $hPt=$this->fwPt; 
     1387        $wPt=$this->DefPageFormat[0]*$this->k; 
     1388        $hPt=$this->DefPageFormat[1]*$this->k; 
     1389    } 
     1390    else 
     1391    { 
     1392        $wPt=$this->DefPageFormat[1]*$this->k; 
     1393        $hPt=$this->DefPageFormat[0]*$this->k; 
    11151394    } 
    11161395    $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; 
     
    11211400        $this->_out('<</Type /Page'); 
    11221401        $this->_out('/Parent 1 0 R'); 
    1123         if(isset($this->OrientationChanges[$n])) 
    1124             $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$hPt,$wPt)); 
     1402        if(isset($this->PageSizes[$n])) 
     1403            $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]',$this->PageSizes[$n][0],$this->PageSizes[$n][1])); 
    11251404        $this->_out('/Resources 2 0 R'); 
    11261405        if(isset($this->PageLinks[$n])) 
     
    11301409            foreach($this->PageLinks[$n] as $pl) 
    11311410            { 
    1132                 $rect=sprintf('%.2f %.2f %.2f %.2f',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]); 
     1411                $rect=sprintf('%.2F %.2F %.2F %.2F',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]); 
    11331412                $annots.='<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] '; 
    11341413                if(is_string($pl[4])) 
     
    11371416                { 
    11381417                    $l=$this->links[$pl[4]]; 
    1139                     $h=isset($this->OrientationChanges[$l[0]]) ? $wPt : $hPt; 
    1140                     $annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>',1+2*$l[0],$h-$l[1]*$this->k); 
     1418                    $h=isset($this->PageSizes[$l[0]]) ? $this->PageSizes[$l[0]][1] : $hPt; 
     1419                    $annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]>>',1+2*$l[0],$h-$l[1]*$this->k); 
    11411420                } 
    11421421            } 
     
    11611440    $this->_out($kids.']'); 
    11621441    $this->_out('/Count '.$nb); 
    1163     $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$wPt,$hPt)); 
     1442    $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]',$wPt,$hPt)); 
    11641443    $this->_out('>>'); 
    11651444    $this->_out('endobj'); 
     
    11761455        $this->_out('endobj'); 
    11771456    } 
    1178     $mqr=get_magic_quotes_runtime(); 
    1179     set_magic_quotes_runtime(0); 
    11801457    foreach($this->FontFiles as $file=>$info) 
    11811458    { 
     
    11931470        if(!$compressed && isset($info['length2'])) 
    11941471        { 
    1195             $header=(ord($font{0})==128); 
     1472            $header=(ord($font[0])==128); 
    11961473            if($header) 
    11971474            { 
     
    11991476                $font=substr($font,6); 
    12001477            } 
    1201             if($header && ord($font{$info['length1']})==128) 
     1478            if($header && ord($font[$info['length1']])==128) 
    12021479            { 
    12031480                //Strip second binary header 
     
    12151492        $this->_out('endobj'); 
    12161493    } 
    1217     set_magic_quotes_runtime($mqr); 
    12181494    foreach($this->fonts as $k=>$font) 
    12191495    { 
     
    13751651    if(!empty($this->creator)) 
    13761652        $this->_out('/Creator '.$this->_textstring($this->creator)); 
    1377     $this->_out('/CreationDate '.$this->_textstring('D:'.date('YmdHis'))); 
     1653    $this->_out('/CreationDate '.$this->_textstring('D:'.@date('YmdHis'))); 
    13781654} 
    13791655 
     
    14441720    $this->state=3; 
    14451721} 
    1446  
    1447 function _beginpage($orientation) 
    1448 { 
    1449     $this->page++; 
    1450     $this->pages[$this->page]=''; 
    1451     $this->state=2; 
    1452     $this->x=$this->lMargin; 
    1453     $this->y=$this->tMargin; 
    1454     $this->FontFamily=''; 
    1455     //Page orientation 
    1456     if(!$orientation) 
    1457         $orientation=$this->DefOrientation; 
    1458     else 
    1459     { 
    1460         $orientation=strtoupper($orientation{0}); 
    1461         if($orientation!=$this->DefOrientation) 
    1462             $this->OrientationChanges[$this->page]=true; 
    1463     } 
    1464     if($orientation!=$this->CurOrientation) 
    1465     { 
    1466         //Change orientation 
    1467         if($orientation=='P') 
    1468         { 
    1469             $this->wPt=$this->fwPt; 
    1470             $this->hPt=$this->fhPt; 
    1471             $this->w=$this->fw; 
    1472             $this->h=$this->fh; 
    1473         } 
    1474         else 
    1475         { 
    1476             $this->wPt=$this->fhPt; 
    1477             $this->hPt=$this->fwPt; 
    1478             $this->w=$this->fh; 
    1479             $this->h=$this->fw; 
    1480         } 
    1481         $this->PageBreakTrigger=$this->h-$this->bMargin; 
    1482         $this->CurOrientation=$orientation; 
    1483     } 
    1484 } 
    1485  
    1486 function _endpage() 
    1487 { 
    1488     //End of page contents 
    1489     $this->state=1; 
    1490 } 
    1491  
    1492 function _newobj() 
    1493 { 
    1494     //Begin a new object 
    1495     $this->n++; 
    1496     $this->offsets[$this->n]=strlen($this->buffer); 
    1497     $this->_out($this->n.' 0 obj'); 
    1498 } 
    1499  
    1500 function _dounderline($x,$y,$txt) 
    1501 { 
    1502     //Underline text 
    1503     $up=$this->CurrentFont['up']; 
    1504     $ut=$this->CurrentFont['ut']; 
    1505     $w=$this->GetStringWidth($txt)+$this->ws*substr_count($txt,' '); 
    1506     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); 
    1507 } 
    1508  
    1509 function _parsejpg($file) 
    1510 { 
    1511     //Extract info from a JPEG file 
    1512     $a=GetImageSize($file); 
    1513     if(!$a) 
    1514         $this->Error('Missing or incorrect image file: '.$file); 
    1515     if($a[2]!=2) 
    1516         $this->Error('Not a JPEG file: '.$file); 
    1517     if(!isset($a['channels']) || $a['channels']==3) 
    1518         $colspace='DeviceRGB'; 
    1519     elseif($a['channels']==4) 
    1520         $colspace='DeviceCMYK'; 
    1521     else 
    1522         $colspace='DeviceGray'; 
    1523     $bpc=isset($a['bits']) ? $a['bits'] : 8; 
    1524     //Read whole file 
    1525     $f=fopen($file,'rb'); 
    1526     $data=''; 
    1527     while(!feof($f)) 
    1528         $data.=fread($f,4096); 
    1529     fclose($f); 
    1530     return array('w'=>$a[0],'h'=>$a[1],'cs'=>$colspace,'bpc'=>$bpc,'f'=>'DCTDecode','data'=>$data); 
    1531 } 
    1532  
    1533 function _parsepng($file) 
    1534 { 
    1535     //Extract info from a PNG file 
    1536     $f=fopen($file,'rb'); 
    1537     if(!$f) 
    1538         $this->Error('Can\'t open image file: '.$file); 
    1539     //Check signature 
    1540     if(fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) 
    1541         $this->Error('Not a PNG file: '.$file); 
    1542     //Read header chunk 
    1543     fread($f,4); 
    1544     if(fread($f,4)!='IHDR') 
    1545         $this->Error('Incorrect PNG file: '.$file); 
    1546     $w=$this->_freadint($f); 
    1547     $h=$this->_freadint($f); 
    1548     $bpc=ord(fread($f,1)); 
    1549     if($bpc>8) 
    1550         $this->Error('16-bit depth not supported: '.$file); 
    1551     $ct=ord(fread($f,1)); 
    1552     if($ct==0) 
    1553         $colspace='DeviceGray'; 
    1554     elseif($ct==2) 
    1555         $colspace='DeviceRGB'; 
    1556     elseif($ct==3) 
    1557         $colspace='Indexed'; 
    1558     else 
    1559         $this->Error('Alpha channel not supported: '.$file); 
    1560     if(ord(fread($f,1))!=0) 
    1561         $this->Error('Unknown compression method: '.$file); 
    1562     if(ord(fread($f,1))!=0) 
    1563         $this->Error('Unknown filter method: '.$file); 
    1564     if(ord(fread($f,1))!=0) 
    1565         $this->Error('Interlacing not supported: '.$file); 
    1566     fread($f,4); 
    1567     $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>'; 
    1568     //Scan chunks looking for palette, transparency and image data 
    1569     $pal=''; 
    1570     $trns=''; 
    1571     $data=''; 
    1572     do 
    1573     { 
    1574         $n=$this->_freadint($f); 
    1575         $type=fread($f,4); 
    1576         if($type=='PLTE') 
    1577         { 
    1578             //Read palette 
    1579             $pal=fread($f,$n); 
    1580             fread($f,4); 
    1581         } 
    1582         elseif($type=='tRNS') 
    1583         { 
    1584             //Read transparency info 
    1585             $t=fread($f,$n); 
    1586             if($ct==0) 
    1587                 $trns=array(ord(substr($t,1,1))); 
    1588             elseif($ct==2) 
    1589                 $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1))); 
    1590             else 
    1591             { 
    1592                 $pos=strpos($t,chr(0)); 
    1593                 if($pos!==false) 
    1594                     $trns=array($pos); 
    1595             } 
    1596             fread($f,4); 
    1597         } 
    1598         elseif($type=='IDAT') 
    1599         { 
    1600             //Read image data block 
    1601             $data.=fread($f,$n); 
    1602             fread($f,4); 
    1603         } 
    1604         elseif($type=='IEND') 
    1605             break; 
    1606         else 
    1607             fread($f,$n+4); 
    1608     } 
    1609     while($n); 
    1610     if($colspace=='Indexed' && empty($pal)) 
    1611         $this->Error('Missing palette in '.$file); 
    1612     fclose($f); 
    1613     return array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$data); 
    1614 } 
    1615  
    1616 function _freadint($f) 
    1617 { 
    1618     //Read a 4-byte integer from file 
    1619     $a=unpack('Ni',fread($f,4)); 
    1620     return $a['i']; 
    1621 } 
    1622  
    1623 function _textstring($s) 
    1624 { 
    1625     //Format a text string 
    1626     return '('.$this->_escape($s).')'; 
    1627 } 
    1628  
    1629 function _escape($s) 
    1630 { 
    1631     //Add \ before \, ( and ) 
    1632     return str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$s))); 
    1633 } 
    1634  
    1635 function _putstream($s) 
    1636 { 
    1637     $this->_out('stream'); 
    1638     $this->_out($s); 
    1639     $this->_out('endstream'); 
    1640 } 
    1641  
    1642 function _out($s) 
    1643 { 
    1644     //Add a line to the document 
    1645     if($this->state==2) 
    1646         $this->pages[$this->page].=$s."\n"; 
    1647     else 
    1648         $this->buffer.=$s."\n"; 
    1649 } 
    16501722//End of class 
    16511723} 
     
    16581730} 
    16591731 
    1660 } 
    16611732?> 
  • branches/version-2_5-dev/data/module/fpdf/fpdf_tpl.php

    r18701 r19716  
    11<?php 
    22// 
    3 //  FPDF_TPL - Version 1.1.1 
    4 // 
    5 //    Copyright 2004-2007 Setasign - Jan Slabon 
     3//  FPDF_TPL - Version 1.2 
     4// 
     5//    Copyright 2004-2010 Setasign - Jan Slabon 
    66// 
    77//  Licensed under the Apache License, Version 2.0 (the "License"); 
     
    1818// 
    1919 
    20 require_once("fpdf.php"); 
    21  
    2220class FPDF_TPL extends FPDF { 
    2321    /** 
     
    5250     
    5351    /** 
    54      * Constructor 
    55      * See FPDF-Documentation 
    56      * @param string $orientation 
    57      * @param string $unit 
    58      * @param mixed $format 
    59      */ 
    60     function fpdf_tpl($orientation='P',$unit='mm',$format='A4') { 
    61         parent::fpdf($orientation,$unit,$format); 
    62     } 
     52     * Last used Template data 
     53     * 
     54     * @var array 
     55     */ 
     56    var $lastUsedTemplateData = array(); 
    6357     
    6458    /** 
     
    8074     * @return int The ID of new created Template 
    8175     */ 
    82     function beginTemplate($x=null,$y=null,$w=null,$h=null) { 
     76    function beginTemplate($x = null, $y = null, $w = null, $h = null) { 
     77        if (is_subclass_of($this, 'TCPDF')) { 
     78            $this->Error('This method is only usable with FPDF. Use TCPDF methods startTemplate() instead.'); 
     79            return; 
     80        } 
     81         
    8382        if ($this->page <= 0) 
    8483            $this->error("You have to add a page to fpdf first!"); 
     
    120119 
    121120        $this->_intpl = true; 
    122         $this->SetXY($x+$this->lMargin,$y+$this->tMargin); 
    123         $this->SetRightMargin($this->w-$w+$this->rMargin); 
     121        $this->SetXY($x + $this->lMargin, $y + $this->tMargin); 
     122        $this->SetRightMargin($this->w - $w + $this->rMargin); 
    124123 
    125124        return $this->tpl; 
     
    134133     */ 
    135134    function endTemplate() { 
     135        if (is_subclass_of($this, 'TCPDF')) { 
     136            $args = func_get_args(); 
     137            return call_user_func_array(array($this, 'TCPDF::endTemplate'), $args); 
     138        } 
     139         
    136140        if ($this->_intpl) { 
    137141            $this->_intpl = false;  
     
    168172     * @retrun array The height and width of the template 
    169173     */ 
    170     function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) { 
     174    function useTemplate($tplidx, $_x = null, $_y = null, $_w = 0, $_h = 0) { 
    171175        if ($this->page <= 0) 
    172             $this->error("You have to add a page to fpdf first!"); 
    173  
     176            $this->error('You have to add a page first!'); 
     177         
    174178        if (!isset($this->tpls[$tplidx])) 
    175             $this->error("Template does not exist!"); 
     179            $this->error('Template does not exist!'); 
    176180             
    177181        if ($this->_intpl) { 
     
    180184         
    181185        $tpl =& $this->tpls[$tplidx]; 
    182         $x = $tpl['x']; 
    183         $y = $tpl['y']; 
    184186        $w = $tpl['w']; 
    185187        $h = $tpl['h']; 
    186188         
    187189        if ($_x == null) 
    188             $_x = $x; 
     190            $_x = 0; 
    189191        if ($_y == null) 
    190             $_y = $y; 
    191         $wh = $this->getTemplateSize($tplidx,$_w,$_h); 
     192            $_y = 0; 
     193             
     194        $_x += $tpl['x']; 
     195        $_y += $tpl['y']; 
     196         
     197        $wh = $this->getTemplateSize($tplidx, $_w, $_h); 
    192198        $_w = $wh['w']; 
    193199        $_h = $wh['h']; 
    194200     
    195         $this->_out(sprintf("q %.4f 0 0 %.4f %.2f %.2f cm", ($_w/$w), ($_h/$h), $_x*$this->k, ($this->h-($_y+$_h))*$this->k)); // Translate  
    196         $this->_out($this->tplprefix.$tplidx." Do Q"); 
    197  
    198         return array("w" => $_w, "h" => $_h); 
     201        $tData = array( 
     202            'x' => $this->x, 
     203            'y' => $this->y, 
     204            'w' => $_w, 
     205            'h' => $_h, 
     206            'scaleX' => ($_w / $w), 
     207            'scaleY' => ($_h / $h), 
     208            'tx' => $_x, 
     209            'ty' =>  ($this->h - $_y - $_h), 
     210            'lty' => ($this->h - $_y - $_h) - ($this->h - $h) * ($_h / $h) 
     211        ); 
     212         
     213        $this->_out(sprintf('q %.4F 0 0 %.4F %.4F %.4F cm', $tData['scaleX'], $tData['scaleY'], $tData['tx'] * $this->k, $tData['ty'] * $this->k)); // Translate  
     214        $this->_out(sprintf('%s%d Do Q', $this->tplprefix, $tplidx)); 
     215 
     216        // reset font in the outer graphic state 
     217        if ($this->FontFamily) { 
     218            $family = $this->FontFamily; 
     219            $this->FontFamily = ''; 
     220            $this->SetFont($family); 
     221        } 
     222         
     223        $this->lastUsedTemplateData = $tData; 
     224         
     225        return array('w' => $_w, 'h' => $_h); 
    199226    } 
    200227     
     
    209236     * @return array The height and width of the template 
    210237     */ 
    211     function getTemplateSize($tplidx, $_w=0, $_h=0) { 
     238    function getTemplateSize($tplidx, $_w = 0, $_h = 0) { 
    212239        if (!$this->tpls[$tplidx]) 
    213240            return false; 
     
    222249        } 
    223250 
    224         if($_w==0) 
    225             $_w=$_h*$w/$h; 
    226         if($_h==0) 
    227             $_h=$_w*$h/$w; 
     251        if($_w == 0) 
     252            $_w = $_h * $w / $h; 
     253        if($_h == 0) 
     254            $_h = $_w * $h / $w; 
    228255             
    229256        return array("w" => $_w, "h" => $_h); 
     
    231258     
    232259    /** 
    233      * See FPDF-Documentation ;-) 
    234      */ 
    235     function SetFont($family,$style='',$size=0) { 
     260     * See FPDF/TCPDF-Documentation ;-) 
     261     */ 
     262    public function SetFont($family, $style = '', $size = 0) { 
     263        if (is_subclass_of($this, 'TCPDF')) { 
     264            $args = func_get_args(); 
     265            return call_user_func_array(array($this, 'TCPDF::SetFont'), $args); 
     266        } 
     267         
    236268        /** 
    237269         * force the resetting of font changes in a template 
     
    242274        parent::SetFont($family, $style, $size); 
    243275        
    244         $fontkey = $this->FontFamily.$this->FontStyle; 
     276        $fontkey = $this->FontFamily . $this->FontStyle; 
    245277         
    246278        if ($this->_intpl) { 
     
    252284     
    253285    /** 
    254      * See FPDF-Documentation ;-) 
    255      */ 
    256     function Image($file,$x,$y,$w=0,$h=0,$type='',$link='') { 
    257         parent::Image($file,$x,$y,$w,$h,$type,$link); 
     286     * See FPDF/TCPDF-Documentation ;-) 
     287     */ 
     288    function Image($file, $x = null, $y = null, $w = 0, $h = 0, $type = '', $link = '') { 
     289        if (is_subclass_of($this, 'TCPDF')) { 
     290            $args = func_get_args(); 
     291            return call_user_func_array(array($this, 'TCPDF::Image'), $args); 
     292        } 
     293         
     294        $ret = parent::Image($file, $x, $y, $w, $h, $type, $link); 
    258295        if ($this->_intpl) { 
    259296            $this->_res['tpl'][$this->tpl]['images'][$file] =& $this->images[$file]; 
     
    261298            $this->_res['page'][$this->page]['images'][$file] =& $this->images[$file]; 
    262299        } 
     300         
     301        return $ret; 
    263302    } 
    264303     
     
    268307     * AddPage is not available when you're "in" a template. 
    269308     */ 
    270     function AddPage($orientation='') { 
     309    function AddPage($orientation = '', $format = '') { 
     310        if (is_subclass_of($this, 'TCPDF')) { 
     311            $args = func_get_args(); 
     312            return call_user_func_array(array($this, 'TCPDF::AddPage'), $args); 
     313        } 
     314         
    271315        if ($this->_intpl) 
    272316            $this->Error('Adding pages in templates isn\'t possible!'); 
    273         parent::AddPage($orientation); 
     317             
     318        parent::AddPage($orientation, $format); 
    274319    } 
    275320 
     
    277322     * Preserve adding Links in Templates ...won't work 
    278323     */ 
    279     function Link($x,$y,$w,$h,$link) { 
     324    function Link($x, $y, $w, $h, $link) { 
     325        if (is_subclass_of($this, 'TCPDF')) { 
     326            $args = func_get_args(); 
     327            return call_user_func_array(array($this, 'TCPDF::Link'), $args); 
     328        } 
     329         
    280330        if ($this->_intpl) 
    281331            $this->Error('Using links in templates aren\'t possible!'); 
    282         parent::Link($x,$y,$w,$h,$link); 
     332             
     333        parent::Link($x, $y, $w, $h, $link); 
    283334    } 
    284335     
    285336    function AddLink() { 
     337        if (is_subclass_of($this, 'TCPDF')) { 
     338            $args = func_get_args(); 
     339            return call_user_func_array(array($this, 'TCPDF::AddLink'), $args); 
     340        } 
     341         
    286342        if ($this->_intpl) 
    287343            $this->Error('Adding links in templates aren\'t possible!'); 
     
    289345    } 
    290346     
    291     function SetLink($link,$y=0,$page=-1) { 
     347    function SetLink($link, $y = 0, $page = -1) { 
     348        if (is_subclass_of($this, 'TCPDF')) { 
     349            $args = func_get_args(); 
     350            return call_user_func_array(array($this, 'TCPDF::SetLink'), $args); 
     351        } 
     352         
    292353        if ($this->_intpl) 
    293354            $this->Error('Setting links in templates aren\'t possible!'); 
    294         parent::SetLink($link,$y,$page); 
     355        parent::SetLink($link, $y, $page); 
    295356    } 
    296357     
     
    309370            $this->_out('/Subtype /Form'); 
    310371            $this->_out('/FormType 1'); 
    311             $this->_out(sprintf('/BBox [%.2f %.2f %.2f %.2f]',$tpl['x']*$this->k, ($tpl['h']-$tpl['y'])*$this->k, $tpl['w']*$this->k, ($tpl['h']-$tpl['y']-$tpl['h'])*$this->k)); 
     372            $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]', 
     373                // llx 
     374                $tpl['x'] * $this->k, 
     375                // lly 
     376                -$tpl['y'] * $this->k, 
     377                // urx 
     378                ($tpl['w'] + $tpl['x']) * $this->k, 
     379                // ury 
     380                ($tpl['h'] - $tpl['y']) * $this->k 
     381            )); 
     382             
     383            if ($tpl['x'] != 0 || $tpl['y'] != 0) { 
     384                $this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]', 
     385                     -$tpl['x'] * $this->k * 2, $tpl['y'] * $this->k * 2 
     386                )); 
     387            } 
     388             
    312389            $this->_out('/Resources '); 
    313390 
     
    316393                $this->_out('/Font <<'); 
    317394                foreach($this->_res['tpl'][$tplidx]['fonts'] as $font) 
    318                     $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R'); 
     395                    $this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R'); 
    319396                $this->_out('>>'); 
    320397            } 
     
    325402                if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) { 
    326403                    foreach($this->_res['tpl'][$tplidx]['images'] as $image) 
    327                         $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R'); 
     404                        $this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R'); 
    328405                } 
    329406                if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) { 
    330407                    foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl) 
    331                         $this->_out($this->tplprefix.$i.' '.$tpl['n'].' 0 R'); 
     408                        $this->_out($this->tplprefix . $i . ' ' . $tpl['n'] . ' 0 R'); 
    332409                } 
    333410                $this->_out('>>'); 
     
    335412            $this->_out('>>'); 
    336413             
    337             $this->_out('/Length '.strlen($p).' >>'); 
     414            $this->_out('/Length ' . strlen($p) . ' >>'); 
    338415            $this->_putstream($p); 
    339416            $this->_out('endobj'); 
     
    342419     
    343420    /** 
    344      * Private Method 
    345      */ 
    346     function _putresources() { 
    347         $this->_putfonts(); 
    348         $this->_putimages(); 
    349         $this->_putformxobjects(); 
    350         //Resource dictionary 
    351         $this->offsets[2]=strlen($this->buffer); 
    352         $this->_out('2 0 obj'); 
    353         $this->_out('<<'); 
    354         $this->_putresourcedict(); 
    355         $this->_out('>>'); 
    356         $this->_out('endobj'); 
     421     * Overwritten to add _putformxobjects() after _putimages() 
     422     * 
     423     */ 
     424    function _putimages() { 
     425        parent::_putimages(); 
     426        $this->_putformxobjects(); 
    357427    } 
    358428     
     
    362432        if (count($this->tpls)) { 
    363433            foreach($this->tpls as $tplidx => $tpl) { 
    364                 $this->_out($this->tplprefix.$tplidx.' '.$tpl['n'].' 0 R'); 
     434                $this->_out(sprintf('%s%d %d 0 R', $this->tplprefix, $tplidx, $tpl['n'])); 
    365435            } 
    366436        } 
     
    371441     */ 
    372442    function _out($s) { 
    373        //Add a line to the document 
    374        if ($this->state==2) { 
    375            if (!$this->_intpl) 
    376                $this->pages[$this->page].=$s."\n"; 
    377            else 
    378                $this->tpls[$this->tpl]['buffer'] .= $s."\n"; 
    379        } else { 
    380            $this->buffer.=$s."\n"; 
    381        } 
     443        if ($this->state == 2 && $this->_intpl) { 
     444            $this->tpls[$this->tpl]['buffer'] .= $s . "\n"; 
     445        } else { 
     446            parent::_out($s); 
     447        } 
    382448    } 
    383449} 
    384  
    385 ?> 
  • branches/version-2_5-dev/data/module/fpdf/fpdi.php

    r17260 r19716  
    11<?php 
    22// 
    3 //  FPDI - Version 1.2 
     3//  FPDI - Version 1.4 
    44// 
    5 //    Copyright 2004-2007 Setasign - Jan Slabon 
     5//    Copyright 2004-2010 Setasign - Jan Slabon 
    66// 
    77//  Licensed under the Apache License, Version 2.0 (the "License"); 
     
    1818// 
    1919 
    20 define('FPDI_VERSION','1.2'); 
    21  
    22 ini_set('auto_detect_line_endings',1); // Strongly required! 
    23  
    24 require_once("fpdf_tpl.php"); 
    25 require_once("fpdi_pdf_parser.php"); 
     20define('FPDI_VERSION', '1.4'); 
     21 
     22// Check for TCPDF and remap TCPDF to FPDF 
     23if (class_exists('TCPDF', false)) { 
     24    require_once('fpdi2tcpdf_bridge.php'); 
     25} 
     26 
     27require_once('fpdf_tpl.php'); 
     28require_once('fpdi_pdf_parser.php'); 
    2629 
    2730 
     
    4649     
    4750    /** 
    48      * Highest version of imported PDF 
    49      * @var double 
    50      */ 
    51     var $importVersion = 1.3; 
    52  
    53     /** 
    5451     * object stack 
    5552     * @var array 
     
    7673     
    7774    /** 
    78      * Constructor 
    79      * See FPDF-Manual 
    80      */ 
    81     function FPDI($orientation='P',$unit='mm',$format='A4') { 
    82         parent::FPDF_TPL($orientation,$unit,$format); 
    83     } 
     75     * Cache for imported pages/template ids 
     76     * @var array 
     77     */ 
     78    var $_importedPages = array(); 
    8479     
    8580    /** 
     
    9186    function setSourceFile($filename) { 
    9287        $this->current_filename = $filename; 
    93         $fn =& $this->current_filename; 
    94  
    95         if (!isset($this->parsers[$fn])) 
    96             $this->parsers[$fn] =& new fpdi_pdf_parser($fn,$this); 
    97         $this->current_parser =& $this->parsers[$fn]; 
    98          
    99         return $this->parsers[$fn]->getPageCount(); 
    100     } 
    101      
     88         
     89        if (!isset($this->parsers[$filename])) 
     90            $this->parsers[$filename] = $this->_getPdfParser($filename); 
     91        $this->current_parser =& $this->parsers[$filename]; 
     92         
     93        return $this->parsers[$filename]->getPageCount(); 
     94    } 
     95     
     96    /** 
     97     * Returns a PDF parser object 
     98     * 
     99     * @param string $filename 
     100     * @return fpdi_pdf_parser 
     101     */ 
     102    function _getPdfParser($filename) { 
     103        return new fpdi_pdf_parser($filename, $this); 
     104    } 
     105     
     106    /** 
     107     * Get the current PDF version 
     108     * 
     109     * @return string 
     110     */ 
     111    function getPDFVersion() { 
     112        return $this->PDFVersion; 
     113    } 
     114     
     115    /** 
     116     * Set the PDF version 
     117     * 
     118     * @return string 
     119     */ 
     120    function setPDFVersion($version = '1.3') { 
     121        $this->PDFVersion = $version; 
     122    } 
     123     
    102124    /** 
    103125     * Import a page 
     
    106128     * @return int Index of imported page - to use with fpdf_tpl::useTemplate() 
    107129     */ 
    108     function importPage($pageno, $boxName='/CropBox') { 
     130    function importPage($pageno, $boxName = '/CropBox') { 
    109131        if ($this->_intpl) { 
    110             return $this->error("Please import the desired pages before creating a new template."); 
    111         } 
    112          
    113         $fn =& $this->current_filename; 
     132            return $this->error('Please import the desired pages before creating a new template.'); 
     133        } 
     134         
     135        $fn = $this->current_filename; 
     136         
     137        // check if page already imported 
     138        $pageKey = $fn . ((int)$pageno) . $boxName; 
     139        if (isset($this->_importedPages[$pageKey])) 
     140            return $this->_importedPages[$pageKey]; 
    114141         
    115142        $parser =& $this->parsers[$fn]; 
    116143        $parser->setPageno($pageno); 
    117144 
    118         $this->tpl++; 
    119         $this->tpls[$this->tpl] = array(); 
    120         $tpl =& $this->tpls[$this->tpl]; 
    121         $tpl['parser'] =& $parser; 
    122         $tpl['resources'] = $parser->getPageResources(); 
    123         $tpl['buffer'] = $parser->getContent(); 
    124          
    125145        if (!in_array($boxName, $parser->availableBoxes)) 
    126             return $this->Error(sprintf("Unknown box: %s", $boxName)); 
    127         $pageboxes = $parser->getPageBoxes($pageno); 
     146            return $this->Error(sprintf('Unknown box: %s', $boxName)); 
     147        $pageboxes = $parser->getPageBoxes($pageno, $this->k); 
    128148         
    129149        /** 
     
    134154         * ArtBox: Default -> CropBox 
    135155         */ 
    136         if (!isset($pageboxes[$boxName]) && ($boxName == "/BleedBox" || $boxName == "/TrimBox" || $boxName == "/ArtBox")) 
    137             $boxName = "/CropBox"; 
    138         if (!isset($pageboxes[$boxName]) && $boxName == "/CropBox") 
    139             $boxName = "/MediaBox"; 
     156        if (!isset($pageboxes[$boxName]) && ($boxName == '/BleedBox' || $boxName == '/TrimBox' || $boxName == '/ArtBox')) 
     157            $boxName = '/CropBox'; 
     158        if (!isset($pageboxes[$boxName]) && $boxName == '/CropBox') 
     159            $boxName = '/MediaBox'; 
    140160         
    141161        if (!isset($pageboxes[$boxName])) 
     
    144164         
    145165        $box = $pageboxes[$boxName]; 
     166         
     167        $this->tpl++; 
     168        $this->tpls[$this->tpl] = array(); 
     169        $tpl =& $this->tpls[$this->tpl]; 
     170        $tpl['parser'] =& $parser; 
     171        $tpl['resources'] = $parser->getPageResources(); 
     172        $tpl['buffer'] = $parser->getContent(); 
    146173        $tpl['box'] = $box; 
    147174         
    148175        // To build an array that can be used by PDF_TPL::useTemplate() 
    149         $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl],$box); 
     176        $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl], $box); 
     177         
    150178        // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects() 
    151179        $tpl['x'] = 0; 
    152180        $tpl['y'] = 0; 
    153181         
    154         $page =& $parser->pages[$parser->pageno]; 
    155          
    156         // fix for rotated pages 
     182        // handle rotated pages 
    157183        $rotation = $parser->getPageRotation($pageno); 
     184        $tpl['_rotationAngle'] = 0; 
    158185        if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0) { 
    159             $steps = $angle / 90; 
     186            $steps = $angle / 90; 
    160187                 
    161188            $_w = $tpl['w']; 
     
    164191            $tpl['h'] = $steps % 2 == 0 ? $_h : $_w; 
    165192             
    166             if ($steps % 2 != 0) { 
    167                 $x = $y = ($steps == 1 || $steps == -3) ? $tpl['h'] : $tpl['w']; 
    168             } else { 
    169                 $x = $tpl['w']; 
    170                 $y = $tpl['h']; 
    171             } 
    172              
    173             $cx=($x/2+$tpl['box']['x'])*$this->k; 
    174             $cy=($y/2+$tpl['box']['y'])*$this->k; 
    175              
    176             $angle*=-1;  
    177              
    178             $angle*=M_PI/180; 
    179             $c=cos($angle); 
    180             $s=sin($angle); 
    181              
    182             $tpl['buffer'] = sprintf('q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm %s Q',$c,$s,-$s,$c,$cx,$cy,-$cx,-$cy, $tpl['buffer']); 
    183         } 
     193            if ($angle < 0) 
     194                $angle += 360; 
     195             
     196            $tpl['_rotationAngle'] = $angle * -1; 
     197        } 
     198         
     199        $this->_importedPages[$pageKey] = $this->tpl; 
    184200         
    185201        return $this->tpl; 
     
    190206    } 
    191207     
    192     function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) { 
    193         $this->_out('q 0 J 1 w 0 j 0 G'); // reset standard values 
     208    function useTemplate($tplidx, $_x = null, $_y = null, $_w = 0, $_h = 0, $adjustPageSize = false) { 
     209        if ($adjustPageSize == true && is_null($_x) && is_null($_y)) { 
     210            $size = $this->getTemplateSize($tplidx, $_w, $_h); 
     211            $format = array($size['w'], $size['h']); 
     212            if (is_subclass_of($this, 'TCPDF')) { 
     213                $this->setPageFormat($format, $format[0] > $format[1] ? 'L' : 'P'); 
     214            } else { 
     215                if ($format[0] != $this->CurPageFormat[0] || $format[1] != $this->CurPageFormat[1]) { 
     216                    $this->w = $format[0]; 
     217                    $this->h = $format[1]; 
     218                    $this->wPt = $this->w * $this->k; 
     219                    $this->hPt = $this->h * $this->k; 
     220                    $this->PageBreakTrigger = $this->h - $this->bMargin; 
     221                    $this->CurPageFormat = $format; 
     222                    $this->PageSizes[$this->page] = array($this->wPt, $this->hPt); 
     223                } 
     224            }  
     225        } 
     226         
     227        $this->_out('q 0 J 1 w 0 j 0 G 0 g'); // reset standard values 
    194228        $s = parent::useTemplate($tplidx, $_x, $_y, $_w, $_h); 
    195229        $this->_out('Q'); 
     230         
    196231        return $s; 
    197232    } 
     
    204239            foreach($this->parsers AS $filename => $p) { 
    205240                $this->current_parser =& $this->parsers[$filename]; 
    206                 if (is_array($this->_obj_stack[$filename])) { 
    207                     while($n = key($this->_obj_stack[$filename])) { 
    208                         $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c,$this->_obj_stack[$filename][$n][1]); 
     241                if (isset($this->_obj_stack[$filename]) && is_array($this->_obj_stack[$filename])) { 
     242                    while(($n = key($this->_obj_stack[$filename])) !== null) { 
     243                        $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c, $this->_obj_stack[$filename][$n][1]); 
    209244                         
    210245                        $this->_newobj($this->_obj_stack[$filename][$n][0]); 
    211246                         
    212247                        if ($nObj[0] == PDF_TYPE_STREAM) { 
    213                             $this->pdf_write_value ($nObj); 
     248                            $this->pdf_write_value($nObj); 
    214249                        } else { 
    215                             $this->pdf_write_value ($nObj[1]); 
     250                            $this->pdf_write_value($nObj[1]); 
    216251                        } 
    217252                         
     
    226261    } 
    227262     
    228     /** 
    229      * Sets the PDF Version to the highest of imported documents 
    230      */ 
    231     function setVersion() { 
    232         $this->PDFVersion = max($this->importVersion, $this->PDFVersion); 
    233     } 
    234      
    235     /** 
    236      * Put resources 
    237      */ 
    238     function _putresources() { 
    239         $this->_putfonts(); 
    240         $this->_putimages(); 
    241         $this->_putformxobjects(); 
    242         $this->_putimportedobjects(); 
    243         //Resource dictionary 
    244         $this->offsets[2]=strlen($this->buffer); 
    245         $this->_out('2 0 obj'); 
    246         $this->_out('<<'); 
    247         $this->_putresourcedict(); 
    248         $this->_out('>>'); 
    249         $this->_out('endobj'); 
    250     } 
    251263     
    252264    /** 
     
    259271            $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer']; 
    260272            $this->_newobj(); 
     273            $cN = $this->n; // TCPDF/Protection: rem current "n" 
     274             
    261275            $this->tpls[$tplidx]['n'] = $this->n; 
    262             $this->_out('<<'.$filter.'/Type /XObject'); 
     276            $this->_out('<<' . $filter . '/Type /XObject'); 
    263277            $this->_out('/Subtype /Form'); 
    264278            $this->_out('/FormType 1'); 
    265279             
    266             $this->_out(sprintf('/BBox [%.2f %.2f %.2f %.2f]', 
    267                 ($tpl['x'] + (isset($tpl['box']['x'])?$tpl['box']['x']:0))*$this->k, 
    268                 ($tpl['h'] + (isset($tpl['box']['y'])?$tpl['box']['y']:0) - $tpl['y'])*$this->k, 
    269                 ($tpl['w'] + (isset($tpl['box']['x'])?$tpl['box']['x']:0))*$this->k, 
    270                 ($tpl['h'] + (isset($tpl['box']['y'])?$tpl['box']['y']:0) - $tpl['y']-$tpl['h'])*$this->k) 
    271             ); 
    272              
    273             if (isset($tpl['box'])) 
    274                 $this->_out(sprintf('/Matrix [1 0 0 1 %.5f %.5f]',-$tpl['box']['x']*$this->k, -$tpl['box']['y']*$this->k)); 
     280            $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]',  
     281                (isset($tpl['box']['llx']) ? $tpl['box']['llx'] : $tpl['x']) * $this->k, 
     282                (isset($tpl['box']['lly']) ? $tpl['box']['lly'] : -$tpl['y']) * $this->k, 
     283                (isset($tpl['box']['urx']) ? $tpl['box']['urx'] : $tpl['w'] + $tpl['x']) * $this->k, 
     284                (isset($tpl['box']['ury']) ? $tpl['box']['ury'] : $tpl['h'] - $tpl['y']) * $this->k 
     285            )); 
     286             
     287            $c = 1; 
     288            $s = 0; 
     289            $tx = 0; 
     290            $ty = 0; 
     291             
     292            if (isset($tpl['box'])) { 
     293                $tx = -$tpl['box']['llx']; 
     294                $ty = -$tpl['box']['lly'];  
     295                 
     296                if ($tpl['_rotationAngle'] <> 0) { 
     297                    $angle = $tpl['_rotationAngle'] * M_PI/180; 
     298                    $c=cos($angle); 
     299                    $s=sin($angle); 
     300                     
     301                    switch($tpl['_rotationAngle']) { 
     302                        case -90: 
     303                           $tx = -$tpl['box']['lly']; 
     304                           $ty = $tpl['box']['urx']; 
     305                           break; 
     306                        case -180: 
     307                            $tx = $tpl['box']['urx']; 
     308                            $ty = $tpl['box']['ury']; 
     309                            break; 
     310                        case -270: 
     311                            $tx = $tpl['box']['ury']; 
     312                            $ty = -$tpl['box']['llx']; 
     313                            break; 
     314                    } 
     315                } 
     316            } else if ($tpl['x'] != 0 || $tpl['y'] != 0) { 
     317                $tx = -$tpl['x']*2; 
     318                $ty = $tpl['y']*2; 
     319            } 
     320             
     321            $tx *= $this->k; 
     322            $ty *= $this->k; 
     323             
     324            if ($c != 1 || $s != 0 || $tx != 0 || $ty != 0) { 
     325                $this->_out(sprintf('/Matrix [%.5F %.5F %.5F %.5F %.5F %.5F]', 
     326                    $c, $s, -$s, $c, $tx, $ty 
     327                )); 
     328            } 
    275329             
    276330            $this->_out('/Resources '); 
     
    278332            if (isset($tpl['resources'])) { 
    279333                $this->current_parser =& $tpl['parser']; 
    280                 $this->pdf_write_value($tpl['resources']); 
     334                $this->pdf_write_value($tpl['resources']); // "n" will be changed 
    281335            } else { 
    282336                $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); 
     
    284338                    $this->_out('/Font <<'); 
    285339                    foreach($this->_res['tpl'][$tplidx]['fonts'] as $font) 
    286                         $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R'); 
     340                        $this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R'); 
    287341                    $this->_out('>>'); 
    288342                } 
     
    293347                    if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) { 
    294348                        foreach($this->_res['tpl'][$tplidx]['images'] as $image) 
    295                             $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R'); 
     349                            $this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R'); 
    296350                    } 
    297351                    if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) { 
    298352                        foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl) 
    299                             $this->_out($this->tplprefix.$i.' '.$tpl['n'].' 0 R'); 
     353                            $this->_out($this->tplprefix . $i . ' ' . $tpl['n'] . ' 0 R'); 
    300354                    } 
    301355                    $this->_out('>>'); 
     
    304358            } 
    305359 
    306             $this->_out('/Length '.strlen($p).' >>'); 
     360            $nN = $this->n; // TCPDF: rem new "n" 
     361            $this->n = $cN; // TCPDF: reset to current "n" 
     362            $this->_out('/Length ' . strlen($p) . ' >>'); 
    307363            $this->_putstream($p); 
    308364            $this->_out('endobj'); 
    309         } 
     365            $this->n = $nN; // TCPDF: reset to new "n" 
     366        } 
     367         
     368        $this->_putimportedobjects(); 
    310369    } 
    311370 
     
    313372     * Rewritten to handle existing own defined objects 
    314373     */ 
    315     function _newobj($obj_id=false,$onlynewobj=false) { 
     374    function _newobj($obj_id = false, $onlynewobj = false) { 
    316375        if (!$obj_id) { 
    317376            $obj_id = ++$this->n; 
    318377        } 
    319378 
    320         //Begin a new object 
     379        //Begin a new object 
    321380        if (!$onlynewobj) { 
    322             $this->offsets[$obj_id] = strlen($this->buffer); 
    323             $this->_out($obj_id.' 0 obj'); 
     381            $this->offsets[$obj_id] = is_subclass_of($this, 'TCPDF') ? $this->bufferlen : strlen($this->buffer); 
     382            $this->_out($obj_id . ' 0 obj'); 
    324383            $this->_current_obj_id = $obj_id; // for later use with encryption 
    325384        } 
    326385         
     386        return $obj_id; 
    327387    } 
    328388 
     
    335395    function pdf_write_value(&$value) 
    336396    { 
    337  
     397        if (is_subclass_of($this, 'TCPDF')) { 
     398            parent::pdf_write_value($value); 
     399        } 
     400         
    338401        switch ($value[0]) { 
    339402 
    340             case PDF_TYPE_NUMERIC : 
    341             case PDF_TYPE_TOKEN : 
    342                 // A numeric value or a token. 
    343                 // Simply output them 
    344                 $this->_out($value[1]." ", false); 
    345                 break; 
    346  
    347             case PDF_TYPE_ARRAY : 
     403            case PDF_TYPE_TOKEN: 
     404                $this->_straightOut($value[1] . ' '); 
     405                break; 
     406            case PDF_TYPE_NUMERIC: 
     407            case PDF_TYPE_REAL: 
     408                if (is_float($value[1]) && $value[1] != 0) { 
     409                    $this->_straightOut(rtrim(rtrim(sprintf('%F', $value[1]), '0'), '.') . ' '); 
     410                } else { 
     411                    $this->_straightOut($value[1] . ' '); 
     412                } 
     413                break; 
     414                 
     415            case PDF_TYPE_ARRAY: 
    348416 
    349417                // An array. Output the proper 
    350418                // structure and move on. 
    351419 
    352                 $this->_out("[",false); 
     420                $this->_straightOut('['); 
    353421                for ($i = 0; $i < count($value[1]); $i++) { 
    354422                    $this->pdf_write_value($value[1][$i]); 
    355423                } 
    356424 
    357                 $this->_out("]"); 
    358                 break; 
    359  
    360             case PDF_TYPE_DICTIONARY : 
     425                $this->_out(']'); 
     426                break; 
     427 
     428            case PDF_TYPE_DICTIONARY: 
    361429 
    362430                // A dictionary. 
    363                 $this->_out("<<",false); 
     431                $this->_straightOut('<<'); 
    364432 
    365433                reset ($value[1]); 
    366434 
    367435                while (list($k, $v) = each($value[1])) { 
    368                     $this->_out($k . " ",false); 
     436                    $this->_straightOut($k . ' '); 
    369437                    $this->pdf_write_value($v); 
    370438                } 
    371439 
    372                 $this->_out(">>"); 
    373                 break; 
    374  
    375             case PDF_TYPE_OBJREF : 
     440                $this->_straightOut('>>'); 
     441                break; 
     442 
     443            case PDF_TYPE_OBJREF: 
    376444 
    377445                // An indirect object reference 
    378446                // Fill the object stack if needed 
    379447                $cpfn =& $this->current_parser->filename; 
     448                 
    380449                if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) { 
    381                     $this->_newobj(false,true); 
    382                     $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value); 
    383                     $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value); 
     450                    $this->_newobj(false, true); 
     451                    $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value); 
     452                    $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value); // Value is maybee obsolete!!! 
    384453                } 
    385454                $objid = $this->_don_obj_stack[$cpfn][$value[1]][0]; 
    386455 
    387                 $this->_out("{$objid} 0 R"); //{$value[2]} 
    388                 break; 
    389  
    390             case PDF_TYPE_STRING : 
     456                $this->_out($objid . ' 0 R'); 
     457                break; 
     458 
     459            case PDF_TYPE_STRING: 
    391460 
    392461                // A string. 
    393                 $this->_out('('.$value[1].')'); 
    394  
    395                 break; 
    396  
    397             case PDF_TYPE_STREAM : 
     462                $this->_straightOut('(' . $value[1] . ')'); 
     463 
     464                break; 
     465 
     466            case PDF_TYPE_STREAM: 
    398467 
    399468                // A stream. First, output the 
     
    401470                // stream data itself. 
    402471                $this->pdf_write_value($value[1]); 
    403                 $this->_out("stream"); 
     472                $this->_out('stream'); 
    404473                $this->_out($value[2][1]); 
    405                 $this->_out("endstream"); 
    406                 break; 
    407             case PDF_TYPE_HEX : 
    408              
    409                 $this->_out("<".$value[1].">"); 
     474                $this->_out('endstream'); 
     475                break; 
     476                 
     477            case PDF_TYPE_HEX: 
     478                $this->_straightOut('<' . $value[1] . '>'); 
    410479                break; 
    411480 
    412             case PDF_TYPE_NULL : 
     481            case PDF_TYPE_BOOLEAN: 
     482                $this->_straightOut($value[1] ? 'true ' : 'false '); 
     483                break; 
     484             
     485            case PDF_TYPE_NULL: 
    413486                // The null object. 
    414487 
    415                 $this->_out("null"); 
     488                $this->_straightOut('null '); 
    416489                break; 
    417490        } 
     
    420493     
    421494    /** 
    422      * Private Method 
    423      */ 
    424     function _out($s,$ln=true) { 
    425        //Add a line to the document 
    426        if ($this->state==2) { 
    427            if (!$this->_intpl) 
    428                $this->pages[$this->page] .= $s.($ln == true ? "\n" : ''); 
    429            else 
    430                $this->tpls[$this->tpl]['buffer'] .= $s.($ln == true ? "\n" : ''); 
    431        } else { 
    432            $this->buffer.=$s.($ln == true ? "\n" : ''); 
    433        } 
     495     * Modified so not each call will add a newline to the output. 
     496     */ 
     497    function _straightOut($s) { 
     498        if (!is_subclass_of($this, 'TCPDF')) { 
     499            if($this->state==2) 
     500                $this->pages[$this->page] .= $s; 
     501            else 
     502                $this->buffer .= $s; 
     503        } else { 
     504            if ($this->state == 2) { 
     505                if (isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) { 
     506                    // puts data before page footer 
     507                    $page = substr($this->getPageBuffer($this->page), 0, -$this->footerlen[$this->page]); 
     508                    $footer = substr($this->getPageBuffer($this->page), -$this->footerlen[$this->page]); 
     509                    $this->setPageBuffer($this->page, $page . ' ' . $s . "\n" . $footer); 
     510                } else { 
     511                    $this->setPageBuffer($this->page, $s, true); 
     512                } 
     513            } else { 
     514                $this->setBuffer($s); 
     515            } 
     516        } 
    434517    } 
    435518 
     
    457540        return false; 
    458541    } 
    459  
    460542} 
    461  
    462 // for PHP5 
    463 if (version_compare("5", PHP_VERSION, "<")) { 
    464     if (!class_exists('fpdi')) { 
    465         class fpdi extends FPDI {} 
    466     } 
    467 } 
    468 ?> 
  • branches/version-2_5-dev/data/module/fpdf/fpdi_pdf_parser.php

    r18701 r19716  
    11<?php 
    22// 
    3 //  FPDI - Version 1.2 
    4 // 
    5 //    Copyright 2004-2007 Setasign - Jan Slabon 
     3//  FPDI - Version 1.4 
     4// 
     5//    Copyright 2004-2010 Setasign - Jan Slabon 
    66// 
    77//  Licensed under the Apache License, Version 2.0 (the "License"); 
     
    1818// 
    1919 
    20 require_once("pdf_parser.php"); 
     20require_once('pdf_parser.php'); 
    2121 
    2222class fpdi_pdf_parser extends pdf_parser { 
     
    5959     * @var array 
    6060     */ 
    61     var $availableBoxes = array("/MediaBox","/CropBox","/BleedBox","/TrimBox","/ArtBox"); 
     61    var $availableBoxes = array('/MediaBox', '/CropBox', '/BleedBox', '/TrimBox', '/ArtBox'); 
    6262         
    6363    /** 
     
    6767     * @param object $fpdi      Object of type fpdi 
    6868     */ 
    69     function fpdi_pdf_parser($filename,&$fpdi) { 
     69    function fpdi_pdf_parser($filename, &$fpdi) { 
    7070        $this->fpdi =& $fpdi; 
    71         $this->filename = $filename; 
    7271         
    7372        parent::pdf_parser($filename); 
     
    111110 
    112111        if ($pageno < 0 || $pageno >= $this->getPageCount()) { 
    113             $this->fpdi->error("Pagenumber is wrong!"); 
     112            $this->fpdi->error('Pagenumber is wrong!'); 
    114113        } 
    115114 
     
    164163     */ 
    165164    function getContent() { 
    166         $buffer = ""; 
     165        $buffer = ''; 
    167166         
    168167        if (isset($this->pages[$this->pageno][1][1]['/Contents'])) { 
    169168            $contents = $this->_getPageContent($this->pages[$this->pageno][1][1]['/Contents']); 
    170169            foreach($contents AS $tmp_content) { 
    171                 $buffer .= $this->_rebuildContentStream($tmp_content).' '; 
     170                $buffer .= $this->_rebuildContentStream($tmp_content) . ' '; 
    172171            } 
    173172        } 
     
    215214            $_filter = $obj[1][1]['/Filter']; 
    216215 
     216            if ($_filter[0] == PDF_TYPE_OBJREF) { 
     217                $tmpFilter = $this->pdf_resolve_object($this->c, $_filter); 
     218                $_filter = $tmpFilter[1]; 
     219            } 
     220             
    217221            if ($_filter[0] == PDF_TYPE_TOKEN) { 
    218222                $filters[] = $_filter; 
     
    226230        foreach ($filters AS $_filter) { 
    227231            switch ($_filter[1]) { 
    228                 case "/FlateDecode": 
    229                     if (function_exists('gzuncompress')) { 
    230                         $stream = (strlen($stream) > 0) ? @gzuncompress($stream) : '';                         
     232                case '/FlateDecode': 
     233                    // $stream .= "\x0F\x0D"; // in an errorious stream this suffix could work 
     234                    if (function_exists('gzuncompress')) { 
     235                        $stream = (strlen($stream) > 0) ? @gzuncompress($stream) : ''; 
    231236                    } else { 
    232                         $this->fpdi->error(sprintf("To handle %s filter, please compile php with zlib support.",$_filter[1])); 
     237                        $this->error(sprintf('To handle %s filter, please compile php with zlib support.',$_filter[1])); 
    233238                    } 
     239                     
    234240                    if ($stream === false) { 
    235                         $this->fpdi->error("Error while decompressing stream."); 
     241                        $this->error('Error while decompressing stream.'); 
    236242                    } 
    237243                break; 
     244                case '/LZWDecode': 
     245                    include_once('filters/FilterLZW_FPDI.php'); 
     246                    $decoder = new FilterLZW_FPDI($this->fpdi); 
     247                    $stream = $decoder->decode($stream); 
     248                    break; 
     249                case '/ASCII85Decode': 
     250                    include_once('filters/FilterASCII85_FPDI.php'); 
     251                    $decoder = new FilterASCII85_FPDI($this->fpdi); 
     252                    $stream = $decoder->decode($stream); 
     253                    break; 
    238254                case null: 
    239255                    $stream = $stream; 
    240256                break; 
    241257                default: 
    242                     if (preg_match("/^\/[a-z85]*$/i", $_filter[1], $filterName) && @include_once('decoders'.$_filter[1].'.php')) { 
    243                         $filterName = substr($_filter[1],1); 
    244                         if (class_exists($filterName)) { 
    245                             $decoder =& new $filterName($this->fpdi); 
    246                             $stream = $decoder->decode(trim($stream)); 
    247                         } else { 
    248                             $this->fpdi->error(sprintf("Unsupported Filter: %s",$_filter[1])); 
    249                         } 
    250                     } else { 
    251                         $this->fpdi->error(sprintf("Unsupported Filter: %s",$_filter[1])); 
    252                     } 
     258                    $this->error(sprintf('Unsupported Filter: %s',$_filter[1])); 
    253259            } 
    254260        } 
     
    264270     * @param array $page a /Page 
    265271     * @param string $box_index Type of Box @see $availableBoxes 
    266      * @return array 
    267      */ 
    268     function getPageBox($page, $box_index) { 
    269         $page = $this->pdf_resolve_object($this->c,$page); 
     272     * @param float Scale factor from user space units to points 
     273     * @return array 
     274     */ 
     275    function getPageBox($page, $box_index, $k) { 
     276        $page = $this->pdf_resolve_object($this->c, $page); 
    270277        $box = null; 
    271278        if (isset($page[1][1][$box_index])) 
     
    273280         
    274281        if (!is_null($box) && $box[0] == PDF_TYPE_OBJREF) { 
    275             $tmp_box = $this->pdf_resolve_object($this->c,$box); 
     282            $tmp_box = $this->pdf_resolve_object($this->c, $box); 
    276283            $box = $tmp_box[1]; 
    277284        } 
     
    279286        if (!is_null($box) && $box[0] == PDF_TYPE_ARRAY) { 
    280287            $b =& $box[1]; 
    281             return array("x" => $b[0][1]/$this->fpdi->k, 
    282                          "y" => $b[1][1]/$this->fpdi->k, 
    283                          "w" => abs($b[0][1]-$b[2][1])/$this->fpdi->k, 
    284                          "h" => abs($b[1][1]-$b[3][1])/$this->fpdi->k); 
     288            return array('x' => $b[0][1]/$k, 
     289                         'y' => $b[1][1]/$k, 
     290                         'w' => abs($b[0][1]-$b[2][1])/$k, 
     291                         'h' => abs($b[1][1]-$b[3][1])/$k, 
     292                         'llx' => min($b[0][1], $b[2][1])/$k, 
     293                         'lly' => min($b[1][1], $b[3][1])/$k, 
     294                         'urx' => max($b[0][1], $b[2][1])/$k, 
     295                         'ury' => max($b[1][1], $b[3][1])/$k, 
     296                         ); 
    285297        } else if (!isset ($page[1][1]['/Parent'])) { 
    286298            return false; 
    287299        } else { 
    288             return $this->getPageBox($this->pdf_resolve_object($this->c, $page[1][1]['/Parent']), $box_index); 
    289         } 
    290     } 
    291  
    292     function getPageBoxes($pageno) { 
    293         return $this->_getPageBoxes($this->pages[$pageno-1]); 
    294     } 
    295      
    296     /** 
    297      * Get all Boxes from /Page 
     300            return $this->getPageBox($this->pdf_resolve_object($this->c, $page[1][1]['/Parent']), $box_index, $k); 
     301        } 
     302    } 
     303 
     304    /** 
     305     * Get all page boxes by page no 
     306     *  
     307     * @param int The page number 
     308     * @param float Scale factor from user space units to points 
     309     * @return array 
     310     */ 
     311     function getPageBoxes($pageno, $k) { 
     312        return $this->_getPageBoxes($this->pages[$pageno-1], $k); 
     313    } 
     314     
     315    /** 
     316     * Get all boxes from /Page 
    298317     * 
    299318     * @param array a /Page 
    300319     * @return array 
    301320     */ 
    302     function _getPageBoxes($page) { 
     321    function _getPageBoxes($page, $k) { 
    303322        $boxes = array(); 
    304323 
    305324        foreach($this->availableBoxes AS $box) { 
    306             if ($_box = $this->getPageBox($page,$box)) { 
     325            if ($_box = $this->getPageBox($page, $box, $k)) { 
    307326                $boxes[$box] = $_box; 
    308327            } 
     
    312331    } 
    313332 
     333    /** 
     334     * Get the page rotation by pageno 
     335     * 
     336     * @param integer $pageno 
     337     * @return array 
     338     */ 
    314339    function getPageRotation($pageno) { 
    315340        return $this->_getPageRotation($this->pages[$pageno-1]); 
    316341    } 
    317342     
    318     function _getPageRotation ($obj) { // $obj = /Page 
     343    function _getPageRotation($obj) { // $obj = /Page 
    319344        $obj = $this->pdf_resolve_object($this->c, $obj); 
    320345        if (isset ($obj[1][1]['/Rotate'])) { 
     
    342367     * @param array the result-array 
    343368     */ 
    344     function read_pages (&$c, &$pages, &$result) { 
     369    function read_pages(&$c, &$pages, &$result) { 
    345370        // Get the kids dictionary 
    346         $kids = $this->pdf_resolve_object ($c, $pages[1][1]['/Kids']); 
    347  
    348         if (!is_array($kids)) 
    349             $this->fpdi->Error("Cannot find /Kids in current /Page-Dictionary"); 
    350         foreach ($kids[1] as $v) { 
     371        $_kids = $this->pdf_resolve_object ($c, $pages[1][1]['/Kids']); 
     372         
     373        if (!is_array($_kids)) 
     374            $this->error('Cannot find /Kids in current /Page-Dictionary'); 
     375             
     376        if ($_kids[1][0] == PDF_TYPE_ARRAY) { 
     377            $kids = $_kids[1][1]; 
     378        } else { 
     379            $kids = $_kids[1]; 
     380        } 
     381         
     382        foreach ($kids as $v) { 
    351383            $pg = $this->pdf_resolve_object ($c, $v); 
    352384            if ($pg[1][1]['/Type'][1] === '/Pages') { 
    353385                // If one of the kids is an embedded 
    354386                // /Pages array, resolve it as well. 
    355                 $this->read_pages ($c, $pg, $result); 
     387                $this->read_pages($c, $pg, $result); 
    356388            } else { 
    357389                $result[] = $pg; 
     
    369401    function getPDFVersion() { 
    370402        parent::getPDFVersion(); 
    371          
    372         if (isset($this->fpdi->importVersion) && $this->pdfVersion > $this->fpdi->importVersion) { 
    373             $this->fpdi->importVersion = $this->pdfVersion; 
    374         } 
     403        $this->fpdi->setPDFVersion(max($this->fpdi->getPDFVersion(), $this->pdfVersion)); 
    375404    } 
    376405     
    377406} 
    378  
    379 ?> 
  • branches/version-2_5-dev/data/module/fpdf/pdf_context.php

    r18701 r19716  
    11<?php 
    22// 
    3 //  FPDI - Version 1.2 
     3//  FPDI - Version 1.4 
    44// 
    5 //    Copyright 2004-2007 Setasign - Jan Slabon 
     5//    Copyright 2004-2010 Setasign - Jan Slabon 
    66// 
    77//  Licensed under the Apache License, Version 2.0 (the "License"); 
     
    1818// 
    1919 
    20 class pdf_context { 
    21  
    22     var $file; 
    23     var $buffer; 
    24     var $offset; 
    25     var $length; 
    26  
    27     var $stack; 
    28  
    29     // Constructor 
    30  
    31     function pdf_context($f) { 
    32         $this->file = $f; 
    33         $this->reset(); 
    34     } 
    35  
    36     // Optionally move the file 
    37     // pointer to a new location 
    38     // and reset the buffered data 
    39  
    40     function reset($pos = null, $l = 100) { 
    41         if (!is_null ($pos)) { 
    42             fseek ($this->file, $pos); 
    43         } 
    44  
    45         $this->buffer = $l > 0 ? fread($this->file, $l) : ''; 
    46         $this->offset = 0; 
    47         $this->length = strlen($this->buffer); 
    48         $this->stack = array(); 
    49     } 
    50  
    51     // Make sure that there is at least one 
    52     // character beyond the current offset in 
    53     // the buffer to prevent the tokenizer 
    54     // from attempting to access data that does 
    55     // not exist 
    56  
    57     function ensure_content() { 
    58         if ($this->offset >= $this->length - 1) { 
    59             return $this->increase_length(); 
    60         } else { 
    61             return true; 
    62         } 
    63     } 
    64  
    65     // Forcefully read more data into the buffer 
    66  
    67     function increase_length($l=100) { 
    68         if (feof($this->file)) { 
    69             return false; 
    70         } else { 
    71             $this->buffer .= fread($this->file, $l); 
    72             $this->length = strlen($this->buffer); 
    73             return true; 
    74         } 
    75     } 
    76  
     20if (!class_exists('pdf_context', false)) { 
     21     
     22    class pdf_context { 
     23     
     24        /** 
     25         * Modi 
     26         * 
     27         * @var integer 0 = file | 1 = string 
     28         */ 
     29        var $_mode = 0; 
     30         
     31        var $file; 
     32        var $buffer; 
     33        var $offset; 
     34        var $length; 
     35     
     36        var $stack; 
     37     
     38        // Constructor 
     39     
     40        function pdf_context(&$f) { 
     41            $this->file =& $f; 
     42            if (is_string($this->file)) 
     43                $this->_mode = 1; 
     44            $this->reset(); 
     45        } 
     46     
     47        // Optionally move the file 
     48        // pointer to a new location 
     49        // and reset the buffered data 
     50     
     51        function reset($pos = null, $l = 100) { 
     52            if ($this->_mode == 0) { 
     53                if (!is_null ($pos)) { 
     54                    fseek ($this->file, $pos); 
     55                } 
     56         
     57                $this->buffer = $l > 0 ? fread($this->file, $l) : ''; 
     58                $this->length = strlen($this->buffer); 
     59                if ($this->length < $l) 
     60                    $this->increase_length($l - $this->length); 
     61            } else { 
     62                $this->buffer = $this->file; 
     63                $this->length = strlen($this->buffer); 
     64            } 
     65            $this->offset = 0; 
     66            $this->stack = array(); 
     67        } 
     68     
     69        // Make sure that there is at least one 
     70        // character beyond the current offset in 
     71        // the buffer to prevent the tokenizer 
     72        // from attempting to access data that does 
     73        // not exist 
     74     
     75        function ensure_content() { 
     76            if ($this->offset >= $this->length - 1) { 
     77                return $this->increase_length(); 
     78            } else { 
     79                return true; 
     80            } 
     81        } 
     82     
     83        // Forcefully read more data into the buffer 
     84     
     85        function increase_length($l = 100) { 
     86            if ($this->_mode == 0 && feof($this->file)) { 
     87                return false; 
     88            } else if ($this->_mode == 0) { 
     89                $totalLength = $this->length + $l; 
     90                do { 
     91                    $this->buffer .= fread($this->file, $totalLength-$this->length); 
     92                } while ((($this->length = strlen($this->buffer)) != $totalLength) && !feof($this->file)); 
     93                 
     94                return true; 
     95            } else { 
     96                return false; 
     97            } 
     98        } 
     99    } 
    77100} 
    78 ?> 
  • branches/version-2_5-dev/data/module/fpdf/pdf_parser.php

    r18701 r19716  
    11<?php 
    22// 
    3 //  FPDI - Version 1.2 
     3//  FPDI - Version 1.4 
    44// 
    5 //    Copyright 2004-2007 Setasign - Jan Slabon 
     5//    Copyright 2004-2010 Setasign - Jan Slabon 
    66// 
    77//  Licensed under the Apache License, Version 2.0 (the "License"); 
     
    4040if (!defined ('PDF_TYPE_STREAM')) 
    4141    define ('PDF_TYPE_STREAM', 10); 
     42if (!defined ('PDF_TYPE_BOOLEAN')) 
     43    define ('PDF_TYPE_BOOLEAN', 11); 
     44if (!defined ('PDF_TYPE_REAL')) 
     45    define ('PDF_TYPE_REAL', 12); 
     46     
     47require_once('pdf_context.php'); 
    4248 
    43 require_once("pdf_context.php"); 
    44 require_once("wrapper_functions.php"); 
    45  
    46 class pdf_parser { 
    47      
    48     /** 
    49      * Filename 
    50      * @var string 
    51      */ 
    52     var $filename; 
    53      
    54     /** 
    55      * File resource 
    56      * @var resource 
    57      */ 
    58     var $f; 
    59      
    60     /** 
    61      * PDF Context 
    62      * @var object pdf_context-Instance 
    63      */ 
    64     var $c; 
    65      
    66     /** 
    67      * xref-Data 
    68      * @var array 
    69      */ 
    70     var $xref; 
    71  
    72     /** 
    73      * root-Object 
    74      * @var array 
    75      */ 
    76     var $root; 
    77      
    78      
    79     /** 
    80      * Constructor 
    81      * 
    82      * @param string $filename  Source-Filename 
    83      */ 
    84     function pdf_parser($filename) { 
    85         $this->filename = $filename; 
    86          
    87         $this->f = @fopen($this->filename, "rb"); 
    88  
    89         if (!$this->f) 
    90             $this->error(sprintf("Cannot open %s !", $filename)); 
    91  
    92         $this->getPDFVersion(); 
    93  
    94         $this->c =& new pdf_context($this->f); 
    95         // Read xref-Data 
    96         $this->pdf_read_xref($this->xref, $this->pdf_find_xref()); 
    97  
    98         // Check for Encryption 
    99         $this->getEncryption(); 
    100  
    101         // Read root 
    102         $this->pdf_read_root(); 
    103     } 
    104      
    105     /** 
    106      * Close the opened file 
    107      */ 
    108     function closeFile() { 
    109         if (isset($this->f)) { 
    110             fclose($this->f);    
    111             unset($this->f); 
    112         }    
    113     } 
    114      
    115     /** 
    116      * Print Error and die 
    117      * 
    118      * @param string $msg  Error-Message 
    119      */ 
    120     function error($msg) { 
    121         die("<b>PDF-Parser Error:</b> ".$msg);   
    122     } 
    123      
    124     /** 
    125      * Check Trailer for Encryption 
    126      */ 
    127     function getEncryption() { 
    128         if (isset($this->xref['trailer'][1]['/Encrypt'])) { 
    129             $this->error("File is encrypted!"); 
    130         } 
    131     } 
    132      
    133     /** 
    134      * Find/Return /Root 
    135      * 
    136      * @return array 
    137      */ 
    138     function pdf_find_root() { 
    139         if ($this->xref['trailer'][1]['/Root'][0] != PDF_TYPE_OBJREF) { 
    140             $this->error("Wrong Type of Root-Element! Must be an indirect reference"); 
    141         } 
    142         return $this->xref['trailer'][1]['/Root']; 
    143     } 
    144  
    145     /** 
    146      * Read the /Root 
    147      */ 
    148     function pdf_read_root() { 
    149         // read root 
    150         $this->root = $this->pdf_resolve_object($this->c, $this->pdf_find_root()); 
    151     } 
    152      
    153     /** 
    154      * Get PDF-Version 
    155      * 
    156      * And reset the PDF Version used in FPDI if needed 
    157      */ 
    158     function getPDFVersion() { 
    159         fseek($this->f, 0); 
    160         preg_match("/\d\.\d/",fread($this->f,16),$m); 
    161         $this->pdfVersion = $m[0]; 
    162     } 
    163      
    164     /** 
    165      * Find the xref-Table 
    166      */ 
    167     function pdf_find_xref() { 
    168         fseek ($this->f, -min(filesize($this->filename),1500), SEEK_END); 
    169         $data = fread($this->f, 1500); 
    170          
    171         $pos = strlen($data) - strpos(strrev($data), strrev('startxref'));  
    172         $data = substr($data, $pos); 
    173          
    174         if (!preg_match('/\s*(\d+).*$/s', $data, $matches)) { 
    175             $this->error("Unable to find pointer to xref table"); 
    176         } 
    177  
    178         return (int) $matches[1]; 
    179     } 
    180  
    181     /** 
    182      * Read xref-table 
    183      * 
    184      * @param array $result Array of xref-table 
    185      * @param integer $offset of xref-table 
    186      * @param integer $start start-position in xref-table 
    187      * @param integer $end end-position in xref-table 
    188      */ 
    189     function pdf_read_xref(&$result, $offset, $start = null, $end = null) { 
    190         if (is_null ($start) || is_null ($end)) { 
    191             fseek($this->f, $o_pos = $offset); 
    192             $data = trim(fgets($this->f,1024)); 
    193                          
    194             if (strlen($data) == 0)  
    195                 $data = trim(fgets($this->f,1024)); 
    196                      
    197             if ($data !== 'xref') { 
    198                 fseek($this->f, $o_pos); 
    199                 $data = trim(_fgets($this->f, true)); 
    200                 if ($data !== 'xref') { 
    201                     if (preg_match('/(.*xref)(.*)/m', $data, $m)) { // xref 0 128 - in one line 
    202                         fseek($this->f, $o_pos+strlen($m[1]));                       
    203                     } elseif (preg_match('/(x|r|e|f)+/', $data, $m)) { // correct invalid xref-pointer 
    204                         $tmpOffset = $offset-4+strlen($m[0]); 
    205                         $this->pdf_read_xref($result, $tmpOffset, $start, $end); 
    206                         return; 
    207                     } else { 
    208                         $this->error("Unable to find xref table - Maybe a Problem with 'auto_detect_line_endings'"); 
    209                     } 
    210                 } 
    211             } 
    212  
    213             $o_pos = ftell($this->f); 
    214             $data = explode(' ', trim(fgets($this->f,1024))); 
    215             if (count($data) != 2) { 
    216                 fseek($this->f, $o_pos); 
    217                 $data = explode(' ', trim(_fgets($this->f, true))); 
    218              
    219                 if (count($data) != 2) { 
    220                     if (count($data) > 2) { // no lineending 
    221                         $n_pos = $o_pos+strlen($data[0])+strlen($data[1])+2; 
    222                         fseek($this->f, $n_pos); 
    223                     } else { 
    224                         $this->error("Unexpected header in xref table"); 
    225                     } 
    226                 } 
     49if (!class_exists('pdf_parser', false)) { 
     50     
     51    class pdf_parser { 
     52         
     53        /** 
     54         * Filename 
     55         * @var string 
     56         */ 
     57        var $filename; 
     58         
     59        /** 
     60         * File resource 
     61         * @var resource 
     62         */ 
     63        var $f; 
     64         
     65        /** 
     66         * PDF Context 
     67         * @var object pdf_context-Instance 
     68         */ 
     69        var $c; 
     70         
     71        /** 
     72         * xref-Data 
     73         * @var array 
     74         */ 
     75        var $xref; 
     76     
     77        /** 
     78         * root-Object 
     79         * @var array 
     80         */ 
     81        var $root; 
     82         
     83        /** 
     84         * PDF version of the loaded document 
     85         * @var string 
     86         */ 
     87        var $pdfVersion; 
     88         
     89        /** 
     90         * For reading encrypted documents and xref/objectstreams are in use 
     91         * 
     92         * @var boolean 
     93         */ 
     94        var $readPlain = true; 
     95         
     96        /** 
     97         * Constructor 
     98         * 
     99         * @param string $filename  Source-Filename 
     100         */ 
     101        function pdf_parser($filename) { 
     102            $this->filename = $filename; 
     103             
     104            $this->f = @fopen($this->filename, 'rb'); 
     105     
     106            if (!$this->f) 
     107                $this->error(sprintf('Cannot open %s !', $filename)); 
     108     
     109            $this->getPDFVersion(); 
     110     
     111            $this->c = new pdf_context($this->f); 
     112             
     113            // Read xref-Data 
     114            $this->xref = array(); 
     115            $this->pdf_read_xref($this->xref, $this->pdf_find_xref()); 
     116             
     117            // Check for Encryption 
     118            $this->getEncryption(); 
     119     
     120            // Read root 
     121            $this->pdf_read_root(); 
     122        } 
     123         
     124        /** 
     125         * Close the opened file 
     126         */ 
     127        function closeFile() { 
     128            if (isset($this->f) && is_resource($this->f)) { 
     129                fclose($this->f);    
     130                unset($this->f); 
     131            }    
     132        } 
     133         
     134        /** 
     135         * Print Error and die 
     136         * 
     137         * @param string $msg  Error-Message 
     138         */ 
     139        function error($msg) { 
     140            die('<b>PDF-Parser Error:</b> '.$msg);   
     141        } 
     142         
     143        /** 
     144         * Check Trailer for Encryption 
     145         */ 
     146        function getEncryption() { 
     147            if (isset($this->xref['trailer'][1]['/Encrypt'])) { 
     148                $this->error('File is encrypted!'); 
    227149            } 
    228             $start = $data[0]; 
    229             $end = $start + $data[1]; 
    230         } 
    231  
    232         if (!isset($result['xref_location'])) { 
    233             $result['xref_location'] = $offset; 
    234         } 
    235  
    236         if (!isset($result['max_object']) || $end > $result['max_object']) { 
    237             $result['max_object'] = $end; 
    238         } 
    239  
    240         for (; $start < $end; $start++) { 
    241             $data = ltrim(fread($this->f, 20)); // Spezifications says: 20 bytes including newlines 
    242             $offset = substr($data, 0, 10); 
    243             $generation = substr($data, 11, 5); 
    244  
    245             if (!isset ($result['xref'][$start][(int) $generation])) { 
    246                 $result['xref'][$start][(int) $generation] = (int) $offset; 
    247             } 
    248         } 
    249  
    250         $o_pos = ftell($this->f); 
    251         $data = fgets($this->f,1024); 
    252         if (strlen(trim($data)) == 0)  
    253             $data = fgets($this->f, 1024); 
    254          
    255         if (preg_match("/trailer/",$data)) { 
    256             if (preg_match("/(.*trailer[ \n\r]*)/",$data,$m)) { 
    257                 fseek($this->f, $o_pos+strlen($m[1])); 
    258             } 
    259              
    260             $c =&  new pdf_context($this->f); 
     150        } 
     151         
     152        /** 
     153         * Find/Return /Root 
     154         * 
     155         * @return array 
     156         */ 
     157        function pdf_find_root() { 
     158            if ($this->xref['trailer'][1]['/Root'][0] != PDF_TYPE_OBJREF) { 
     159                $this->error('Wrong Type of Root-Element! Must be an indirect reference'); 
     160            } 
     161             
     162            return $this->xref['trailer'][1]['/Root']; 
     163        } 
     164     
     165        /** 
     166         * Read the /Root 
     167         */ 
     168        function pdf_read_root() { 
     169            // read root 
     170            $this->root = $this->pdf_resolve_object($this->c, $this->pdf_find_root()); 
     171        } 
     172         
     173        /** 
     174         * Get PDF-Version 
     175         * 
     176         * And reset the PDF Version used in FPDI if needed 
     177         */ 
     178        function getPDFVersion() { 
     179            fseek($this->f, 0); 
     180            preg_match('/\d\.\d/',fread($this->f,16),$m); 
     181            if (isset($m[0])) 
     182                $this->pdfVersion = $m[0]; 
     183            return $this->pdfVersion; 
     184        } 
     185         
     186        /** 
     187         * Find the xref-Table 
     188         */ 
     189        function pdf_find_xref() { 
     190            $toRead = 1500; 
     191                     
     192            $stat = fseek ($this->f, -$toRead, SEEK_END); 
     193            if ($stat === -1) { 
     194                fseek ($this->f, 0); 
     195            } 
     196            $data = fread($this->f, $toRead); 
     197             
     198            $pos = strlen($data) - strpos(strrev($data), strrev('startxref'));  
     199            $data = substr($data, $pos); 
     200             
     201            if (!preg_match('/\s*(\d+).*$/s', $data, $matches)) { 
     202                $this->error('Unable to find pointer to xref table'); 
     203            } 
     204     
     205            return (int) $matches[1]; 
     206        } 
     207     
     208        /** 
     209         * Read xref-table 
     210         * 
     211         * @param array $result Array of xref-table 
     212         * @param integer $offset of xref-table 
     213         */ 
     214        function pdf_read_xref(&$result, $offset) { 
     215            $o_pos = $offset-min(20, $offset); 
     216            fseek($this->f, $o_pos); // set some bytes backwards to fetch errorious docs 
     217                 
     218            $data = fread($this->f, 100); 
     219             
     220            $xrefPos = strrpos($data, 'xref'); 
     221     
     222            if ($xrefPos === false) { 
     223                fseek($this->f, $offset); 
     224                $c = new pdf_context($this->f); 
     225                $xrefStreamObjDec = $this->pdf_read_value($c); 
     226                 
     227                if (is_array($xrefStreamObjDec) && isset($xrefStreamObjDec[0]) && $xrefStreamObjDec[0] == PDF_TYPE_OBJDEC) { 
     228                    $this->error(sprintf('This document (%s) probably uses a compression technique which is not supported by the free parser shipped with FPDI.', $this->filename)); 
     229                } else {             
     230                    $this->error('Unable to find xref table.'); 
     231                } 
     232            } 
     233             
     234            if (!isset($result['xref_location'])) { 
     235                $result['xref_location'] = $o_pos+$xrefPos; 
     236                $result['max_object'] = 0; 
     237            } 
     238     
     239            $cylces = -1; 
     240            $bytesPerCycle = 100; 
     241             
     242            fseek($this->f, $o_pos = $o_pos+$xrefPos+4); // set the handle directly after the "xref"-keyword 
     243            $data = fread($this->f, $bytesPerCycle); 
     244             
     245            while (($trailerPos = strpos($data, 'trailer', max($bytesPerCycle*$cylces++, 0))) === false && !feof($this->f)) { 
     246                $data .= fread($this->f, $bytesPerCycle); 
     247            } 
     248             
     249            if ($trailerPos === false) { 
     250                $this->error('Trailer keyword not found after xref table'); 
     251            } 
     252             
     253            $data = substr($data, 0, $trailerPos); 
     254             
     255            // get Line-Ending 
     256            preg_match_all("/(\r\n|\n|\r)/", substr($data, 0, 100), $m); // check the first 100 bytes for linebreaks 
     257     
     258            $differentLineEndings = count(array_unique($m[0])); 
     259            if ($differentLineEndings > 1) { 
     260                $lines = preg_split("/(\r\n|\n|\r)/", $data, -1, PREG_SPLIT_NO_EMPTY); 
     261            } else { 
     262                $lines = explode($m[0][1], $data); 
     263            } 
     264             
     265            $data = $differentLineEndings = $m = null; 
     266            unset($data, $differentLineEndings, $m); 
     267             
     268            $linesCount = count($lines); 
     269             
     270            $start = 1; 
     271             
     272            for ($i = 0; $i < $linesCount; $i++) { 
     273                $line = trim($lines[$i]); 
     274                if ($line) { 
     275                    $pieces = explode(' ', $line); 
     276                    $c = count($pieces); 
     277                    switch($c) { 
     278                        case 2: 
     279                            $start = (int)$pieces[0]; 
     280                            $end   = $start+(int)$pieces[1]; 
     281                            if ($end > $result['max_object']) 
     282                                $result['max_object'] = $end; 
     283                            break; 
     284                        case 3: 
     285                            if (!isset($result['xref'][$start])) 
     286                                $result['xref'][$start] = array(); 
     287                             
     288                            if (!array_key_exists($gen = (int) $pieces[1], $result['xref'][$start])) { 
     289                                $result['xref'][$start][$gen] = $pieces[2] == 'n' ? (int) $pieces[0] : null; 
     290                            } 
     291                            $start++; 
     292                            break; 
     293                        default: 
     294                            $this->error('Unexpected data in xref table'); 
     295                    } 
     296                } 
     297            } 
     298             
     299            $lines = $pieces = $line = $start = $end = $gen = null; 
     300            unset($lines, $pieces, $line, $start, $end, $gen); 
     301             
     302            fseek($this->f, $o_pos+$trailerPos+7); 
     303             
     304            $c = new pdf_context($this->f); 
    261305            $trailer = $this->pdf_read_value($c); 
    262306             
     307            $c = null; 
     308            unset($c); 
     309             
     310            if (!isset($result['trailer'])) { 
     311                $result['trailer'] = $trailer;           
     312            } 
     313             
    263314            if (isset($trailer[1]['/Prev'])) { 
    264                 $this->pdf_read_xref($result, $trailer[1]['/Prev'][1]); 
    265                 $result['trailer'][1] = array_merge($result['trailer'][1], $trailer[1]); 
    266             } else { 
    267                 $result['trailer'] = $trailer; 
    268             } 
    269         } else { 
    270             $data = explode(' ', trim($data)); 
    271              
    272             if (count($data) != 2) { 
    273                 fseek($this->f, $o_pos); 
    274                 $data = explode(' ', trim (_fgets ($this->f, true))); 
    275  
    276                 if (count($data) != 2) { 
    277                     $this->error("Unexpected data in xref table"); 
     315                $this->pdf_read_xref($result, $trailer[1]['/Prev'][1]); 
     316            }  
     317             
     318            $trailer = null; 
     319            unset($trailer); 
     320             
     321            return true; 
     322        } 
     323         
     324        /** 
     325         * Reads an Value 
     326         * 
     327         * @param object $c pdf_context 
     328         * @param string $token a Token 
     329         * @return mixed 
     330         */ 
     331        function pdf_read_value(&$c, $token = null) { 
     332            if (is_null($token)) { 
     333                $token = $this->pdf_read_token($c); 
     334            } 
     335             
     336            if ($token === false) { 
     337                return false; 
     338            } 
     339     
     340            switch ($token) { 
     341                case    '<': 
     342                    // This is a hex string. 
     343                    // Read the value, then the terminator 
     344     
     345                    $pos = $c->offset; 
     346     
     347                    while(1) { 
     348     
     349                        $match = strpos ($c->buffer, '>', $pos); 
     350                     
     351                        // If you can't find it, try 
     352                        // reading more data from the stream 
     353     
     354                        if ($match === false) { 
     355                            if (!$c->increase_length()) { 
     356                                return false; 
     357                            } else { 
     358                                continue; 
     359                            } 
     360                        } 
     361     
     362                        $result = substr ($c->buffer, $c->offset, $match - $c->offset); 
     363                        $c->offset = $match + 1; 
     364                         
     365                        return array (PDF_TYPE_HEX, $result); 
     366                    } 
     367                     
     368                    break; 
     369                case    '<<': 
     370                    // This is a dictionary. 
     371     
     372                    $result = array(); 
     373     
     374                    // Recurse into this function until we reach 
     375                    // the end of the dictionary. 
     376                    while (($key = $this->pdf_read_token($c)) !== '>>') { 
     377                        if ($key === false) { 
     378                            return false; 
     379                        } 
     380                         
     381                        if (($value =   $this->pdf_read_value($c)) === false) { 
     382                            return false; 
     383                        } 
     384                         
     385                        // Catch missing value 
     386                        if ($value[0] == PDF_TYPE_TOKEN && $value[1] == '>>') { 
     387                            $result[$key] = array(PDF_TYPE_NULL); 
     388                            break; 
     389                        } 
     390                         
     391                        $result[$key] = $value; 
     392                    } 
     393                     
     394                    return array (PDF_TYPE_DICTIONARY, $result); 
     395     
     396                case    '[': 
     397                    // This is an array. 
     398     
     399                    $result = array(); 
     400     
     401                    // Recurse into this function until we reach 
     402                    // the end of the array. 
     403                    while (($token = $this->pdf_read_token($c)) !== ']') { 
     404                        if ($token === false) { 
     405                            return false; 
     406                        } 
     407                         
     408                        if (($value = $this->pdf_read_value($c, $token)) === false) { 
     409                            return false; 
     410                        } 
     411                         
     412                        $result[] = $value; 
     413                    } 
     414                     
     415                    return array (PDF_TYPE_ARRAY, $result); 
     416     
     417                case    '('     : 
     418                    // This is a string 
     419                    $pos = $c->offset; 
     420                     
     421                    $openBrackets = 1; 
     422                    do { 
     423                        for (; $openBrackets != 0 && $pos < $c->length; $pos++) { 
     424                            switch (ord($c->buffer[$pos])) { 
     425                                case 0x28: // '(' 
     426                                    $openBrackets++; 
     427                                    break; 
     428                                case 0x29: // ')' 
     429                                    $openBrackets--; 
     430                                    break; 
     431                                case 0x5C: // backslash 
     432                                    $pos++; 
     433                            } 
     434                        } 
     435                    } while($openBrackets != 0 && $c->increase_length()); 
     436                     
     437                    $result = substr($c->buffer, $c->offset, $pos - $c->offset - 1); 
     438                    $c->offset = $pos; 
     439                     
     440                    return array (PDF_TYPE_STRING, $result); 
     441     
     442                case 'stream': 
     443                    $o_pos = ftell($c->file)-strlen($c->buffer); 
     444                    $o_offset = $c->offset; 
     445                     
     446                    $c->reset($startpos = $o_pos + $o_offset); 
     447                     
     448                    $e = 0; // ensure line breaks in front of the stream 
     449                    if ($c->buffer[0] == chr(10) || $c->buffer[0] == chr(13)) 
     450                        $e++; 
     451                    if ($c->buffer[1] == chr(10) && $c->buffer[0] != chr(10)) 
     452                        $e++; 
     453                     
     454                    if ($this->actual_obj[1][1]['/Length'][0] == PDF_TYPE_OBJREF) { 
     455                        $tmp_c = new pdf_context($this->f); 
     456                        $tmp_length = $this->pdf_resolve_object($tmp_c, $this->actual_obj[1][1]['/Length']); 
     457                        $length = $tmp_length[1][1]; 
     458                    } else { 
     459                        $length = $this->actual_obj[1][1]['/Length'][1];     
     460                    } 
     461                         
     462                    if ($length > 0) { 
     463                        $c->reset($startpos+$e,$length); 
     464                        $v = $c->buffer; 
     465                    } else { 
     466                        $v = '';    
     467                    } 
     468                    $c->reset($startpos+$e+$length+9); // 9 = strlen("endstream") 
     469                     
     470                    return array(PDF_TYPE_STREAM, $v); 
     471                     
     472                default : 
     473                    if (is_numeric ($token)) { 
     474                        // A numeric token. Make sure that 
     475                        // it is not part of something else. 
     476                        if (($tok2 = $this->pdf_read_token ($c)) !== false) { 
     477                            if (is_numeric ($tok2)) { 
     478     
     479                                // Two numeric tokens in a row. 
     480                                // In this case, we're probably in 
     481                                // front of either an object reference 
     482                                // or an object specification. 
     483                                // Determine the case and return the data 
     484                                if (($tok3 = $this->pdf_read_token ($c)) !== false) { 
     485                                    switch ($tok3) { 
     486                                        case    'obj'   : 
     487                                            return array (PDF_TYPE_OBJDEC, (int) $token, (int) $tok2); 
     488                                        case    'R'     : 
     489                                            return array (PDF_TYPE_OBJREF, (int) $token, (int) $tok2); 
     490                                    } 
     491                                    // If we get to this point, that numeric value up 
     492                                    // there was just a numeric value. Push the extra 
     493                                    // tokens back into the stack and return the value. 
     494                                    array_push ($c->stack, $tok3); 
     495                                } 
     496                            } 
     497     
     498                            array_push ($c->stack, $tok2); 
     499                        } 
     500     
     501                        if ($token === (string)((int)$token)) 
     502                            return array (PDF_TYPE_NUMERIC, (int)$token); 
     503                        else  
     504                            return array (PDF_TYPE_REAL, (float)$token); 
     505                    } else if ($token == 'true' || $token == 'false') { 
     506                        return array (PDF_TYPE_BOOLEAN, $token == 'true'); 
     507                    } else if ($token == 'null') { 
     508                       return array (PDF_TYPE_NULL); 
     509                    } else { 
     510                        // Just a token. Return it. 
     511                        return array (PDF_TYPE_TOKEN, $token); 
     512                    } 
     513             } 
     514        } 
     515         
     516        /** 
     517         * Resolve an object 
     518         * 
     519         * @param object $c pdf_context 
     520         * @param array $obj_spec The object-data 
     521         * @param boolean $encapsulate Must set to true, cause the parsing and fpdi use this method only without this para 
     522         */ 
     523        function pdf_resolve_object(&$c, $obj_spec, $encapsulate = true) { 
     524            // Exit if we get invalid data 
     525            if (!is_array($obj_spec)) { 
     526                $ret = false; 
     527                return $ret; 
     528            } 
     529     
     530            if ($obj_spec[0] == PDF_TYPE_OBJREF) { 
     531     
     532                // This is a reference, resolve it 
     533                if (isset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]])) { 
     534     
     535                    // Save current file position 
     536                    // This is needed if you want to resolve 
     537                    // references while you're reading another object 
     538                    // (e.g.: if you need to determine the length 
     539                    // of a stream) 
     540     
     541                    $old_pos = ftell($c->file); 
     542     
     543                    // Reposition the file pointer and 
     544                    // load the object header. 
     545                     
     546                    $c->reset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]]); 
     547     
     548                    $header = $this->pdf_read_value($c); 
     549     
     550                    if ($header[0] != PDF_TYPE_OBJDEC || $header[1] != $obj_spec[1] || $header[2] != $obj_spec[2]) { 
     551                        $toSearchFor = $obj_spec[1].' '.$obj_spec[2].' obj'; 
     552                        if (preg_match('/'.$toSearchFor.'/', $c->buffer)) { 
     553                            $c->offset = strpos($c->buffer, $toSearchFor) + strlen($toSearchFor); 
     554                            // reset stack 
     555                            $c->stack = array(); 
     556                        } else { 
     557                            $this->error("Unable to find object ({$obj_spec[1]}, {$obj_spec[2]}) at expected location"); 
     558                        } 
     559                    } 
     560     
     561                    // If we're being asked to store all the information 
     562                    // about the object, we add the object ID and generation 
     563                    // number for later use 
     564                    $result = array(); 
     565                    $this->actual_obj =& $result; 
     566                    if ($encapsulate) { 
     567                        $result = array ( 
     568                            PDF_TYPE_OBJECT, 
     569                            'obj' => $obj_spec[1], 
     570                            'gen' => $obj_spec[2] 
     571                        ); 
     572                    }  
     573     
     574                    // Now simply read the object data until 
     575                    // we encounter an end-of-object marker 
     576                    while(1) { 
     577                        $value = $this->pdf_read_value($c); 
     578                        if ($value === false || count($result) > 4) { 
     579                            // in this case the parser coudn't find an endobj so we break here 
     580                            break; 
     581                        } 
     582     
     583                        if ($value[0] == PDF_TYPE_TOKEN && $value[1] === 'endobj') { 
     584                            break; 
     585                        } 
     586     
     587                        $result[] = $value; 
     588                    } 
     589     
     590                    $c->reset($old_pos); 
     591     
     592                    if (isset($result[2][0]) && $result[2][0] == PDF_TYPE_STREAM) { 
     593                        $result[0] = PDF_TYPE_STREAM; 
     594                    } 
     595     
     596                    return $result; 
    278597                } 
    279             } 
    280              
    281             $this->pdf_read_xref($result, null, (int) $data[0], (int) $data[0] + (int) $data[1]); 
    282         } 
     598            } else { 
     599                return $obj_spec; 
     600            } 
     601        } 
     602     
     603         
     604         
     605        /** 
     606         * Reads a token from the file 
     607         * 
     608         * @param object $c pdf_context 
     609         * @return mixed 
     610         */ 
     611        function pdf_read_token(&$c) 
     612        { 
     613            // If there is a token available 
     614            // on the stack, pop it out and 
     615            // return it. 
     616     
     617            if (count($c->stack)) { 
     618                return array_pop($c->stack); 
     619            } 
     620     
     621            // Strip away any whitespace 
     622     
     623            do { 
     624                if (!$c->ensure_content()) { 
     625                    return false; 
     626                } 
     627                $c->offset += strspn($c->buffer, " \n\r\t", $c->offset); 
     628            } while ($c->offset >= $c->length - 1); 
     629     
     630            // Get the first character in the stream 
     631     
     632            $char = $c->buffer[$c->offset++]; 
     633     
     634            switch ($char) { 
     635     
     636                case '[': 
     637                case ']': 
     638                case '(': 
     639                case ')': 
     640                 
     641                    // This is either an array or literal string 
     642                    // delimiter, Return it 
     643     
     644                    return $char; 
     645     
     646                case '<': 
     647                case '>': 
     648     
     649                    // This could either be a hex string or 
     650                    // dictionary delimiter. Determine the 
     651                    // appropriate case and return the token 
     652     
     653                    if ($c->buffer[$c->offset] == $char) { 
     654                        if (!$c->ensure_content()) { 
     655                            return false; 
     656                        } 
     657                        $c->offset++; 
     658                        return $char . $char; 
     659                    } else { 
     660                        return $char; 
     661                    } 
     662     
     663                case '%': 
     664                     
     665                    // This is a comment - jump over it! 
     666                     
     667                    $pos = $c->offset; 
     668                    while(1) { 
     669                        $match = preg_match("/(\r\n|\r|\n)/", $c->buffer, $m, PREG_OFFSET_CAPTURE, $pos); 
     670                        if ($match === 0) { 
     671                            if (!$c->increase_length()) { 
     672                                return false; 
     673                            } else { 
     674                                continue; 
     675                            } 
     676                        } 
     677     
     678                        $c->offset = $m[0][1]+strlen($m[0][0]); 
     679                         
     680                        return $this->pdf_read_token($c); 
     681                    } 
     682                     
     683                default: 
     684     
     685                    // This is "another" type of token (probably 
     686                    // a dictionary entry or a numeric value) 
     687                    // Find the end and return it. 
     688     
     689                    if (!$c->ensure_content()) { 
     690                        return false; 
     691                    } 
     692     
     693                    while(1) { 
     694     
     695                        // Determine the length of the token 
     696     
     697                        $pos = strcspn($c->buffer, " %[]<>()\r\n\t/", $c->offset); 
     698                         
     699                        if ($c->offset + $pos <= $c->length - 1) { 
     700                            break; 
     701                        } else { 
     702                            // If the script reaches this point, 
     703                            // the token may span beyond the end 
     704                            // of the current buffer. Therefore, 
     705                            // we increase the size of the buffer 
     706                            // and try again--just to be safe. 
     707     
     708                            $c->increase_length(); 
     709                        } 
     710                    } 
     711     
     712                    $result = substr($c->buffer, $c->offset - 1, $pos + 1); 
     713     
     714                    $c->offset += $pos; 
     715                    return $result; 
     716            } 
     717        } 
    283718    } 
    284  
    285  
    286     /** 
    287      * Reads an Value 
    288      * 
    289      * @param object $c pdf_context 
    290      * @param string $token a Token 
    291      * @return mixed 
    292      */ 
    293     function pdf_read_value(&$c, $token = null) { 
    294         if (is_null($token)) { 
    295             $token = $this->pdf_read_token($c); 
    296         } 
    297          
    298         if ($token === false) { 
    299             return false; 
    300         } 
    301  
    302         switch ($token) { 
    303             case    '<': 
    304                 // This is a hex string. 
    305                 // Read the value, then the terminator 
    306  
    307                 $pos = $c->offset; 
    308  
    309                 while(1) { 
    310  
    311                     $match = strpos ($c->buffer, '>', $pos); 
    312                  
    313                     // If you can't find it, try 
    314                     // reading more data from the stream 
    315  
    316                     if ($match === false) { 
    317                         if (!$c->increase_length()) { 
    318                             return false; 
    319                         } else { 
    320                             continue; 
    321                         } 
    322                     } 
    323  
    324                     $result = substr ($c->buffer, $c->offset, $match - $c->offset); 
    325                     $c->offset = $match+1; 
    326                      
    327                     return array (PDF_TYPE_HEX, $result); 
    328                 } 
    329                  
    330                 break; 
    331             case    '<<': 
    332                 // This is a dictionary. 
    333  
    334                 $result = array(); 
    335  
    336                 // Recurse into this function until we reach 
    337                 // the end of the dictionary. 
    338                 while (($key = $this->pdf_read_token($c)) !== '>>') { 
    339                     if ($key === false) { 
    340                         return false; 
    341                     } 
    342                      
    343                     if (($value =   $this->pdf_read_value($c)) === false) { 
    344                         return false; 
    345                     } 
    346                     $result[$key] = $value; 
    347                 } 
    348                  
    349                 return array (PDF_TYPE_DICTIONARY, $result); 
    350  
    351             case    '[': 
    352                 // This is an array. 
    353  
    354                 $result = array(); 
    355  
    356                 // Recurse into this function until we reach 
    357                 // the end of the array. 
    358                 while (($token = $this->pdf_read_token($c)) !== ']') { 
    359                     if ($token === false) { 
    360                         return false; 
    361                     } 
    362                      
    363                     if (($value = $this->pdf_read_value($c, $token)) === false) { 
    364                         return false; 
    365                     } 
    366                      
    367                     $result[] = $value; 
    368                 } 
    369                  
    370                 return array (PDF_TYPE_ARRAY, $result); 
    371  
    372             case    '('     : 
    373                 // This is a string 
    374  
    375                 $pos = $c->offset; 
    376  
    377                 while(1) { 
    378  
    379                     // Start by finding the next closed 
    380                     // parenthesis 
    381  
    382                     $match = strpos ($c->buffer, ')', $pos); 
    383  
    384                     // If you can't find it, try 
    385                     // reading more data from the stream 
    386  
    387                     if ($match === false) { 
    388                         if (!$c->increase_length()) { 
    389                             return false; 
    390                         } else { 
    391                             continue; 
    392                         } 
    393                     } 
    394  
    395                     // Make sure that there is no backslash 
    396                     // before the parenthesis. If there is, 
    397                     // move on. Otherwise, return the string. 
    398                     $esc = preg_match('/([\\\\]+)$/', $tmpresult = substr($c->buffer, $c->offset, $match - $c->offset), $m); 
    399                      
    400                     if ($esc === 0 || strlen($m[1]) % 2 == 0) { 
    401                         $result = $tmpresult; 
    402                         $c->offset = $match + 1; 
    403                         return array (PDF_TYPE_STRING, $result); 
    404                     } else { 
    405                         $pos = $match + 1; 
    406  
    407                         if ($pos > $c->offset + $c->length) { 
    408                             $c->increase_length(); 
    409                         } 
    410                     }                    
    411                 } 
    412  
    413             case "stream": 
    414                 $o_pos = ftell($c->file)-strlen($c->buffer); 
    415                 $o_offset = $c->offset; 
    416                  
    417                 $c->reset($startpos = $o_pos + $o_offset); 
    418                  
    419                 $e = 0; // ensure line breaks in front of the stream 
    420                 if ($c->buffer[0] == chr(10) || $c->buffer[0] == chr(13)) 
    421                     $e++; 
    422                 if ($c->buffer[1] == chr(10) && $c->buffer[0] != chr(10)) 
    423                     $e++; 
    424                  
    425                 if ($this->actual_obj[1][1]['/Length'][0] == PDF_TYPE_OBJREF) { 
    426                     $tmp_c =& new pdf_context($this->f); 
    427                     $tmp_length = $this->pdf_resolve_object($tmp_c,$this->actual_obj[1][1]['/Length']); 
    428                     $length = $tmp_length[1][1]; 
    429                 } else { 
    430                     $length = $this->actual_obj[1][1]['/Length'][1];     
    431                 } 
    432                  
    433                 if ($length > 0) { 
    434                     $c->reset($startpos+$e,$length); 
    435                     $v = $c->buffer; 
    436                 } else { 
    437                     $v = '';    
    438                 } 
    439                 $c->reset($startpos+$e+$length+9); // 9 = strlen("endstream") 
    440                  
    441                 return array(PDF_TYPE_STREAM, $v); 
    442                  
    443             default : 
    444                 if (is_numeric ($token)) { 
    445                     // A numeric token. Make sure that 
    446                     // it is not part of something else. 
    447                     if (($tok2 = $this->pdf_read_token ($c)) !== false) { 
    448                         if (is_numeric ($tok2)) { 
    449  
    450                             // Two numeric tokens in a row. 
    451                             // In this case, we're probably in 
    452                             // front of either an object reference 
    453                             // or an object specification. 
    454                             // Determine the case and return the data 
    455                             if (($tok3 = $this->pdf_read_token ($c)) !== false) { 
    456                                 switch ($tok3) { 
    457                                     case    'obj'   : 
    458                                         return array (PDF_TYPE_OBJDEC, (int) $token, (int) $tok2); 
    459                                     case    'R'     : 
    460                                         return array (PDF_TYPE_OBJREF, (int) $token, (int) $tok2); 
    461                                 } 
    462                                 // If we get to this point, that numeric value up 
    463                                 // there was just a numeric value. Push the extra 
    464                                 // tokens back into the stack and return the value. 
    465                                 array_push ($c->stack, $tok3); 
    466                             } 
    467                         } 
    468  
    469                         array_push ($c->stack, $tok2); 
    470                     } 
    471  
    472                     return array (PDF_TYPE_NUMERIC, $token); 
    473                 } else { 
    474  
    475                     // Just a token. Return it. 
    476                     return array (PDF_TYPE_TOKEN, $token); 
    477                 } 
    478  
    479          } 
    480     } 
    481      
    482     /** 
    483      * Resolve an object 
    484      * 
    485      * @param object $c pdf_context 
    486      * @param array $obj_spec The object-data 
    487      * @param boolean $encapsulate Must set to true, cause the parsing and fpdi use this method only without this para 
    488      */ 
    489     function pdf_resolve_object(&$c, $obj_spec, $encapsulate = true) { 
    490         // Exit if we get invalid data 
    491         if (!is_array($obj_spec)) { 
    492             return false; 
    493         } 
    494  
    495         if ($obj_spec[0] == PDF_TYPE_OBJREF) { 
    496  
    497             // This is a reference, resolve it 
    498             if (isset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]])) { 
    499  
    500                 // Save current file position 
    501                 // This is needed if you want to resolve 
    502                 // references while you're reading another object 
    503                 // (e.g.: if you need to determine the length 
    504                 // of a stream) 
    505  
    506                 $old_pos = ftell($c->file); 
    507  
    508                 // Reposition the file pointer and 
    509                 // load the object header. 
    510                  
    511                 $c->reset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]]); 
    512  
    513                 $header = $this->pdf_read_value($c,null,true); 
    514  
    515                 if ($header[0] != PDF_TYPE_OBJDEC || $header[1] != $obj_spec[1] || $header[2] != $obj_spec[2]) { 
    516                     $this->error("Unable to find object ({$obj_spec[1]}, {$obj_spec[2]}) at expected location"); 
    517                 } 
    518  
    519                 // If we're being asked to store all the information 
    520                 // about the object, we add the object ID and generation 
    521                 // number for later use 
    522                 $this->actual_obj =& $result; 
    523                 if ($encapsulate) { 
    524                     $result = array ( 
    525                         PDF_TYPE_OBJECT, 
    526                         'obj' => $obj_spec[1], 
    527                         'gen' => $obj_spec[2] 
    528                     ); 
    529                 } else { 
    530                     $result = array(); 
    531                 } 
    532  
    533                 // Now simply read the object data until 
    534                 // we encounter an end-of-object marker 
    535                 while(1) { 
    536                     $value = $this->pdf_read_value($c); 
    537                     if ($value === false || count($result) > 4) { 
    538                         // in this case the parser coudn't find an endobj so we break here 
    539                         break; 
    540                     } 
    541  
    542                     if ($value[0] == PDF_TYPE_TOKEN && $value[1] === 'endobj') { 
    543                         break; 
    544                     } 
    545  
    546                     $result[] = $value; 
    547                 } 
    548  
    549                 $c->reset($old_pos); 
    550  
    551                 if (isset($result[2][0]) && $result[2][0] == PDF_TYPE_STREAM) { 
    552                     $result[0] = PDF_TYPE_STREAM; 
    553                 } 
    554  
    555                 return $result; 
    556             } 
    557         } else { 
    558             return $obj_spec; 
    559         } 
    560     } 
    561  
    562      
    563      
    564     /** 
    565      * Reads a token from the file 
    566      * 
    567      * @param object $c pdf_context 
    568      * @return mixed 
    569      */ 
    570     function pdf_read_token(&$c) 
    571     { 
    572         // If there is a token available 
    573         // on the stack, pop it out and 
    574         // return it. 
    575  
    576         if (count($c->stack)) { 
    577             return array_pop($c->stack); 
    578         } 
    579  
    580         // Strip away any whitespace 
    581  
    582         do { 
    583             if (!$c->ensure_content()) { 
    584                 return false; 
    585             } 
    586             $c->offset += _strspn($c->buffer, " \n\r\t", $c->offset); 
    587         } while ($c->offset >= $c->length - 1); 
    588  
    589         // Get the first character in the stream 
    590  
    591         $char = $c->buffer[$c->offset++]; 
    592  
    593         switch ($char) { 
    594  
    595             case '['    : 
    596             case ']'    : 
    597             case '('    : 
    598             case ')'    : 
    599  
    600                 // This is either an array or literal string 
    601                 // delimiter, Return it 
    602  
    603                 return $char; 
    604  
    605             case '<'    : 
    606             case '>'    : 
    607  
    608                 // This could either be a hex string or 
    609                 // dictionary delimiter. Determine the 
    610                 // appropriate case and return the token 
    611  
    612                 if ($c->buffer[$c->offset] == $char) { 
    613                     if (!$c->ensure_content()) { 
    614                         return false; 
    615                     } 
    616                     $c->offset++; 
    617                     return $char . $char; 
    618                 } else { 
    619                     return $char; 
    620                 } 
    621  
    622             default     : 
    623  
    624                 // This is "another" type of token (probably 
    625                 // a dictionary entry or a numeric value) 
    626                 // Find the end and return it. 
    627  
    628                 if (!$c->ensure_content()) { 
    629                     return false; 
    630                 } 
    631  
    632                 while(1) { 
    633  
    634                     // Determine the length of the token 
    635  
    636                     $pos = _strcspn($c->buffer, " []<>()\r\n\t/", $c->offset); 
    637                     if ($c->offset + $pos <= $c->length - 1) { 
    638                         break; 
    639                     } else { 
    640                         // If the script reaches this point, 
    641                         // the token may span beyond the end 
    642                         // of the current buffer. Therefore, 
    643                         // we increase the size of the buffer 
    644                         // and try again--just to be safe. 
    645  
    646                         $c->increase_length(); 
    647                     } 
    648                 } 
    649  
    650                 $result = substr($c->buffer, $c->offset - 1, $pos + 1); 
    651  
    652                 $c->offset += $pos; 
    653                 return $result; 
    654         } 
    655     } 
    656  
    657      
    658719} 
    659  
    660 ?> 
Note: See TracChangeset for help on using the changeset viewer.