00001 <?php
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00134 require_once(dirname(__FILE__).'/config/tcpdf_config.php');
00135 
00136 
00137 
00141 require_once(dirname(__FILE__).'/unicode_data.php');
00142 
00146 require_once(dirname(__FILE__).'/htmlcolors.php');
00147 
00148 if (!class_exists('TCPDF', false)) {
00152     define('PDF_PRODUCER', 'TCPDF 4.6.008 (http://www.tcpdf.org)');
00153     
00163     class TCPDF {
00164         
00165         
00166 
00171         protected $page;
00172         
00177         protected $n;
00178 
00183         protected $offsets;
00184 
00189         protected $buffer;
00190 
00195         protected $pages = array();
00196 
00201         protected $state;
00202 
00207         protected $compress;
00208         
00213         protected $CurOrientation;
00214 
00219         protected $pagedim = array();
00220 
00225         protected $k;
00226 
00231         protected $fwPt;
00232 
00237         protected $fhPt;
00238 
00243         protected $wPt;
00244 
00249         protected $hPt;
00250 
00255         protected $w;
00256 
00261         protected $h;
00262 
00267         protected $lMargin;
00268 
00273         protected $tMargin;
00274 
00279         protected $rMargin;
00280 
00285         protected $bMargin;
00286 
00291         
00292         public $cMargin;
00293         
00298         protected $oldcMargin;
00299 
00304         protected $x;
00305 
00310         protected $y;
00311 
00316         protected $lasth;
00317 
00322         protected $LineWidth;
00323 
00328         protected $CoreFonts;
00329 
00334         protected $fonts = array();
00335 
00340         protected $FontFiles = array();
00341 
00346         protected $diffs = array();
00347 
00352         protected $images = array();
00353 
00358         protected $PageAnnots = array();
00359 
00364         protected $links = array();
00365 
00370         protected $FontFamily;
00371 
00376         protected $FontStyle;
00377         
00383         protected $FontAscent;
00384         
00390         protected $FontDescent;
00391 
00396         protected $underline;
00397 
00402         protected $CurrentFont;
00403 
00408         protected $FontSizePt;
00409 
00414         protected $FontSize;
00415 
00420         protected $DrawColor;
00421 
00426         protected $FillColor;
00427 
00432         protected $TextColor;
00433 
00438         protected $ColorFlag;
00439 
00444         protected $AutoPageBreak;
00445 
00450         protected $PageBreakTrigger;
00451 
00456         protected $InFooter = false;
00457 
00462         protected $ZoomMode;
00463 
00468         protected $LayoutMode;
00469 
00474         protected $title = '';
00475 
00480         protected $subject = '';
00481 
00486         protected $author = '';
00487 
00492         protected $keywords = '';
00493 
00498         protected $creator = '';
00499 
00504         protected $AliasNbPages = '{nb}';
00505         
00510         protected $AliasNumPage = '{pnb}';
00511         
00518         protected $img_rb_x;
00519 
00526         protected $img_rb_y;
00527 
00534         protected $imgscale = 1;
00535 
00542         protected $isunicode = false;
00543 
00549         protected $PDFVersion = '1.7';
00550         
00551         
00552         
00553         
00558         protected $header_margin;
00559         
00564         protected $footer_margin;
00565         
00571         protected $original_lMargin;
00572         
00578         protected $original_rMargin;
00579             
00584         protected $header_font;
00585         
00590         protected $footer_font;
00591         
00596         protected $l;
00597         
00602         protected $barcode = false;
00603         
00608         protected $print_header = true;
00609         
00614         protected $print_footer = true;
00615             
00620         protected $header_logo = '';
00621         
00626         protected $header_logo_width = 30;
00627         
00632         protected $header_title = '';
00633         
00638         protected $header_string = '';
00639         
00644         protected $default_table_columns = 4;
00645         
00646         
00647         
00648         
00653         protected $HREF = array();
00654         
00659         protected $fontlist = array();
00660         
00665         protected $fgcolor;
00666                         
00671         protected $listordered = array();
00672         
00677         protected $listcount = array();
00678         
00683         protected $listnum = 0;
00684         
00689         protected $listindent;
00690         
00695         protected $bgcolor;
00696         
00701         protected $tempfontsize = 10;
00702         
00707         protected $lispacer = '';
00708         
00714         protected $encoding = 'UTF-8';
00715         
00721         protected $internal_encoding;
00722         
00728         protected $rtl = false;
00729         
00735         protected $tmprtl = false;
00736         
00737         
00738         
00744         protected $encrypted;
00745         
00751         protected $Uvalue;
00752         
00758         protected $Ovalue;
00759         
00765         protected $Pvalue;
00766         
00772         protected $enc_obj_id;
00773         
00779         protected $last_rc4_key;
00780         
00786         protected $last_rc4_key_c;
00787         
00792         protected $padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
00793         
00798         protected $encryption_key;
00799         
00800         
00801         
00807         protected $outlines = array();
00808         
00814         protected $OutlineRoot;
00815         
00816         
00817         
00818         
00824         protected $javascript = '';
00825         
00831         protected $n_js;
00832 
00838         protected $linethrough;
00839 
00840         
00841         
00842 
00848         protected $ur;
00849 
00855         protected $ur_document;
00856 
00862         protected $ur_annots;
00863 
00869         protected $ur_form;
00870 
00876         protected $ur_signature;
00877 
00883         protected $dpi = 72;
00884         
00890         protected $newpagegroup = array();
00891         
00897         protected $pagegroups;
00898         
00904         protected $currpagegroup; 
00905         
00911         protected $visibility = 'all';
00912         
00918         protected $n_ocg_print;
00919         
00925         protected $n_ocg_view;
00926         
00932         protected $extgstates;
00933         
00939         protected $jpeg_quality;
00940         
00946         protected $cell_height_ratio = K_CELL_HEIGHT_RATIO;
00947         
00953         protected $viewer_preferences;
00954         
00960         protected $PageMode;
00961         
00967         protected $gradients = array();
00968         
00975         protected $intmrk = array();
00976         
00982         protected $footerpos = array();
00983         
00984         
00990         protected $footerlen = array();
00991         
00997         protected $newline = true;
00998         
01004         protected $endlinex = 0;
01005         
01011         protected $linestyleWidth = '';
01012         
01018         protected $linestyleCap = '0 J';
01019         
01025         protected $linestyleJoin = '0 j';
01026         
01032         protected $linestyleDash = '[] 0 d';
01033         
01039         protected $openMarkedContent = false;
01040         
01046         protected $htmlvspace = 0;
01047         
01053         protected $spot_colors = array();
01054         
01060         protected $lisymbol = '';
01061         
01067         protected $epsmarker = 'x#!#EPS#!#x';
01068         
01074         protected $transfmatrix = array();
01075         
01081         protected $booklet = false;
01082         
01088         protected $feps = 0.001;
01089         
01095         protected $tagvspaces = array();
01096         
01103         protected $customlistindent = -1;
01104         
01110         protected $opencell = true;
01111 
01117         protected $embeddedfiles = array();
01118 
01124         protected $premode = false;
01125 
01132         protected $transfmrk = array();
01133 
01139         protected $htmlLinkColorArray = array(0, 0, 255);
01140 
01146         protected $htmlLinkFontStyle = 'U';
01147 
01153         protected $numpages = 0;
01154 
01160         protected $pagelen = array();
01161 
01167         protected $numimages = 0;
01168 
01174         protected $imagekeys = array();
01175 
01181         protected $bufferlen = 0;
01182 
01188         protected $diskcache = false;
01189 
01195         protected $numfonts = 0;
01196 
01202         protected $fontkeys = array();
01203 
01209         protected $pageopen = array();
01210         
01216         protected $default_monospaced_font = 'courier';
01217 
01223         protected $objcopy;
01224 
01230         protected $cache_file_lenght = array();
01231 
01237         protected $thead = '';
01238 
01244         protected $theadMargin = '';
01245 
01251         protected $cache_UTF8StringToArray = array();
01252 
01258         protected $cache_maxsize_UTF8StringToArray = 8;
01259 
01265         protected $cache_size_UTF8StringToArray = 0;
01266 
01272         protected $sign = false;
01273 
01279         protected $signature_data = array();
01280 
01286         protected $signature_max_lenght = 5120;
01287 
01293         protected $re_spaces = '/[\s\p{Z}\p{Lo}]/';
01294 
01295         
01296         
01297         
01298 
01312         public function __construct($orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding='UTF-8', $diskcache=false) {
01313             
01314             if (function_exists('mb_internal_encoding') AND mb_internal_encoding()) {
01315                 $this->internal_encoding = mb_internal_encoding();
01316                 mb_internal_encoding('ASCII');
01317             }
01318             
01319             $this->diskcache = $diskcache ? true : false;
01320             
01321             $this->rtl = $this->l['a_meta_dir']=='rtl' ? true : false;
01322             $this->tmprtl = false;
01323             
01324             $this->_dochecks();
01325             
01326             $this->isunicode = $unicode;
01327             $this->page = 0;
01328             $this->transfmrk[0] = array();
01329             $this->pagedim = array();
01330             $this->n = 2;
01331             $this->buffer = '';
01332             $this->pages = array();
01333             $this->state = 0;
01334             $this->fonts = array();
01335             $this->FontFiles = array();
01336             $this->diffs = array();
01337             $this->images = array();
01338             $this->links = array();
01339             $this->gradients = array();
01340             $this->InFooter = false;
01341             $this->lasth = 0;
01342             $this->FontFamily = 'helvetica';
01343             $this->FontStyle = '';
01344             $this->FontSizePt = 12;
01345             $this->underline = false;
01346             $this->linethrough = false;
01347             $this->DrawColor = '0 G';
01348             $this->FillColor = '0 g';
01349             $this->TextColor = '0 g';
01350             $this->ColorFlag = false;
01351             
01352             $this->encrypted = false;
01353             $this->last_rc4_key = '';
01354             $this->padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
01355             
01356             $this->CoreFonts = array(
01357                 'courier'=>'Courier',
01358                 'courierB'=>'Courier-Bold',
01359                 'courierI'=>'Courier-Oblique',
01360                 'courierBI'=>'Courier-BoldOblique',
01361                 'helvetica'=>'Helvetica',
01362                 'helveticaB'=>'Helvetica-Bold',
01363                 'helveticaI'=>'Helvetica-Oblique',
01364                 'helveticaBI'=>'Helvetica-BoldOblique',
01365                 'times'=>'Times-Roman',
01366                 'timesB'=>'Times-Bold',
01367                 'timesI'=>'Times-Italic',
01368                 'timesBI'=>'Times-BoldItalic',
01369                 'symbol'=>'Symbol',
01370                 'zapfdingbats'=>'ZapfDingbats'
01371             );
01372             
01373             $this->setPageUnit($unit);
01374             
01375             $this->setPageFormat($format, $orientation);
01376             
01377             $margin = 28.35 / $this->k;
01378             $this->SetMargins($margin, $margin);
01379             
01380             $this->cMargin = $margin / 10;
01381             
01382             $this->LineWidth = 0.57 / $this->k;
01383             $this->linestyleWidth = sprintf('%.2F w', ($this->LineWidth * $this->k));
01384             $this->linestyleCap = '0 J';
01385             $this->linestyleJoin = '0 j';
01386             $this->linestyleDash = '[] 0 d';
01387             
01388             $this->SetAutoPageBreak(true, (2 * $margin));
01389             
01390             $this->SetDisplayMode('fullwidth');
01391             
01392             $this->SetCompression(true);
01393             
01394             $this->PDFVersion = '1.7';
01395             $this->encoding = $encoding;
01396             $this->HREF = array();
01397             $this->getFontsList();
01398             $this->fgcolor = array('R' => 0, 'G' => 0, 'B' => 0);
01399             $this->bgcolor = array('R' => 255, 'G' => 255, 'B' => 255);
01400             $this->extgstates = array();
01401             
01402             $this->sign = false;
01403             $this->ur = false;
01404             $this->ur_document = '/FullSave';
01405             $this->ur_annots = '/Create/Delete/Modify/Copy/Import/Export';
01406             $this->ur_form = '/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate';
01407             $this->ur_signature = '/Modify';            
01408             
01409             $this->jpeg_quality = 75;
01410             
01411             $this->utf8Bidi(array(''), '');
01412             
01413             $this->SetFont($this->FontFamily, $this->FontStyle, $this->FontSizePt);
01414             
01415             if (@preg_match('/\pL/u', 'a') == 1) {
01416                 
01417                 
01418                 
01419                 
01420                 $this->re_spaces = '/[\s\p{Z}\p{Lo}]/';
01421             } else {
01422                 
01423                 $this->re_spaces = '/[\s]/';
01424             }
01425         }
01426         
01432         public function __destruct() {
01433             
01434             if (isset($this->internal_encoding) AND !empty($this->internal_encoding)) {
01435                 mb_internal_encoding($this->internal_encoding);
01436             }
01437             
01438             $this->_destroy(true);
01439         }
01440         
01447         public function setPageUnit($unit) {
01448         
01449             switch (strtolower($unit)) {
01450                 
01451                 case 'px':
01452                 case 'pt': {
01453                     $this->k = 1;
01454                     break;
01455                 }
01456                 
01457                 case 'mm': {
01458                     $this->k = $this->dpi / 25.4;
01459                     break;
01460                 }
01461                 
01462                 case 'cm': {
01463                     $this->k = $this->dpi / 2.54;
01464                     break;
01465                 }
01466                 
01467                 case 'in': {
01468                     $this->k = $this->dpi;
01469                     break;
01470                 }
01471                 
01472                 default : {
01473                     $this->Error('Incorrect unit: '.$unit);
01474                     break;
01475                 }
01476             }
01477             if (isset($this->CurOrientation)) {
01478                     $this->setPageOrientation($this->CurOrientation);
01479             }
01480         }
01481         
01489         public function setPageFormat($format, $orientation='P') {
01490             
01491             if (is_string($format)) {
01492                 
01493                 
01494                 switch (strtoupper($format)) {
01495                     case '4A0': {$format = array(4767.87,6740.79); break;}
01496                     case '2A0': {$format = array(3370.39,4767.87); break;}
01497                     case 'A0': {$format = array(2383.94,3370.39); break;}
01498                     case 'A1': {$format = array(1683.78,2383.94); break;}
01499                     case 'A2': {$format = array(1190.55,1683.78); break;}
01500                     case 'A3': {$format = array(841.89,1190.55); break;}
01501                     case 'A4': default: {$format = array(595.28,841.89); break;}
01502                     case 'A5': {$format = array(419.53,595.28); break;}
01503                     case 'A6': {$format = array(297.64,419.53); break;}
01504                     case 'A7': {$format = array(209.76,297.64); break;}
01505                     case 'A8': {$format = array(147.40,209.76); break;}
01506                     case 'A9': {$format = array(104.88,147.40); break;}
01507                     case 'A10': {$format = array(73.70,104.88); break;}
01508                     case 'B0': {$format = array(2834.65,4008.19); break;}
01509                     case 'B1': {$format = array(2004.09,2834.65); break;}
01510                     case 'B2': {$format = array(1417.32,2004.09); break;}
01511                     case 'B3': {$format = array(1000.63,1417.32); break;}
01512                     case 'B4': {$format = array(708.66,1000.63); break;}
01513                     case 'B5': {$format = array(498.90,708.66); break;}
01514                     case 'B6': {$format = array(354.33,498.90); break;}
01515                     case 'B7': {$format = array(249.45,354.33); break;}
01516                     case 'B8': {$format = array(175.75,249.45); break;}
01517                     case 'B9': {$format = array(124.72,175.75); break;}
01518                     case 'B10': {$format = array(87.87,124.72); break;}
01519                     case 'C0': {$format = array(2599.37,3676.54); break;}
01520                     case 'C1': {$format = array(1836.85,2599.37); break;}
01521                     case 'C2': {$format = array(1298.27,1836.85); break;}
01522                     case 'C3': {$format = array(918.43,1298.27); break;}
01523                     case 'C4': {$format = array(649.13,918.43); break;}
01524                     case 'C5': {$format = array(459.21,649.13); break;}
01525                     case 'C6': {$format = array(323.15,459.21); break;}
01526                     case 'C7': {$format = array(229.61,323.15); break;}
01527                     case 'C8': {$format = array(161.57,229.61); break;}
01528                     case 'C9': {$format = array(113.39,161.57); break;}
01529                     case 'C10': {$format = array(79.37,113.39); break;}
01530                     case 'RA0': {$format = array(2437.80,3458.27); break;}
01531                     case 'RA1': {$format = array(1729.13,2437.80); break;}
01532                     case 'RA2': {$format = array(1218.90,1729.13); break;}
01533                     case 'RA3': {$format = array(864.57,1218.90); break;}
01534                     case 'RA4': {$format = array(609.45,864.57); break;}
01535                     case 'SRA0': {$format = array(2551.18,3628.35); break;}
01536                     case 'SRA1': {$format = array(1814.17,2551.18); break;}
01537                     case 'SRA2': {$format = array(1275.59,1814.17); break;}
01538                     case 'SRA3': {$format = array(907.09,1275.59); break;}
01539                     case 'SRA4': {$format = array(637.80,907.09); break;}
01540                     case 'LETTER': {$format = array(612.00,792.00); break;}
01541                     case 'LEGAL': {$format = array(612.00,1008.00); break;}
01542                     case 'EXECUTIVE': {$format = array(521.86,756.00); break;}
01543                     case 'FOLIO': {$format = array(612.00,936.00); break;}
01544                 }
01545                 $this->fwPt = $format[0];
01546                 $this->fhPt = $format[1];
01547             } else {
01548                 $this->fwPt = $format[0] * $this->k;
01549                 $this->fhPt = $format[1] * $this->k;
01550             }
01551             $this->setPageOrientation($orientation);
01552         }
01553         
01562         public function setPageOrientation($orientation, $autopagebreak='', $bottommargin='') {
01563             $orientation = strtoupper($orientation);
01564             if (($orientation == 'P') OR ($orientation == 'PORTRAIT')) {
01565                 $this->CurOrientation = 'P';
01566                 $this->wPt = $this->fwPt;
01567                 $this->hPt = $this->fhPt;
01568             } elseif (($orientation == 'L') OR ($orientation == 'LANDSCAPE')) {
01569                 $this->CurOrientation = 'L';
01570                 $this->wPt = $this->fhPt;
01571                 $this->hPt = $this->fwPt;
01572             } else {
01573                 $this->Error('Incorrect orientation: '.$orientation);
01574             }
01575             $this->w = $this->wPt / $this->k;
01576             $this->h = $this->hPt / $this->k;
01577             if ($this->empty_string($autopagebreak)) {
01578                 if (isset($this->AutoPageBreak)) {
01579                     $autopagebreak = $this->AutoPageBreak;
01580                 } else {
01581                     $autopagebreak = true;
01582                 }
01583             }
01584             if ($this->empty_string($bottommargin)) {
01585                 if (isset($this->bMargin)) {
01586                     $bottommargin = $this->bMargin;
01587                 } else {
01588                     
01589                     $bottommargin = 2 * 28.35 / $this->k;
01590                 }
01591             }
01592             $this->SetAutoPageBreak($autopagebreak, $bottommargin);
01593             
01594             $this->pagedim[$this->page] = array('w' => $this->wPt, 'h' => $this->hPt, 'wk' => $this->w, 'hk' => $this->h, 'tm' => $this->tMargin, 'bm' => $bottommargin, 'lm' => $this->lMargin, 'rm' => $this->rMargin, 'pb' => $autopagebreak, 'or' => $this->CurOrientation, 'olm' => $this->original_lMargin, 'orm' => $this->original_rMargin);
01595         }
01596                 
01603         public function setRTL($enable) {
01604             $this->rtl = $enable ? true : false;
01605             $this->tmprtl = false;
01606         }
01607         
01614         public function getRTL() {
01615             return $this->rtl;
01616         }
01617         
01624         public function setTempRTL($mode) {
01625             switch ($mode) {
01626                 case false:
01627                 case 'L':
01628                 case 'R': {
01629                     $this->tmprtl = $mode;
01630                 }
01631             }
01632         }
01633         
01641         public function setLastH($h) {
01642             $this->lasth = $h;
01643         }
01644         
01651         public function getLastH() {
01652             return $this->lasth;
01653         }
01654         
01662         public function setImageScale($scale) {
01663             $this->imgscale = $scale;
01664         }
01665 
01673         public function getImageScale() {
01674             return $this->imgscale;
01675         }
01676                 
01686         public function getPageDimensions($pagenum='') {
01687             if (empty($pagenum)) {
01688                 $pagenum = $this->page;
01689             }
01690             return $this->pagedim[$pagenum];
01691         }
01692         
01702         public function getPageWidth($pagenum='') {
01703             if (empty($pagenum)) {
01704                 return $this->w;
01705             }
01706             return $this->pagedim[$pagenum]['w'];
01707         }
01708 
01718         public function getPageHeight($pagenum='') {
01719             if (empty($pagenum)) {
01720                 return $this->h;
01721             }
01722             return $this->pagedim[$pagenum]['h'];
01723         }
01724 
01734         public function getBreakMargin($pagenum='') {
01735             if (empty($pagenum)) {
01736                 return $this->bMargin;
01737             }
01738             return $this->pagedim[$pagenum]['bm'];
01739         }
01740 
01748         public function getScaleFactor() {
01749             return $this->k;
01750         }
01751 
01761         public function SetMargins($left, $top, $right=-1) {
01762             
01763             $this->lMargin = $left;
01764             $this->tMargin = $top;
01765             if ($right == -1) {
01766                 $right = $left;
01767             }
01768             $this->rMargin = $right;
01769         }
01770 
01778         public function SetLeftMargin($margin) {
01779             
01780             $this->lMargin=$margin;
01781             if (($this->page > 0) AND ($this->x < $margin)) {
01782                 $this->x = $margin;
01783             }
01784         }
01785 
01793         public function SetTopMargin($margin) {
01794             
01795             $this->tMargin=$margin;
01796             if (($this->page > 0) AND ($this->y < $margin)) {
01797                 $this->y = $margin;
01798             }
01799         }
01800 
01808         public function SetRightMargin($margin) {
01809             $this->rMargin=$margin;
01810             if (($this->page > 0) AND ($this->x > ($this->w - $margin))) {
01811                 $this->x = $this->w - $margin;
01812             }
01813         }
01814 
01822         public function SetCellPadding($pad) {
01823             $this->cMargin = $pad;
01824         }
01825 
01834         public function SetAutoPageBreak($auto, $margin=0) {
01835             
01836             $this->AutoPageBreak = $auto;
01837             $this->bMargin = $margin;
01838             $this->PageBreakTrigger = $this->h - $margin;
01839         }
01840 
01849         public function SetDisplayMode($zoom, $layout='SinglePage', $mode='UseNone') {
01850             
01851             if (($zoom == 'fullpage') OR ($zoom == 'fullwidth') OR ($zoom == 'real') OR ($zoom == 'default') OR (!is_string($zoom))) {
01852                 $this->ZoomMode = $zoom;
01853             } else {
01854                 $this->Error('Incorrect zoom display mode: '.$zoom);
01855             }
01856             switch ($layout) {
01857                 case 'default':
01858                 case 'single':
01859                 case 'SinglePage': {
01860                     $this->LayoutMode = 'SinglePage';
01861                     break;
01862                 }
01863                 case 'continuous':
01864                 case 'OneColumn': {
01865                     $this->LayoutMode = 'OneColumn';
01866                     break;
01867                 }
01868                 case 'two':
01869                 case 'TwoColumnLeft': {
01870                     $this->LayoutMode = 'TwoColumnLeft';
01871                     break;
01872                 }
01873                 case 'TwoColumnRight': {
01874                     $this->LayoutMode = 'TwoColumnRight';
01875                     break;
01876                 }
01877                 case 'TwoPageLeft': {
01878                     $this->LayoutMode = 'TwoPageLeft';
01879                     break;
01880                 }
01881                 case 'TwoPageRight': {
01882                     $this->LayoutMode = 'TwoPageRight';
01883                     break;
01884                 }
01885                 default: {
01886                     $this->LayoutMode = 'SinglePage';
01887                 }
01888             }
01889             switch ($mode) {
01890                 case 'UseNone': {
01891                     $this->PageMode = 'UseNone';
01892                     break;
01893                 }
01894                 case 'UseOutlines': {
01895                     $this->PageMode = 'UseOutlines';
01896                     break;
01897                 }
01898                 case 'UseThumbs': {
01899                     $this->PageMode = 'UseThumbs';
01900                     break;
01901                 }
01902                 case 'FullScreen': {
01903                     $this->PageMode = 'FullScreen';
01904                     break;
01905                 }
01906                 case 'UseOC': {
01907                     $this->PageMode = 'UseOC';
01908                     break;
01909                 }
01910                 case '': {
01911                     $this->PageMode = 'UseAttachments';
01912                     break;
01913                 }
01914                 default: {
01915                     $this->PageMode = 'UseNone';
01916                 }
01917             }
01918         }
01919 
01927         public function SetCompression($compress) {
01928             
01929             if (function_exists('gzcompress')) {
01930                 $this->compress = $compress;
01931             } else {
01932                 $this->compress = false;
01933             }
01934         }
01935 
01943         public function SetTitle($title) {
01944             
01945             $this->title = $title;
01946         }
01947 
01955         public function SetSubject($subject) {
01956             
01957             $this->subject = $subject;
01958         }
01959 
01967         public function SetAuthor($author) {
01968             
01969             $this->author = $author;
01970         }
01971 
01979         public function SetKeywords($keywords) {
01980             
01981             $this->keywords = $keywords;
01982         }
01983 
01991         public function SetCreator($creator) {
01992             
01993             $this->creator = $creator;
01994         }
01995         
02003         public function Error($msg) {
02004             
02005             $this->_destroy(true);
02006             
02007             die('<strong>TCPDF ERROR: </strong>'.$msg);
02008         }
02009 
02018         public function Open() {
02019             
02020             $this->state = 1;
02021         }
02022 
02031         public function Close() {
02032             if ($this->state == 3) {
02033                 return;
02034             }
02035             if ($this->page == 0) {
02036                 $this->AddPage();
02037             }
02038             
02039             $this->endPage();
02040             
02041             $this->_enddoc();
02042             
02043             $this->_destroy(false);
02044         }
02045         
02054         public function setPage($pnum, $resetmargins=false) {
02055             if ($pnum == $this->page) {
02056                 return;
02057             }
02058             if (($pnum > 0) AND ($pnum <= $this->numpages)) {
02059                 $this->state = 2;
02060                 
02061                 
02062                 $oldpage = $this->page;
02063                 $this->page = $pnum;
02064                 $this->wPt = $this->pagedim[$this->page]['w'];
02065                 $this->hPt = $this->pagedim[$this->page]['h'];
02066                 $this->w = $this->wPt / $this->k;
02067                 $this->h = $this->hPt / $this->k;
02068                 $this->tMargin = $this->pagedim[$this->page]['tm'];
02069                 $this->bMargin = $this->pagedim[$this->page]['bm'];
02070                 $this->original_lMargin = $this->pagedim[$this->page]['olm'];
02071                 $this->original_rMargin = $this->pagedim[$this->page]['orm'];
02072                 $this->AutoPageBreak = $this->pagedim[$this->page]['pb'];
02073                 $this->CurOrientation = $this->pagedim[$this->page]['or'];
02074                 $this->SetAutoPageBreak($this->AutoPageBreak, $this->bMargin);
02075                 
02076                 
02077                 if ($resetmargins) {
02078                     $this->lMargin = $this->pagedim[$this->page]['olm'];
02079                     $this->rMargin = $this->pagedim[$this->page]['orm'];
02080                     $this->SetY($this->tMargin);
02081                 } else {
02082                     
02083                     if ($this->pagedim[$this->page]['olm'] != $this->pagedim[$oldpage]['olm']) {
02084                         $deltam = $this->pagedim[$this->page]['olm'] - $this->pagedim[$this->page]['orm'];
02085                         $this->lMargin += $deltam;
02086                         $this->rMargin -= $deltam;
02087                     }
02088                 }
02089             } else {
02090                 $this->Error('Wrong page number on setPage() function.');
02091             }
02092         }
02093         
02101         public function lastPage($resetmargins=false) {
02102             $this->setPage($this->getNumPages(), $resetmargins);
02103         }
02104         
02112         public function getPage() {
02113             return $this->page;
02114         }
02115         
02116         
02124         public function getNumPages() {
02125             return $this->numpages;
02126         }
02127 
02137         public function AddPage($orientation='', $format='') {
02138             if (!isset($this->original_lMargin)) {
02139                 $this->original_lMargin = $this->lMargin;
02140             }
02141             if (!isset($this->original_rMargin)) {
02142                 $this->original_rMargin = $this->rMargin;
02143             }
02144             
02145             $this->endPage();
02146             
02147             $this->startPage($orientation, $format);
02148         }
02149 
02156         protected function endPage() {
02157             
02158             if (($this->page == 0) OR ($this->numpages > $this->page) OR (!$this->pageopen[$this->page])) {
02159                 return;
02160             }
02161             $this->InFooter = true;
02162             
02163             $this->setFooter();
02164             
02165             $this->_endpage();
02166             
02167             $this->pageopen[$this->page] = false;
02168             $this->InFooter = false;
02169         }
02170 
02180         protected function startPage($orientation='', $format='') {
02181             if ($this->numpages > $this->page) {
02182                 
02183                 $this->setPage($this->page + 1);
02184                 $this->SetY($this->tMargin);
02185                 return;
02186             }
02187             
02188             if ($this->state == 0) {
02189                 $this->Open();
02190             }
02191             ++$this->numpages;
02192             $this->swapMargins($this->booklet);
02193             
02194             $gvars = $this->getGraphicVars();
02195             
02196             $this->_beginpage($orientation, $format);
02197             
02198             $this->pageopen[$this->page] = true;
02199             
02200             $this->setGraphicVars($gvars);
02201             
02202             $this->setPageMark();
02203             
02204             $this->setHeader();
02205             
02206             $this->setGraphicVars($gvars);
02207             
02208             $this->setPageMark();
02209             
02210             $this->setTableHeader();
02211         }
02212             
02220         public function setPageMark() {
02221             $this->intmrk[$this->page] = $this->pagelen[$this->page];
02222         }
02223         
02232         public function setHeaderData($ln='', $lw=0, $ht='', $hs='') {
02233             $this->header_logo = $ln;
02234             $this->header_logo_width = $lw;
02235             $this->header_title = $ht;
02236             $this->header_string = $hs;
02237         }
02238         
02246         public function getHeaderData() {
02247             $ret = array();
02248             $ret['logo'] = $this->header_logo;
02249             $ret['logo_width'] = $this->header_logo_width;
02250             $ret['title'] = $this->header_title;
02251             $ret['string'] = $this->header_string;
02252             return $ret;
02253         }
02254         
02261         public function setHeaderMargin($hm=10) {
02262             $this->header_margin = $hm;
02263         }
02264         
02271         public function getHeaderMargin() {
02272             return $this->header_margin;
02273         }
02274         
02281         public function setFooterMargin($fm=10) {
02282             $this->footer_margin = $fm;
02283         }
02284         
02291         public function getFooterMargin() {
02292             return $this->footer_margin;
02293         }
02299         public function setPrintHeader($val=true) {
02300             $this->print_header = $val;
02301         }
02302         
02308         public function setPrintFooter($val=true) {
02309             $this->print_footer = $val;
02310         }
02311         
02317         public function getImageRBX() {
02318             return $this->img_rb_x;
02319         }
02320         
02326         public function getImageRBY() {
02327             return $this->img_rb_y;
02328         }
02329         
02335         public function Header() {
02336             $ormargins = $this->getOriginalMargins();
02337             $headerfont = $this->getHeaderFont();
02338             $headerdata = $this->getHeaderData();
02339             if (($headerdata['logo']) AND ($headerdata['logo'] != K_BLANK_IMAGE)) {
02340                 $this->Image(K_PATH_IMAGES.$headerdata['logo'], $this->GetX(), $this->getHeaderMargin(), $headerdata['logo_width']);
02341                 $imgy = $this->getImageRBY();
02342             } else {
02343                 $imgy = $this->GetY();
02344             }
02345             $cell_height = round(($this->getCellHeightRatio() * $headerfont[2]) / $this->getScaleFactor(), 2);
02346             
02347             if ($this->getRTL()) {
02348                 $header_x = $ormargins['right'] + ($headerdata['logo_width'] * 1.1);
02349             } else {
02350                 $header_x = $ormargins['left'] + ($headerdata['logo_width'] * 1.1);
02351             }
02352             $this->SetTextColor(0, 0, 0);
02353             
02354             $this->SetFont($headerfont[0], 'B', $headerfont[2] + 1);
02355             $this->SetX($header_x);         
02356             $this->Cell(0, $cell_height, $headerdata['title'], 0, 1, '', 0, '', 0);
02357             
02358             $this->SetFont($headerfont[0], $headerfont[1], $headerfont[2]);
02359             $this->SetX($header_x);
02360             $this->MultiCell(0, $cell_height, $headerdata['string'], 0, '', 0, 1, '', '', true, 0, false);
02361             
02362             $this->SetLineStyle(array('width' => 0.85 / $this->getScaleFactor(), 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)));
02363             $this->SetY((2.835 / $this->getScaleFactor()) + max($imgy, $this->GetY()));
02364             if ($this->getRTL()) {
02365                 $this->SetX($ormargins['right']);
02366             } else {
02367                 $this->SetX($ormargins['left']);
02368             }
02369             $this->Cell(0, 0, '', 'T', 0, 'C');
02370         }
02371         
02377         public function Footer() {              
02378             $cur_y = $this->GetY();
02379             $ormargins = $this->getOriginalMargins();
02380             $this->SetTextColor(0, 0, 0);           
02381             
02382             $line_width = 0.85 / $this->getScaleFactor();
02383             $this->SetLineStyle(array('width' => $line_width, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)));
02384             
02385             $barcode = $this->getBarcode();
02386             if (!empty($barcode)) {
02387                 $this->Ln($line_width);
02388                 $barcode_width = round(($this->getPageWidth() - $ormargins['left'] - $ormargins['right'])/3);
02389                 $this->write1DBarcode($barcode, 'C128B', $this->GetX(), $cur_y + $line_width, $barcode_width, (($this->getFooterMargin() / 3) - $line_width), 0.3, '', ''); 
02390             }
02391             if (empty($this->pagegroups)) {
02392                 $pagenumtxt = $this->l['w_page'].' '.$this->getAliasNumPage().' / '.$this->getAliasNbPages();
02393             } else {
02394                 $pagenumtxt = $this->l['w_page'].' '.$this->getPageNumGroupAlias().' / '.$this->getPageGroupAlias();
02395             }       
02396             $this->SetY($cur_y);
02397             
02398             if ($this->getRTL()) {
02399                 $this->SetX($ormargins['right']);
02400                 $this->Cell(0, 0, $pagenumtxt, 'T', 0, 'L');
02401             } else {
02402                 $this->SetX($ormargins['left']);
02403                 $this->Cell(0, 0, $pagenumtxt, 'T', 0, 'R');
02404             }
02405         }
02406         
02412         protected function setHeader() {
02413             if ($this->print_header) {
02414                 $lasth = $this->lasth;
02415                 $this->_out('q');
02416                 $this->rMargin = $this->original_rMargin;
02417                 $this->lMargin = $this->original_lMargin;
02418                 $this->cMargin = 0;
02419                 
02420                 if ($this->rtl) {
02421                     $this->SetXY($this->original_rMargin, $this->header_margin);
02422                 } else {
02423                     $this->SetXY($this->original_lMargin, $this->header_margin);
02424                 }
02425                 $this->SetFont($this->header_font[0], $this->header_font[1], $this->header_font[2]);
02426                 $this->Header();
02427                 
02428                 if ($this->rtl) {
02429                     $this->SetXY($this->original_rMargin, $this->tMargin);
02430                 } else {
02431                     $this->SetXY($this->original_lMargin, $this->tMargin);
02432                 }
02433                 $this->_out('Q');
02434                 $this->lasth = $lasth;
02435             }
02436         }
02437         
02443         protected function setFooter() {
02444             
02445             
02446             $gvars = $this->getGraphicVars();
02447             
02448             $this->footerpos[$this->page] = $this->pagelen[$this->page];
02449             $this->_out("\n");
02450             if ($this->print_footer) {
02451                 $lasth = $this->lasth;
02452                 $this->_out('q');
02453                 $this->rMargin = $this->original_rMargin;
02454                 $this->lMargin = $this->original_lMargin;
02455                 $this->cMargin = 0;
02456                 
02457                 $footer_y = $this->h - $this->footer_margin;
02458                 if ($this->rtl) {
02459                     $this->SetXY($this->original_rMargin, $footer_y);
02460                 } else {
02461                     $this->SetXY($this->original_lMargin, $footer_y);
02462                 }
02463                 $this->SetFont($this->footer_font[0], $this->footer_font[1], $this->footer_font[2]);
02464                 $this->Footer();
02465                 
02466                 if ($this->rtl) {
02467                     $this->SetXY($this->original_rMargin, $this->tMargin);
02468                 } else {
02469                     $this->SetXY($this->original_lMargin, $this->tMargin);
02470                 }
02471                 $this->_out('Q');
02472                 $this->lasth = $lasth;
02473             }
02474             
02475             $this->setGraphicVars($gvars);
02476             
02477             $this->footerlen[$this->page] = $this->pagelen[$this->page] - $this->footerpos[$this->page] + 1;
02478         }
02479 
02485         protected function setTableHeader() {
02486             if (!$this->empty_string($this->theadMargin)) {
02487                 
02488                 $this->tMargin = $this->theadMargin;
02489                 $this->pagedim[$this->page]['tm'] = $this->theadMargin;
02490                 $this->y = $this->theadMargin;
02491             }
02492             if (!$this->empty_string($this->thead)) {
02493                 
02494                 $this->writeHTML($this->thead, false, false, false, false, '');
02495                 
02496                 if (!isset($this->theadMargin) OR ($this->empty_string($this->theadMargin))) {
02497                     $this->theadMargin = $this->tMargin;
02498                 }
02499                 $this->tMargin = $this->y;
02500                 $this->pagedim[$this->page]['tm'] = $this->tMargin;
02501             }
02502         }
02503         
02511         public function PageNo() {
02512             return $this->page;
02513         }
02514 
02527         public function AddSpotColor($name, $c, $m, $y, $k) {
02528             if (!isset($this->spot_colors[$name])) {
02529                 $i = 1 + count($this->spot_colors);
02530                 $this->spot_colors[$name] = array('i' => $i, 'c' => $c, 'm' => $m, 'y' => $y, 'k' => $k);
02531             }
02532         }
02533 
02543         public function SetDrawColorArray($color) {
02544             if (isset($color)) {
02545                 $color = array_values($color);
02546                 $r = isset($color[0]) ? $color[0] : -1;
02547                 $g = isset($color[1]) ? $color[1] : -1;
02548                 $b = isset($color[2]) ? $color[2] : -1;
02549                 $k = isset($color[3]) ? $color[3] : -1;
02550                 if ($r >= 0) {
02551                     $this->SetDrawColor($r, $g, $b, $k);
02552                 }
02553             }
02554         }
02555 
02566         public function SetDrawColor($col1=0, $col2=-1, $col3=-1, $col4=-1) {
02567             
02568             if (!is_numeric($col1)) {
02569                 $col1 = 0;
02570             }
02571             if (!is_numeric($col2)) {
02572                 $col2 = -1;
02573             }
02574             if (!is_numeric($col3)) {
02575                 $col3 = -1;
02576             }
02577             if (!is_numeric($col4)) {
02578                 $col4 = -1;
02579             }
02580             
02581             if (($col2 == -1) AND ($col3 == -1) AND ($col4 == -1)) {
02582                 
02583                 $this->DrawColor = sprintf('%.3F G', $col1/255);
02584             } elseif ($col4 == -1) {
02585                 
02586                 $this->DrawColor = sprintf('%.3F %.3F %.3F RG', $col1/255, $col2/255, $col3/255);
02587             } else {
02588                 
02589                 $this->DrawColor = sprintf('%.3F %.3F %.3F %.3F K', $col1/100, $col2/100, $col3/100, $col4/100);
02590             }
02591             if ($this->page > 0) {
02592                 $this->_out($this->DrawColor);
02593             }
02594         }
02595         
02604         public function SetDrawSpotColor($name, $tint=100) {
02605             if (!isset($this->spot_colors[$name])) {
02606                 $this->Error('Undefined spot color: '.$name);
02607             }
02608             $this->DrawColor = sprintf('/CS%d CS %.3F SCN', $this->spot_colors[$name]['i'], $tint/100);
02609             if ($this->page > 0) {
02610                 $this->_out($this->DrawColor);
02611             }
02612         }
02613         
02623         public function SetFillColorArray($color) {
02624             if (isset($color)) {
02625                 $color = array_values($color);
02626                 $r = isset($color[0]) ? $color[0] : -1;
02627                 $g = isset($color[1]) ? $color[1] : -1;
02628                 $b = isset($color[2]) ? $color[2] : -1;
02629                 $k = isset($color[3]) ? $color[3] : -1;
02630                 if ($r >= 0) {
02631                     $this->SetFillColor($r, $g, $b, $k);
02632                 }
02633             }
02634         }
02635         
02646         public function SetFillColor($col1=0, $col2=-1, $col3=-1, $col4=-1) {
02647             
02648             if (!is_numeric($col1)) {
02649                 $col1 = 0;
02650             }
02651             if (!is_numeric($col2)) {
02652                 $col2 = -1;
02653             }
02654             if (!is_numeric($col3)) {
02655                 $col3 = -1;
02656             }
02657             if (!is_numeric($col4)) {
02658                 $col4 = -1;
02659             }
02660             
02661             if (($col2 == -1) AND ($col3 == -1) AND ($col4 == -1)) {
02662                 
02663                 $this->FillColor = sprintf('%.3F g', $col1/255);
02664                 $this->bgcolor = array('G' => $col1);
02665             } elseif ($col4 == -1) {
02666                 
02667                 $this->FillColor = sprintf('%.3F %.3F %.3F rg', $col1/255, $col2/255, $col3/255);
02668                 $this->bgcolor = array('R' => $col1, 'G' => $col2, 'B' => $col3);
02669             } else {
02670                 
02671                 $this->FillColor = sprintf('%.3F %.3F %.3F %.3F k', $col1/100, $col2/100, $col3/100, $col4/100);
02672                 $this->bgcolor = array('C' => $col1, 'M' => $col2, 'Y' => $col3, 'K' => $col4);
02673             }
02674             $this->ColorFlag = ($this->FillColor != $this->TextColor);
02675             if ($this->page > 0) {
02676                 $this->_out($this->FillColor);
02677             }
02678         }
02679         
02688         public function SetFillSpotColor($name, $tint=100) {
02689             if (!isset($this->spot_colors[$name])) {
02690                 $this->Error('Undefined spot color: '.$name);
02691             }
02692             $this->FillColor = sprintf('/CS%d cs %.3F scn', $this->spot_colors[$name]['i'], $tint/100);
02693             $this->ColorFlag = ($this->FillColor != $this->TextColor);
02694             if ($this->page > 0) {
02695                 $this->_out($this->FillColor);
02696             }
02697         }
02698         
02707         public function SetTextColorArray($color) {
02708             if (isset($color)) {
02709                 $color = array_values($color);
02710                 $r = isset($color[0]) ? $color[0] : -1;
02711                 $g = isset($color[1]) ? $color[1] : -1;
02712                 $b = isset($color[2]) ? $color[2] : -1;
02713                 $k = isset($color[3]) ? $color[3] : -1;
02714                 if ($r >= 0) {
02715                     $this->SetTextColor($r, $g, $b, $k);
02716                 }
02717             }
02718         }
02719 
02730         public function SetTextColor($col1=0, $col2=-1, $col3=-1, $col4=-1) {
02731             
02732             if (!is_numeric($col1)) {
02733                 $col1 = 0;
02734             }
02735             if (!is_numeric($col2)) {
02736                 $col2 = -1;
02737             }
02738             if (!is_numeric($col3)) {
02739                 $col3 = -1;
02740             }
02741             if (!is_numeric($col4)) {
02742                 $col4 = -1;
02743             }
02744             
02745             if (($col2 == -1) AND ($col3 == -1) AND ($col4 == -1)) {
02746                 
02747                 $this->TextColor = sprintf('%.3F g', $col1/255);
02748                 $this->fgcolor = array('G' => $col1);
02749             } elseif ($col4 == -1) {
02750                 
02751                 $this->TextColor = sprintf('%.3F %.3F %.3F rg', $col1/255, $col2/255, $col3/255);
02752                 $this->fgcolor = array('R' => $col1, 'G' => $col2, 'B' => $col3);
02753             } else {
02754                 
02755                 $this->TextColor = sprintf('%.3F %.3F %.3F %.3F k', $col1/100, $col2/100, $col3/100, $col4/100);
02756                 $this->fgcolor = array('C' => $col1, 'M' => $col2, 'Y' => $col3, 'K' => $col4);
02757             }
02758             $this->ColorFlag = ($this->FillColor != $this->TextColor);
02759         }
02760         
02769         public function SetTextSpotColor($name, $tint=100) {
02770             if (!isset($this->spot_colors[$name])) {
02771                 $this->Error('Undefined spot color: '.$name);
02772             }
02773             $this->TextColor = sprintf('/CS%d cs %.3F scn', $this->spot_colors[$name]['i'], $tint/100);
02774             $this->ColorFlag = ($this->FillColor != $this->TextColor);
02775             if ($this->page > 0) {
02776                 $this->_out($this->TextColor);
02777             }
02778         }
02779 
02791         public function GetStringWidth($s, $fontname='', $fontstyle='', $fontsize=0) {
02792             return $this->GetArrStringWidth($this->utf8Bidi($this->UTF8StringToArray($s), $s, $this->tmprtl), $fontname, $fontstyle, $fontsize);
02793         }
02794         
02806         public function GetArrStringWidth($sa, $fontname='', $fontstyle='', $fontsize=0) {
02807             
02808             if (!$this->empty_string($fontname)) {
02809                 $prev_FontFamily = $this->FontFamily;
02810                 $prev_FontStyle = $this->FontStyle;
02811                 $prev_FontSizePt = $this->FontSizePt;
02812                 $this->SetFont($fontname, $fontstyle, $fontsize);
02813             }
02814             $w = 0;
02815             foreach ($sa as $char) {
02816                 $w += $this->GetCharWidth($char);
02817             }
02818             
02819             if (!$this->empty_string($fontname)) {
02820                 $this->SetFont($prev_FontFamily, $prev_FontStyle, $prev_FontSizePt);
02821             }
02822             return $w;
02823         }
02824         
02833         public function GetCharWidth($char) {
02834             if ($char == 173) {
02835                 
02836                 return (0);
02837             }
02838             $cw = &$this->CurrentFont['cw'];
02839             if (isset($cw[$char])) {
02840                 $w = $cw[$char];
02841             } elseif (isset($this->CurrentFont['dw'])) {
02842                 
02843                 $w = $this->CurrentFont['dw'];
02844             } elseif (isset($cw[32])) {
02845                 
02846                 $dw = $cw[32];
02847             } else {
02848                 $w = 600;
02849             }
02850             return ($w * $this->FontSize / 1000);
02851         }
02852         
02860         public function GetNumChars($s) {
02861             if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
02862                 return count($this->UTF8StringToArray($s));
02863             } 
02864             return strlen($s);
02865         }
02866             
02872         protected function getFontsList() {
02873             $fontsdir = opendir($this->_getfontpath());
02874             while (($file = readdir($fontsdir)) !== false) {
02875                 if (substr($file, -4) == '.php') {
02876                     array_push($this->fontlist, strtolower(basename($file, '.php')));
02877                 }
02878             }
02879             closedir($fontsdir);
02880         }
02881         
02894         public function AddFont($family, $style='', $fontfile='') {
02895             if ($this->empty_string($family)) {
02896                 if (!$this->empty_string($this->FontFamily)) {
02897                     $family = $this->FontFamily;
02898                 } else {
02899                     $this->Error('Empty font family');
02900                 }
02901             }
02902             $family = strtolower($family);
02903             if ((!$this->isunicode) AND ($family == 'arial')) {
02904                 $family = 'helvetica';
02905             }
02906             if (($family == 'symbol') OR ($family == 'zapfdingbats')) {
02907                 $style = '';
02908             }
02909             $tempstyle = strtoupper($style);
02910             $style = '';
02911             
02912             if (strpos($tempstyle, 'U') !== false) {
02913                 $this->underline = true;
02914             } else {
02915                 $this->underline = false;
02916             }
02917             
02918             if (strpos($tempstyle, 'D') !== false) {
02919                 $this->linethrough = true;
02920             } else {
02921                 $this->linethrough = false;
02922             }
02923             
02924             if (strpos($tempstyle, 'B') !== false) {
02925                 $style .= 'B';
02926             }
02927             
02928             if (strpos($tempstyle, 'I') !== false) {
02929                 $style .= 'I';
02930             }
02931             $bistyle = $style;
02932             $fontkey = $family.$style;
02933             $font_style = $style.($this->underline ? 'U' : '').($this->linethrough ? 'D' : '');
02934             $fontdata = array('fontkey' => $fontkey, 'family' => $family, 'style' => $font_style);
02935             
02936             if ($this->getFontBuffer($fontkey) !== false) {
02937                 return $fontdata;
02938             }
02939             if (isset($type)) {
02940                 unset($type); 
02941             }
02942             if (isset($cw)) {
02943                 unset($cw); 
02944             }
02945             
02946             $fontdir = '';
02947             if (!$this->empty_string($fontfile)) {
02948                 $fontdir = dirname($fontfile);
02949                 if ($this->empty_string($fontdir) OR ($fontdir == '.')) {
02950                     $fontdir = '';
02951                 } else {
02952                     $fontdir .= '/';
02953                 }
02954             }
02955             
02956             if ($this->empty_string($fontfile) OR (!file_exists($fontfile))) {
02957                 
02958                 $fontfile1 = str_replace(' ', '', $family).strtolower($style).'.php';
02959                 $fontfile2 = str_replace(' ', '', $family).'.php';
02960                 
02961                 if (file_exists($fontdir.$fontfile1)) {
02962                     $fontfile = $fontdir.$fontfile1;
02963                 } elseif (file_exists($this->_getfontpath().$fontfile1)) {
02964                     $fontfile = $this->_getfontpath().$fontfile1;
02965                 } elseif (file_exists($fontfile1)) {
02966                     $fontfile = $fontfile1;
02967                 } elseif (file_exists($fontdir.$fontfile2)) {
02968                     $fontfile = $fontdir.$fontfile2;
02969                 } elseif (file_exists($this->_getfontpath().$fontfile2)) {
02970                     $fontfile = $this->_getfontpath().$fontfile2;
02971                 } else {
02972                     $fontfile = $fontfile2;
02973                 }
02974             }
02975             
02976             if (file_exists($fontfile)) {
02977                 include($fontfile);
02978             } else {
02979                 $this->Error('Could not include font definition file: '.$family.'');
02980             }
02981             
02982             if ((!isset($type)) OR (!isset($cw))) {
02983                 $this->Error('The font definition file has a bad format: '.$fontfile.'');
02984             }
02985             if (!isset($file)) {
02986                 $file = '';
02987             }
02988             if (!isset($enc)) {
02989                 $enc = '';
02990             }
02991             if (!isset($dw) OR $this->empty_string($dw)) {
02992                 
02993                 if (isset($desc['MissingWidth']) AND ($desc['MissingWidth'] > 0)) {
02994                     $dw = $desc['MissingWidth'];
02995                 } elseif (isset($cw[32])) {
02996                     $dw = $cw[32];
02997                 } else {
02998                     $dw = 600;
02999                 }
03000             }
03001             ++$this->numfonts;          
03002             
03003             if ($type == 'cidfont0') {
03004                 $file = ''; 
03005                 $styles = array('' => '', 'B' => ',Bold', 'I' => ',Italic', 'BI' => ',BoldItalic');
03006                 $sname = $name.$styles[$bistyle];
03007                 if ((strpos($bistyle, 'B') !== false) AND (isset($desc['StemV'])) AND ($desc['StemV'] == 70)) {
03008                     $desc['StemV'] = 120;
03009                 }
03010                 $this->setFontBuffer($fontkey, array('i' => $this->numfonts, 'type' => $type, 'name' => $sname, 'desc' => $desc, 'cidinfo' => $cidinfo, 'up' => $up, 'ut' => $ut, 'cw' => $cw, 'dw' => $dw, 'enc' => $enc));
03011             } elseif ($type == 'core') {
03012                 $this->setFontBuffer($fontkey, array('i' => $this->numfonts, 'type' => 'core', 'name' => $this->CoreFonts[$fontkey], 'up' => -100, 'ut' => 50, 'cw' => $cw, 'dw' => $dw));
03013             } elseif (($type == 'TrueType') OR ($type == 'Type1')) {
03014                 $this->setFontBuffer($fontkey, array('i' => $this->numfonts, 'type' => $type, 'name' => $name, 'up' => $up, 'ut' => $ut, 'cw' => $cw, 'dw' => $dw, 'file' => $file, 'enc' => $enc, 'desc' => $desc));
03015             } elseif ($type == 'TrueTypeUnicode') {
03016                 $this->setFontBuffer($fontkey, array('i' => $this->numfonts, 'type' => $type, 'name' => $name, 'desc' => $desc, 'up' => $up, 'ut' => $ut, 'cw' => $cw, 'dw' => $dw, 'enc' => $enc, 'file' => $file, 'ctg' => $ctg));
03017             } else {
03018                 $this->Error('Unknow font type: '.$type.'');
03019             }
03020             if (isset($diff) AND (!empty($diff))) {
03021                 
03022                 $d = 0;
03023                 $nb = count($this->diffs);
03024                 for($i=1; $i <= $nb; ++$i) {
03025                     if ($this->diffs[$i] == $diff) {
03026                         $d = $i;
03027                         break;
03028                     }
03029                 }
03030                 if ($d == 0) {
03031                     $d = $nb + 1;
03032                     $this->diffs[$d] = $diff;
03033                 }
03034                 $this->setFontSubBuffer($fontkey, 'diff', $d);
03035             }
03036             if (!$this->empty_string($file)) {
03037                 if ((strcasecmp($type,'TrueType') == 0) OR (strcasecmp($type, 'TrueTypeUnicode') == 0)) {
03038                     $this->FontFiles[$file] = array('length1' => $originalsize, 'fontdir' => $fontdir);
03039                 } elseif ($type != 'core') {
03040                     $this->FontFiles[$file] = array('length1' => $size1, 'length2' => $size2, 'fontdir' => $fontdir);
03041                 }
03042             }
03043             return $fontdata;
03044         }
03045 
03060         public function SetFont($family, $style='', $size=0, $fontfile='') {
03061             
03062             if ($size == 0) {
03063                 $size = $this->FontSizePt;
03064             }
03065             
03066             $fontdata = $this->AddFont($family, $style, $fontfile);
03067             $this->FontFamily = $fontdata['family'];
03068             $this->FontStyle = $fontdata['style'];
03069             $this->CurrentFont = $this->getFontBuffer($fontdata['fontkey']);
03070             $this->SetFontSize($size);
03071         }
03072 
03080         public function SetFontSize($size) {
03081             
03082             $this->FontSizePt = $size;
03083             $this->FontSize = $size / $this->k;
03084             if (isset($this->CurrentFont['desc']['Ascent']) AND ($this->CurrentFont['desc']['Ascent'] > 0)) {
03085                 $this->FontAscent = $this->CurrentFont['desc']['Ascent'] * $this->FontSize / 1000;
03086             } else {
03087                 $this->FontAscent = 0.8 * $this->FontSize;
03088             }
03089             if (isset($this->CurrentFont['desc']['Descent']) AND ($this->CurrentFont['desc']['Descent'] > 0)) {
03090                 $this->FontDescent = - $this->CurrentFont['desc']['Descent'] * $this->FontSize / 1000;
03091             } else {
03092                 $this->FontDescent = 0.2 * $this->FontSize;
03093             }
03094             if (($this->page > 0) AND (isset($this->CurrentFont['i']))) {
03095                 $this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
03096             }
03097         }
03098 
03105         public function SetDefaultMonospacedFont($font) {
03106             $this->default_monospaced_font = $font;
03107         }
03108         
03116         public function AddLink() {
03117             
03118             $n = count($this->links) + 1;
03119             $this->links[$n] = array(0, 0);
03120             return $n;
03121         }
03122 
03132         public function SetLink($link, $y=0, $page=-1) {
03133             if ($y == -1) {
03134                 $y = $this->y;
03135             }
03136             if ($page == -1) {
03137                 $page = $this->page;
03138             }
03139             $this->links[$link] = array($page, $y);
03140         }
03141 
03155         public function Link($x, $y, $w, $h, $link, $spaces=0) {
03156             $this->Annotation($x, $y, $w, $h, $link, array('Subtype'=>'Link'), $spaces);
03157         }
03158         
03172         public function Annotation($x, $y, $w, $h, $text, $opt=array('Subtype'=>'Text'), $spaces=0) {
03173             
03174             if (isset($this->transfmatrix)) {
03175                 $maxid = count($this->transfmatrix) - 1;
03176                 for ($i=$maxid; $i >= 0; $i--) {
03177                     $ctm = $this->transfmatrix[$i];
03178                     if (isset($ctm['a'])) {
03179                         $x = $x * $this->k;
03180                         $y = ($this->h - $y) * $this->k;
03181                         $w = $w * $this->k;
03182                         $h = $h * $this->k;
03183                         
03184                         $xt = $x;
03185                         $yt = $y;
03186                         $x1 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
03187                         $y1 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
03188                         
03189                         $xt = $x + $w;
03190                         $yt = $y;
03191                         $x2 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
03192                         $y2 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
03193                         
03194                         $xt = $x;
03195                         $yt = $y - $h;
03196                         $x3 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
03197                         $y3 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
03198                         
03199                         $xt = $x + $w;
03200                         $yt = $y - $h;
03201                         $x4 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
03202                         $y4 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
03203                         
03204                         $x = min($x1, $x2, $x3, $x4);
03205                         $y = max($y1, $y2, $y3, $y4);
03206                         $w = (max($x1, $x2, $x3, $x4) - $x) / $this->k;
03207                         $h = ($y - min($y1, $y2, $y3, $y4)) / $this->k;
03208                         $x = $x / $this->k;
03209                         $y = $this->h - ($y / $this->k);
03210                     }
03211                 }
03212             }
03213             $this->PageAnnots[$this->page][] = array('x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'txt' => $text, 'opt' => $opt, 'numspaces' => $spaces);
03214             if (($opt['Subtype'] == 'FileAttachment') AND (!$this->empty_string($opt['FS'])) AND file_exists($opt['FS']) AND (!isset($this->embeddedfiles[basename($opt['FS'])]))) {
03215                 $this->embeddedfiles[basename($opt['FS'])] = array('file' => $opt['FS'], 'n' => ($this->n + count($this->embeddedfiles) + 10000));
03216             }
03217         }
03218 
03225         protected function _putEmbeddedFiles() {
03226             reset($this->embeddedfiles);
03227             foreach ($this->embeddedfiles as $filename => $filedata) {
03228                 $data = file_get_contents($filedata['file']);
03229                 $filter = '';
03230                 if ($this->compress) {
03231                     $data = gzcompress($data);
03232                     $filter = ' /Filter /FlateDecode';
03233                 }
03234                 $this->offsets[$filedata['n']] = $this->bufferlen;
03235                 $this->_out($filedata['n'].' 0 obj');
03236                 $this->_out('<</Type /EmbeddedFile'.$filter.' /Length '.strlen($data).' >>');
03237                 $this->_putstream($data);
03238                 $this->_out('endobj');
03239             }
03240         }
03241         
03256         public function Text($x, $y, $txt, $stroke=0, $clip=false) {
03257             
03258             if ($this->rtl) {
03259                 
03260                 $s = $this->utf8Bidi($this->UTF8StringToArray($txt), $txt, $this->tmprtl);
03261                 $l = $this->GetArrStringWidth($s);
03262                 $xr = $this->w - $x - $this->GetArrStringWidth($s);
03263             } else {
03264                 $xr = $x;
03265             }
03266             $opt = '';
03267             if (($stroke > 0) AND (!$clip)) {
03268                 $opt .= '1 Tr '.intval($stroke).' w ';
03269             } elseif (($stroke > 0) AND $clip) {
03270                 $opt .= '5 Tr '.intval($stroke).' w ';
03271             } elseif ($clip) {
03272                 $opt .= '7 Tr ';
03273             }
03274             $s = sprintf('BT %.2F %.2F Td %s(%s) Tj ET 0 Tr', $xr * $this->k, ($this->h-$y) * $this->k, $opt, $this->_escapetext($txt));
03275             if ($this->underline AND ($txt!='')) {
03276                 $s .= ' '.$this->_dounderline($xr, $y, $txt);
03277             }
03278             if ($this->linethrough AND ($txt!='')) { 
03279                 $s .= ' '.$this->_dolinethrough($xr, $y, $txt); 
03280             }
03281             if ($this->ColorFlag AND (!$clip)) {
03282                 $s='q '.$this->TextColor.' '.$s.' Q';
03283             }
03284             $this->_out($s);
03285         }
03286 
03296         public function AcceptPageBreak() {
03297             return $this->AutoPageBreak;
03298         }
03299         
03307         protected function checkPageBreak($h) {
03308             if ((($this->y + $h) > $this->PageBreakTrigger) AND (!$this->InFooter) AND ($this->AcceptPageBreak())) {
03309                 
03310                 $x = $this->x;
03311                 $this->AddPage($this->CurOrientation);
03312                 $this->y = $this->tMargin;
03313                 $oldpage = $this->page - 1;
03314                 if ($this->rtl) {
03315                     if ($this->pagedim[$this->page]['orm'] != $this->pagedim[$oldpage]['orm']) {
03316                         $this->x = $x - ($this->pagedim[$this->page]['orm'] - $this->pagedim[$oldpage]['orm']);
03317                     } else {
03318                         $this->x = $x;
03319                     }
03320                 } else {
03321                     if ($this->pagedim[$this->page]['olm'] != $this->pagedim[$oldpage]['olm']) {
03322                         $this->x = $x + ($this->pagedim[$this->page]['olm'] - $this->pagedim[$oldpage]['olm']);
03323                     } else {
03324                         $this->x = $x;
03325                     }
03326                 }
03327                 return true;
03328             }
03329             return false;
03330         }
03331 
03350         public function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=0, $link='', $stretch=0, $ignore_min_height=false) {
03351             
03352             $min_cell_height = $this->FontSize * $this->cell_height_ratio;
03353             if ($h < $min_cell_height) {
03354                 $h = $min_cell_height;
03355             }
03356             $this->checkPageBreak($h);
03357             $this->_out($this->getCellCode($w, $h, $txt, $border, $ln, $align, $fill, $link, $stretch, $ignore_min_height));
03358         }
03359 
03367         public function removeSHY($txt='') {
03368             
03369 
03370 
03371 
03372 
03373 
03374 
03375 
03376 
03377 
03378             $txt = preg_replace('/([\\xc2]{1}[\\xad]{1})/', '', $txt);
03379             if (!$this->isunicode) {
03380                 $txt = preg_replace('/([\\xad]{1})/', '', $txt);
03381             }
03382             return $txt;
03383         }
03384         
03402         protected function getCellCode($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=0, $link='', $stretch=0, $ignore_min_height=false) {
03403             $txt = $this->removeSHY($txt);
03404             $rs = ''; 
03405             if (!$ignore_min_height) {
03406                 $min_cell_height = $this->FontSize * $this->cell_height_ratio;
03407                 if ($h < $min_cell_height) {
03408                     $h = $min_cell_height;
03409                 }
03410             }
03411             $k = $this->k;
03412             if ($this->empty_string($w) OR ($w <= 0)) {
03413                 if ($this->rtl) {
03414                     $w = $this->x - $this->lMargin;
03415                 } else {
03416                     $w = $this->w - $this->rMargin - $this->x;
03417                 }
03418             }
03419             $s = '';            
03420             if (($fill == 1) OR ($border == 1)) {
03421                 if ($fill == 1) {
03422                     $op = ($border == 1) ? 'B' : 'f';
03423                 } else {
03424                     $op = 'S';
03425                 }
03426                 if ($this->rtl) {
03427                     $xk = (($this->x  - $w) * $k);
03428                 } else {
03429                     $xk = ($this->x * $k);
03430                 }
03431                 $s .= sprintf('%.2F %.2F %.2F %.2F re %s ', $xk, (($this->h - $this->y) * $k), ($w * $k), (-$h * $k), $op);
03432             }
03433             if (is_string($border)) {
03434                 $lm = ($this->LineWidth / 2);
03435                 $x = $this->x;
03436                 $y = $this->y;
03437                 if (strpos($border,'L') !== false) {
03438                     if ($this->rtl) {
03439                         $xk = ($x - $w) * $k;
03440                     } else {
03441                         $xk = $x * $k;
03442                     }
03443                     $s .= sprintf('%.2F %.2F m %.2F %.2F l S ', $xk, (($this->h - $y + $lm) * $k), $xk, (($this->h - ($y + $h + $lm)) * $k));
03444                 }
03445                 if (strpos($border,'T') !== false) {
03446                     if ($this->rtl) {
03447                         $xk = ($x - $w + $lm) * $k;
03448                         $xwk = ($x - $lm) * $k;
03449                     } else {
03450                         $xk = ($x - $lm) * $k;
03451                         $xwk = ($x + $w + $lm) * $k;
03452                     }
03453                     $s .= sprintf('%.2F %.2F m %.2F %.2F l S ', $xk, (($this->h - $y) * $k), $xwk, (($this->h - $y) * $k));
03454                 }
03455                 if (strpos($border,'R') !== false) {
03456                     if ($this->rtl) {
03457                         $xk = $x * $k;
03458                     } else {
03459                         $xk = ($x + $w) * $k;
03460                     }
03461                     $s .= sprintf('%.2F %.2F m %.2F %.2F l S ', $xk, (($this->h - $y + $lm) * $k), $xk, (($this->h - ($y + $h + $lm))* $k));
03462                 }
03463                 if (strpos($border,'B') !== false) {
03464                     if ($this->rtl) {
03465                         $xk = ($x - $w + $lm) * $k;
03466                         $xwk = ($x - $lm) * $k;
03467                     } else {
03468                         $xk = ($x - $lm) * $k;
03469                         $xwk = ($x + $w + $lm) * $k;
03470                     }
03471                     $s .= sprintf('%.2F %.2F m %.2F %.2F l S ', $xk, (($this->h - ($y + $h)) * $k), $xwk, (($this->h - ($y + $h)) * $k));
03472                 }
03473             }
03474             if ($txt != '') {
03475                 
03476                 $width = $this->GetStringWidth($txt);
03477                 
03478                 $ratio = ($w - (2 * $this->cMargin)) / $width;
03479                 
03480                 
03481                 if (($stretch > 0) AND (($ratio < 1) OR (($ratio > 1) AND (($stretch % 2) == 0)))) {
03482                     if ($stretch > 2) {
03483                         
03484                         
03485                         $char_space = (($w - $width - (2 * $this->cMargin)) * $this->k) / max($this->GetNumChars($txt)-1,1);
03486                         
03487                         $rs .= sprintf('BT %.2F Tc ET ', $char_space);
03488                     } else {
03489                         
03490                         
03491                         $horiz_scale = $ratio * 100.0;
03492                         
03493                         $rs .= sprintf('BT %.2F Tz ET ', $horiz_scale);
03494                     }
03495                     $align = '';
03496                     $width = $w - (2 * $this->cMargin);
03497                 } else {
03498                     $stretch == 0;
03499                 }
03500                 if ($align == 'L') {
03501                     if ($this->rtl) {
03502                         $dx = $w - $width - $this->cMargin;
03503                     } else {
03504                         $dx = $this->cMargin;
03505                     }
03506                 } elseif ($align == 'R') {
03507                     if ($this->rtl) {
03508                         $dx = $this->cMargin;
03509                     } else {
03510                         $dx = $w - $width - $this->cMargin;
03511                     }
03512                 } elseif ($align == 'C') {
03513                     $dx = ($w - $width) / 2;
03514                 } elseif ($align == 'J') {
03515                     if ($this->rtl) {
03516                         $dx = $w - $width - $this->cMargin;
03517                     } else {
03518                         $dx = $this->cMargin;
03519                     }
03520                 } else {
03521                     $dx = $this->cMargin;
03522                 }
03523                 if ($this->ColorFlag) {
03524                     $s .= 'q '.$this->TextColor.' ';
03525                 }
03526                 $txt2 = $this->_escapetext($txt);
03527                 if ($this->rtl) {
03528                     $xdk = ($this->x - $dx - $width) * $k;
03529                 } else {
03530                     $xdk = ($this->x + $dx) * $k;
03531                 }
03532                 
03533                 if ($align == 'J') {
03534                     
03535                     $ns = substr_count($txt, ' ');
03536                     if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
03537                         
03538                         $width = $this->GetStringWidth(str_replace(' ', '', $txt));
03539                         
03540                         $spacewidth = ($w - $width - (2 * $this->cMargin)) / ($ns?$ns:1) / $this->FontSize / $this->k;
03541                         
03542                         $txt2 = str_replace(chr(0).' ', ') '.(-2830 * $spacewidth).' (', $txt2);
03543                     } else {
03544                         
03545                         $width = $this->GetStringWidth($txt);
03546                         $spacewidth = (($w - $width - (2 * $this->cMargin)) / ($ns?$ns:1)) * $this->k;
03547                         $rs .= sprintf('BT %.3F Tw ET ', $spacewidth);
03548                     }
03549                 }
03550                 
03551                 
03552                 $basefonty = $this->y + ($h/2) + ($this->FontSize/3);
03553                 
03554                 $s .= sprintf('BT %.2F %.2F Td [(%s)] TJ ET', $xdk, (($this->h - $basefonty) * $k), $txt2);
03555                 if ($this->rtl) {
03556                     $xdx = $this->x - $dx - $width;
03557                 } else {
03558                     $xdx = $this->x + $dx;
03559                 }
03560                 if ($this->underline)  {
03561                     $s .= ' '.$this->_dounderline($xdx, $basefonty, $txt);
03562                 }
03563                 if ($this->linethrough) { 
03564                     $s .= ' '.$this->_dolinethrough($xdx, $basefonty, $txt);
03565                 }
03566                 if ($this->ColorFlag) {
03567                     $s .= ' Q';
03568                 }
03569                 if ($link) {
03570                     $this->Link($xdx, $this->y + (($h - $this->FontSize)/2), $width, $this->FontSize, $link, substr_count($txt, chr(32)));
03571                 }
03572             }
03573             
03574             if ($s) {
03575                 
03576                 $rs .= $s;
03577                 
03578                 if ($stretch > 2) {
03579                     
03580                     $rs .= ' BT 0 Tc ET';
03581                 } elseif ($stretch > 0) {
03582                     
03583                     $rs .= ' BT 100 Tz ET';
03584                 }
03585             }
03586             
03587             if (!(($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) AND ($align == 'J')) {
03588                 $rs .= ' BT 0 Tw ET';
03589             }
03590             $this->lasth = $h;
03591             if ($ln > 0) {
03592                 
03593                 $this->y += $h;
03594                 if ($ln == 1) {
03595                     if ($this->rtl) {
03596                         $this->x = $this->w - $this->rMargin;
03597                     } else {
03598                         $this->x = $this->lMargin;
03599                     }
03600                 }
03601             } else {
03602                 
03603                 if ($this->rtl) {
03604                     $this->x -= $w;
03605                 } else {
03606                     $this->x += $w;
03607                 }
03608             }
03609             $gstyles = ''.$this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor.' '.$this->FillColor."\n";
03610             $rs = $gstyles.$rs;
03611             return $rs;
03612         }
03613 
03637         public function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=0, $ln=1, $x='', $y='', $reseth=true, $stretch=0, $ishtml=false, $autopadding=true, $maxh=0) { 
03638             if ($this->empty_string($this->lasth) OR $reseth) {
03639                 
03640                 $this->lasth = $this->FontSize * $this->cell_height_ratio;
03641             }
03642             if (!$this->empty_string($y)) {
03643                 $this->SetY($y);
03644             } else {
03645                 $y = $this->GetY();
03646             }
03647             
03648             $this->checkPageBreak($h);
03649             $y = $this->GetY();
03650             
03651             $startpage = $this->page;
03652             if (!$this->empty_string($x)) {
03653                 $this->SetX($x);
03654             } else {
03655                 $x = $this->GetX();
03656             }
03657             if ($this->empty_string($w) OR ($w <= 0)) {
03658                 if ($this->rtl) {
03659                     $w = $this->x - $this->lMargin;
03660                 } else {
03661                     $w = $this->w - $this->rMargin - $this->x;
03662                 }
03663             }
03664             
03665             $lMargin = $this->lMargin;
03666             $rMargin = $this->rMargin;
03667             if ($this->rtl) {
03668                 $this->SetRightMargin($this->w - $this->x);
03669                 $this->SetLeftMargin($this->x - $w);
03670             } else {
03671                 $this->SetLeftMargin($this->x);
03672                 $this->SetRightMargin($this->w - $this->x - $w);
03673             }
03674             $starty = $this->y;
03675             if ($autopadding) {
03676                 
03677                 if ($this->cMargin < ($this->LineWidth / 2)) {
03678                     $this->cMargin = ($this->LineWidth / 2);
03679                 }
03680                 
03681                 if (($this->lasth - $this->FontSize) < $this->LineWidth) {
03682                     $this->y += $this->LineWidth / 2;
03683                 }
03684                 
03685                 $this->y += $this->cMargin;
03686             }
03687             if ($ishtml) {
03688                 
03689                 $this->writeHTML($txt, true, 0, $reseth, true, $align);
03690                 $nl = 1;
03691             } else {
03692                 
03693                 $nl = $this->Write($this->lasth, $txt, '', 0, $align, true, $stretch, false, false, $maxh);
03694             }
03695             if ($autopadding) {
03696                 
03697                 $this->y += $this->cMargin;
03698                 
03699                 if (($this->lasth - $this->FontSize) < $this->LineWidth) {
03700                     $this->y += $this->LineWidth / 2;
03701                 }
03702             }
03703             
03704             $currentY = $this->y;
03705             
03706             $endpage = $this->page;
03707             
03708             if ($endpage > $startpage) {
03709                 
03710                 for ($page=$startpage; $page <= $endpage; ++$page) {
03711                     $this->setPage($page);
03712                     if ($page == $startpage) {
03713                         $this->y = $starty; 
03714                         $h = $this->getPageHeight() - $starty - $this->getBreakMargin();
03715                         $cborder = $this->getBorderMode($border, $position='start');
03716                     } elseif ($page == $endpage) {
03717                         $this->y = $this->tMargin; 
03718                         $h = $currentY - $this->tMargin;
03719                         $cborder = $this->getBorderMode($border, $position='end');
03720                     } else {
03721                         $this->y = $this->tMargin; 
03722                         $h = $this->getPageHeight() - $this->tMargin - $this->getBreakMargin();
03723                         $cborder = $this->getBorderMode($border, $position='middle');
03724                     }
03725                     $nx = $x;
03726                     
03727                     if ($page > $startpage) {
03728                         if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) {
03729                             $nx = $x + ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']);
03730                         } elseif ((!$this->rtl) AND ($this->pagedim[$page]['olm'] != $this->pagedim[$startpage]['olm'])) {
03731                             $nx = $x + ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']);
03732                         }
03733                     }
03734                     $this->SetX($nx);
03735                     $ccode = $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, false);
03736                     if ($cborder OR $fill) {
03737                         $pagebuff = $this->getPageBuffer($this->page);
03738                         $pstart = substr($pagebuff, 0, $this->intmrk[$this->page]);
03739                         $pend = substr($pagebuff, $this->intmrk[$this->page]);
03740                         $this->setPageBuffer($this->page, $pstart.$ccode."\n".$pend);
03741                         $this->intmrk[$this->page] += strlen($ccode."\n");
03742                     }
03743                 }
03744             } else {
03745                 $h = max($h, ($currentY - $y));
03746                 
03747                 $this->SetY($y); 
03748                 $this->SetX($x);
03749                 
03750                 $ccode = $this->getCellCode($w, $h, '', $border, 1, '', $fill, '', 0, true);
03751                 if ($border OR $fill) {
03752                     if (end($this->transfmrk[$this->page]) !== false) {
03753                         $pagemarkkey = key($this->transfmrk[$this->page]);
03754                         $pagemark = &$this->transfmrk[$this->page][$pagemarkkey];
03755                     } elseif ($this->InFooter) {
03756                         $pagemark = &$this->footerpos[$this->page];
03757                     } else {
03758                         $pagemark = &$this->intmrk[$this->page];
03759                     }
03760                     $pagebuff = $this->getPageBuffer($this->page);
03761                     $pstart = substr($pagebuff, 0, $pagemark);
03762                     $pend = substr($pagebuff, $pagemark);
03763                     $this->setPageBuffer($this->page, $pstart.$ccode."\n".$pend);
03764                     $pagemark += strlen($ccode."\n");
03765                 }
03766             }
03767             
03768             $currentY = $this->GetY();
03769             
03770             $this->SetLeftMargin($lMargin);
03771             $this->SetRightMargin($rMargin);
03772             if ($ln > 0) {
03773                 
03774                 $this->SetY($currentY);
03775                 if ($ln == 2) {
03776                     $this->SetX($x + $w);
03777                 }
03778             } else {
03779                 
03780                 $this->setPage($startpage);
03781                 $this->y = $y;
03782                 $this->SetX($x + $w);
03783             }
03784             return $nl;
03785         }
03786 
03795         protected function getBorderMode($border, $position='start') {
03796             if ((!$this->opencell) AND ($border == 1)) {
03797                 return 1;
03798             }
03799             $cborder = '';
03800             switch ($position) {
03801                 case 'start': {
03802                     if ($border == 1) {
03803                         $cborder = 'LTR';
03804                     } else {
03805                         if (!(false === strpos($border, 'L'))) {
03806                             $cborder .= 'L';
03807                         }
03808                         if (!(false === strpos($border, 'T'))) {
03809                             $cborder .= 'T';
03810                         }
03811                         if (!(false === strpos($border, 'R'))) {
03812                             $cborder .= 'R';
03813                         }
03814                         if ((!$this->opencell) AND (!(false === strpos($border, 'B')))) {
03815                             $cborder .= 'B';
03816                         }
03817                     }
03818                     break;
03819                 }
03820                 case 'middle': {
03821                     if ($border == 1) {
03822                         $cborder = 'LR';
03823                     } else {
03824                         if (!(false === strpos($border, 'L'))) {
03825                             $cborder .= 'L';
03826                         }
03827                         if ((!$this->opencell) AND (!(false === strpos($border, 'T')))) {
03828                             $cborder .= 'T';
03829                         }
03830                         if (!(false === strpos($border, 'R'))) {
03831                             $cborder .= 'R';
03832                         }
03833                         if ((!$this->opencell) AND (!(false === strpos($border, 'B')))) {
03834                             $cborder .= 'B';
03835                         }
03836                     }
03837                     break;
03838                 }
03839                 case 'end': {
03840                     if ($border == 1) {
03841                         $cborder = 'LRB';
03842                     } else {
03843                         if (!(false === strpos($border, 'L'))) {
03844                             $cborder .= 'L';
03845                         }
03846                         if ((!$this->opencell) AND (!(false === strpos($border, 'T')))) {
03847                             $cborder .= 'T';
03848                         }
03849                         if (!(false === strpos($border, 'R'))) {
03850                             $cborder .= 'R';
03851                         }
03852                         if (!(false === strpos($border, 'B'))) {
03853                             $cborder .= 'B';
03854                         }
03855                     }
03856                     break;
03857                 }
03858                 default: {
03859                     $cborder = $border;
03860                     break;
03861                 }
03862             }
03863             return $cborder;
03864         }
03865 
03874         public function getNumLines($txt, $w=0) {
03875             $lines = 0;
03876             if ($this->empty_string($w) OR ($w <= 0)) {
03877                 if ($this->rtl) {
03878                     $w = $this->x - $this->lMargin;
03879                 } else {
03880                     $w = $this->w - $this->rMargin - $this->x;
03881                 }
03882             }
03883             
03884             $wmax = $w - (2 * $this->cMargin);
03885             
03886             $txt = str_replace("\r", '', $txt);
03887             
03888             if (substr($txt,-1) == "\n") {
03889                 $txt = substr($txt, 0, -1);
03890             }
03891             
03892             $txtblocks = explode("\n", $txt);
03893             
03894             foreach ($txtblocks as $block) {
03895                 
03896                 $lines += $this->empty_string($block) ? 1 : (ceil($this->GetStringWidth($block) / $wmax));
03897             }
03898             return $lines;
03899         }
03900             
03917         public function Write($h, $txt, $link='', $fill=0, $align='', $ln=false, $stretch=0, $firstline=false, $firstblock=false, $maxh=0) {
03918             if (strlen($txt) == 0) {
03919                 $txt = ' ';
03920             }
03921             
03922             $s = str_replace("\r", '', $txt);
03923             
03924             if (preg_match(K_RE_PATTERN_ARABIC, $s)) {
03925                 $arabic = true;
03926             } else {
03927                 $arabic = false;
03928             }
03929             
03930             if ($arabic OR $this->tmprtl OR preg_match(K_RE_PATTERN_RTL, $txt)) {
03931                 $rtlmode = true;
03932             } else {
03933                 $rtlmode = false;
03934             }
03935             
03936             $chrwidth = $this->GetCharWidth('.');
03937             
03938             $chars = $this->UTF8StringToArray($s);
03939             
03940             $uchars = $this->UTF8ArrayToUniArray($chars);
03941             
03942             $nb = count($chars);
03943             
03944             $shy_replacement = 45;
03945             $shy_replacement_char = $this->unichr($shy_replacement);
03946             
03947             $shy_replacement_width = $this->GetCharWidth($shy_replacement);
03948             
03949             $prevx = $this->x;
03950             $prevy = $this->y;
03951             
03952             $maxy = $this->y + $maxh - $h - (2 * $this->cMargin);
03953             
03954             if ($this->rtl) {
03955                 $w = $this->x - $this->lMargin;
03956             } else {
03957                 $w = $this->w - $this->rMargin - $this->x;
03958             }
03959             
03960             $wmax = $w - (2 * $this->cMargin);
03961             $i = 0; 
03962             $j = 0; 
03963             $sep = -1; 
03964             $shy = false; 
03965             $l = 0; 
03966             $nl = 0; 
03967             $linebreak = false;
03968             
03969             while ($i < $nb) {
03970                 if (($maxh > 0) AND ($this->y >= $maxy) ) {
03971                     $firstline = true;
03972                 }
03973                 
03974                 $c = $chars[$i];
03975                 if ($c == 10) { 
03976                     
03977                     if ($align == 'J') {
03978                         if ($this->rtl) {
03979                             $talign = 'R';
03980                         } else {
03981                             $talign = 'L';
03982                         }
03983                     } else {
03984                         $talign = $align;
03985                     }
03986                     $tmpstr = $this->UniArrSubString($uchars, $j, $i);
03987                     if ($firstline) {
03988                         $startx = $this->x;
03989                         $tmparr = array_slice($chars, $j, $i);
03990                         if ($rtlmode) {
03991                             $tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
03992                         }
03993                         $linew = $this->GetArrStringWidth($tmparr);
03994                         unset($tmparr);
03995                         if ($this->rtl) {
03996                             $this->endlinex = $startx - $linew;
03997                         } else {
03998                             $this->endlinex = $startx + $linew;
03999                         }
04000                         $w = $linew;
04001                         $tmpcmargin = $this->cMargin;
04002                         if ($maxh == 0) {
04003                             $this->cMargin = 0;
04004                         }
04005                     }
04006                     $this->Cell($w, $h, $tmpstr, 0, 1, $talign, $fill, $link, $stretch);
04007                     unset($tmpstr);
04008                     if ($firstline) {
04009                         $this->cMargin = $tmpcmargin;
04010                         return ($this->UniArrSubString($uchars, $i));
04011                     }
04012                     ++$nl;
04013                     $j = $i + 1;
04014                     $l = 0;
04015                     $sep = -1;
04016                     $shy = false;
04017                     
04018                     if ((($this->y + $this->lasth) > $this->PageBreakTrigger) AND (!$this->InFooter)) {
04019                         
04020                         $this->AcceptPageBreak();
04021                     }
04022                     $w = $this->getRemainingWidth();
04023                     $wmax = $w - (2 * $this->cMargin);
04024                 } else {
04025                     
04026                     
04027                     
04028                     
04029                     
04030                     if (($c != 160) AND (($c == 173) OR preg_match($this->re_spaces, $this->unichr($c)))) {
04031                         
04032                         $sep = $i;
04033                         
04034                         if ($c == 173) {
04035                             $shy = true;
04036                         } else {
04037                             $shy = false;
04038                         }
04039                     }
04040                     
04041                     if ((($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) AND ($arabic)) {
04042                         
04043                         
04044                         $l = $this->GetArrStringWidth($this->utf8Bidi(array_slice($chars, $j, $i-$j+1), '', $this->tmprtl));
04045                     } else {
04046                         $l += $this->GetCharWidth($c);
04047                     }
04048                     if (($l > $wmax) OR ($shy AND (($l + $shy_replacement_width) > $wmax)) ) {
04049                         
04050                         if ($sep == -1) {
04051                             
04052                             if (($this->rtl AND ($this->x <= ($this->w - $this->rMargin - $chrwidth)))
04053                                 OR ((!$this->rtl) AND ($this->x >= ($this->lMargin + $chrwidth)))) {
04054                                 
04055                                 $this->Cell($w, $h, '', 0, 1);
04056                                 $linebreak = true;
04057                                 if ($firstline) {
04058                                     return ($this->UniArrSubString($uchars, $j));
04059                                 }
04060                             } else {
04061                                 
04062                                 $tmpstr = $this->UniArrSubString($uchars, $j, $i);
04063                                 if ($firstline) {
04064                                     $startx = $this->x;
04065                                     $tmparr = array_slice($chars, $j, $i);
04066                                     if ($rtlmode) {
04067                                         $tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
04068                                     }
04069                                     $linew = $this->GetArrStringWidth($tmparr);
04070                                     unset($tmparr);
04071                                     if ($this->rtl) {
04072                                         $this->endlinex = $startx - $linew;
04073                                     } else {
04074                                         $this->endlinex = $startx + $linew;
04075                                     }
04076                                     $w = $linew;
04077                                     $tmpcmargin = $this->cMargin;
04078                                     if ($maxh == 0) {
04079                                         $this->cMargin = 0;
04080                                     }
04081                                 }
04082                                 $this->Cell($w, $h, $tmpstr, 0, 1, $align, $fill, $link, $stretch);
04083                                 unset($tmpstr);
04084                                 if ($firstline) {
04085                                     $this->cMargin = $tmpcmargin;
04086                                     return ($this->UniArrSubString($uchars, $i));
04087                                 }
04088                                 $j = $i;
04089                                 --$i;
04090                             }   
04091                         } else {
04092                             
04093                             if ($this->rtl AND (!$firstblock)) {
04094                                 $endspace = 1;
04095                             } else {
04096                                 $endspace = 0;
04097                             }
04098                             if ($shy) {
04099                                 
04100                                 $shy_width = $shy_replacement_width;
04101                                 if ($this->rtl) {
04102                                     $shy_char_left = $shy_replacement_char;
04103                                     $shy_char_right = '';
04104                                 } else {
04105                                     $shy_char_left = '';
04106                                     $shy_char_right = $shy_replacement_char;
04107                                 }
04108                             } else {
04109                                 $shy_width = 0;
04110                                 $shy_char_left = '';
04111                                 $shy_char_right = '';
04112                             }
04113                             $tmpstr = $this->UniArrSubString($uchars, $j, ($sep + $endspace));
04114                             if ($firstline) {
04115                                 $startx = $this->x;
04116                                 $tmparr = array_slice($chars, $j, ($sep + $endspace));
04117                                 if ($rtlmode) {
04118                                     $tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
04119                                 }
04120                                 $linew = $this->GetArrStringWidth($tmparr);
04121                                 unset($tmparr);
04122                                 if ($this->rtl) {
04123                                     $this->endlinex = $startx - $linew - $shy_width;
04124                                 } else {
04125                                     $this->endlinex = $startx + $linew + $shy_width;
04126                                 }
04127                                 $w = $linew;
04128                                 $tmpcmargin = $this->cMargin;
04129                                 if ($maxh == 0) {
04130                                     $this->cMargin = 0;
04131                                 }
04132                             }
04133                             
04134                             $this->Cell($w, $h, $shy_char_left.$tmpstr.$shy_char_right, 0, 1, $align, $fill, $link, $stretch);
04135                             unset($tmpstr);
04136                             if ($firstline) {
04137                                 
04138                                 $this->cMargin = $tmpcmargin;
04139                                 return ($this->UniArrSubString($uchars, ($sep + $endspace)));
04140                             }
04141                             $i = $sep;
04142                             $sep = -1;
04143                             $shy = false;
04144                             $j = ($i+1);
04145                         }
04146                         
04147                         if ((($this->y + $this->lasth) > $this->PageBreakTrigger) AND (!$this->InFooter)) {
04148                             
04149                             $this->AcceptPageBreak();
04150                         }
04151                         $w = $this->getRemainingWidth();
04152                         $wmax = $w - (2 * $this->cMargin);
04153                         if ($linebreak) {
04154                             $linebreak = false;
04155                         } else {
04156                             ++$nl;
04157                             $l = 0;
04158                         }
04159                     }
04160                 }
04161                 ++$i;
04162             } 
04163             
04164             if ($l > 0) {
04165                 switch ($align) {
04166                     case 'J':
04167                     case 'C': {
04168                         $w = $w;
04169                         break;
04170                     }
04171                     case 'L': {
04172                         if ($this->rtl) {
04173                             $w = $w;
04174                         } else {
04175                             $w = $l;
04176                         }
04177                         break;
04178                     }
04179                     case 'R': {
04180                         if ($this->rtl) {
04181                             $w = $l;
04182                         } else {
04183                             $w = $w;
04184                         }
04185                         break;
04186                     }
04187                     default: {
04188                         $w = $l;
04189                         break;
04190                     }
04191                 }
04192                 $tmpstr = $this->UniArrSubString($uchars, $j, $nb);
04193                 if ($firstline) {
04194                     $startx = $this->x;
04195                     $tmparr = array_slice($chars, $j, $nb);
04196                     if ($rtlmode) {
04197                         $tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
04198                     }
04199                     $linew = $this->GetArrStringWidth($tmparr);
04200                     unset($tmparr);
04201                     if ($this->rtl) {
04202                         $this->endlinex = $startx - $linew;
04203                     } else {
04204                         $this->endlinex = $startx + $linew;
04205                     }
04206                     $w = $linew;
04207                     $tmpcmargin = $this->cMargin;
04208                     if ($maxh == 0) {
04209                         $this->cMargin = 0;
04210                     }
04211                 }
04212                 $this->Cell($w, $h, $tmpstr, 0, $ln, $align, $fill, $link, $stretch);
04213                 unset($tmpstr);
04214                 if ($firstline) {
04215                     $this->cMargin = $tmpcmargin;
04216                     return ($this->UniArrSubString($uchars, $nb));
04217                 }
04218                 ++$nl;
04219             }
04220             if ($firstline) {
04221                 return '';
04222             }
04223             return $nl;
04224         }
04225                 
04231         protected function getRemainingWidth() {
04232             if ($this->rtl) {
04233                 return ($this->x - $this->lMargin);
04234             } else {
04235                 return ($this->w - $this->rMargin - $this->x);
04236             }
04237         }
04238 
04247         public function UTF8ArrSubString($strarr, $start='', $end='') {
04248             if (strlen($start) == 0) {
04249                 $start = 0;
04250             }
04251             if (strlen($end) == 0) {
04252                 $end = count($strarr);
04253             }
04254             $string = '';
04255             for ($i=$start; $i < $end; ++$i) {
04256                 $string .= $this->unichr($strarr[$i]);
04257             }
04258             return $string;
04259         }
04260 
04270         public function UniArrSubString($uniarr, $start='', $end='') {
04271             if (strlen($start) == 0) {
04272                 $start = 0;
04273             }
04274             if (strlen($end) == 0) {
04275                 $end = count($uniarr);
04276             }
04277             $string = '';
04278             for ($i=$start; $i < $end; ++$i) {
04279                 $string .= $uniarr[$i];
04280             }
04281             return $string;
04282         }
04283 
04291         public function UTF8ArrayToUniArray($ta) {
04292             return array_map(array($this, 'unichr'), $ta);
04293         }
04294         
04303         public function unichr($c) {
04304             if (!$this->isunicode) {
04305                 return chr($c);
04306             } elseif ($c <= 0x7F) {
04307                 
04308                 return chr($c);
04309             } elseif ($c <= 0x7FF) {
04310                 
04311                 return chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F);
04312             } elseif ($c <= 0xFFFF) {
04313                 
04314                 return chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
04315             } elseif ($c <= 0x10FFFF) {
04316                 
04317                 return chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
04318             } else {
04319                 return '';
04320             }
04321         }
04322         
04352         public function Image($file, $x='', $y='', $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0) {
04353             if ($x === '') {
04354                 $x = $this->x;
04355             }
04356             if ($y === '') {
04357                 $y = $this->y;
04358             }
04359             
04360             $imsize = @getimagesize($file);
04361             if ($imsize === FALSE) {
04362                 
04363                 $file = str_replace(' ', '%20', $file);
04364                 $imsize = @getimagesize($file);
04365                 if ($imsize === FALSE) {
04366                     $this->Error('[Image] No such file or directory in '.$file);
04367                 }
04368             }
04369             
04370             list($pixw, $pixh) = $imsize;
04371             
04372             if (($w <= 0) AND ($h <= 0)) {
04373                 
04374                 $w = $this->pixelsToUnits($pixw);
04375                 $h = $this->pixelsToUnits($pixh);
04376             } elseif ($w <= 0) {
04377                 $w = $h * $pixw / $pixh;
04378             } elseif ($h <= 0) {
04379                 $h = $w * $pixh / $pixw;
04380             }
04381             
04382             $neww = round($w * $this->k * $dpi / $this->dpi);
04383             $newh = round($h * $this->k * $dpi / $this->dpi);
04384             
04385             if (($neww * $newh) >= ($pixw * $pixh)) {
04386                 $resize = false;
04387             }
04388             
04389             if (!in_array($file, $this->imagekeys)) {
04390                 
04391                 if ($type == '') {
04392                     $fileinfo = pathinfo($file);
04393                     if (isset($fileinfo['extension']) AND (!$this->empty_string($fileinfo['extension']))) {
04394                         $type = $fileinfo['extension'];
04395                     } else {
04396                         $this->Error('Image file has no extension and no type was specified: '.$file);
04397                     }
04398                 }
04399                 $type = strtolower($type);
04400                 if ($type == 'jpg') {
04401                     $type = 'jpeg';
04402                 }
04403                 $mqr = get_magic_quotes_runtime();
04404                 set_magic_quotes_runtime(0);
04405                 
04406                 $mtd = '_parse'.$type;
04407                 
04408                 $gdfunction = 'imagecreatefrom'.$type;
04409                 $info = false;
04410                 if ((method_exists($this, $mtd)) AND (!($resize AND function_exists($gdfunction)))) {
04411                     
04412                     $info = $this->$mtd($file);
04413                     if ($info == 'pngalpha') {
04414                         return $this->ImagePngAlpha($file, $x, $y, $w, $h, 'PNG', $link, $align, $resize, $dpi, $palign);
04415                     }
04416                 } 
04417                 if (!$info) {
04418                     if (function_exists($gdfunction)) {
04419                         
04420                         $img = $gdfunction($file);
04421                         if ($resize) {
04422                             $imgr = imagecreatetruecolor($neww, $newh);
04423                             imagecopyresampled($imgr, $img, 0, 0, 0, 0, $neww, $newh, $pixw, $pixh); 
04424                             $info = $this->_toJPEG($imgr);
04425                         } else {
04426                             $info = $this->_toJPEG($img);
04427                         }
04428                     } elseif (extension_loaded('imagick')) {
04429                         
04430                         $img = new Imagick();
04431                         $img->readImage($file);
04432                         if ($resize) {
04433                             $img->resizeImage($neww, $newh, 10, 1, false);
04434                         }
04435                         $img->setCompressionQuality($this->jpeg_quality);
04436                         $img->setImageFormat('jpeg');
04437                         $tempname = tempnam(K_PATH_CACHE, 'jpg_');
04438                         $img->writeImage($tempname);
04439                         $info = $this->_parsejpeg($tempname);
04440                         unlink($tempname);
04441                         $img->destroy();
04442                     } else {
04443                         return;
04444                     }
04445                 }
04446                 if ($info === false) {
04447                     
04448                     return;
04449                 }
04450                 set_magic_quotes_runtime($mqr);
04451                 if ($ismask) {
04452                     
04453                     $info['cs'] = 'DeviceGray';
04454                 }
04455                 $info['i'] = $this->numimages + 1;
04456                 if ($imgmask !== false) {
04457                     $info['masked'] = $imgmask;
04458                 }
04459                 
04460                 $this->setImageBuffer($file, $info);
04461             } else {
04462                 $info = $this->getImageBuffer($file);
04463             }
04464             
04465             if ((($y + $h) > $this->PageBreakTrigger) AND (!$this->InFooter) AND $this->AcceptPageBreak()) {
04466                 
04467                 $this->AddPage($this->CurOrientation);
04468                 
04469                 $y = $this->GetY() + $this->cMargin;
04470             }
04471             
04472             $this->img_rb_y = $y + $h;
04473             
04474             if ($this->rtl) {
04475                 if ($palign == 'L') {
04476                     $ximg = $this->lMargin;
04477                     
04478                     $this->img_rb_x = $ximg + $w;
04479                 } elseif ($palign == 'C') {
04480                     $ximg = ($this->w - $x - $w) / 2;
04481                     
04482                     $this->img_rb_x = $ximg + $w;
04483                 } else {
04484                     $ximg = $this->w - $x - $w;
04485                     
04486                     $this->img_rb_x = $ximg;
04487                 }
04488             } else {
04489                 if ($palign == 'R') {
04490                     $ximg = $this->w - $this->rMargin - $w;
04491                     
04492                     $this->img_rb_x = $ximg;
04493                 } elseif ($palign == 'C') {
04494                     $ximg = ($this->w - $x - $w) / 2;
04495                     
04496                     $this->img_rb_x = $ximg + $w;
04497                 } else {
04498                     $ximg = $x;
04499                     
04500                     $this->img_rb_x = $ximg + $w;
04501                 }
04502             }
04503             if ($ismask) {
04504                 
04505                 $xkimg = ($this->pagedim[$this->page]['w'] + 10);
04506             } else {
04507                 $xkimg = $ximg * $this->k;
04508             }
04509             $this->_out(sprintf('q %.2F 0 0 %.2F %.2F %.2F cm /I%d Do Q', ($w * $this->k), ($h * $this->k), $xkimg, (($this->h - ($y + $h)) * $this->k), $info['i']));
04510             if (!empty($border)) {
04511                 $bx = $x;
04512                 $by = $y;
04513                 $this->x = $ximg;
04514                 $this->y = $y;
04515                 $this->Cell($w, $h, '', $border, 0, '', 0, '', 0);
04516                 $this->x = $bx;
04517                 $this->y = $by;
04518             }
04519             if ($link) {
04520                 $this->Link($ximg, $y, $w, $h, $link, 0);
04521             }
04522             
04523             switch($align) {
04524                 case 'T': {
04525                     $this->y = $y;
04526                     $this->x = $this->img_rb_x;
04527                     break;
04528                 }
04529                 case 'M': {
04530                     $this->y = $y + round($h/2);
04531                     $this->x = $this->img_rb_x;
04532                     break;
04533                 }
04534                 case 'B': {
04535                     $this->y = $this->img_rb_y;
04536                     $this->x = $this->img_rb_x;
04537                     break;
04538                 }
04539                 case 'N': {
04540                     $this->SetY($this->img_rb_y);
04541                     break;
04542                 }
04543                 default:{
04544                     break;
04545                 }
04546             }
04547             $this->endlinex = $this->img_rb_x;
04548             return $info['i'];
04549         }
04550                 
04559         protected function _toJPEG($image) {
04560             $tempname = tempnam(K_PATH_CACHE, 'jpg_');
04561             imagejpeg($image, $tempname, $this->jpeg_quality);
04562             imagedestroy($image);
04563             $retvars = $this->_parsejpeg($tempname);
04564             
04565             unlink($tempname);
04566             return $retvars;
04567         }
04568         
04575         protected function _parsejpeg($file) {
04576             $a = getimagesize($file);
04577             if (empty($a)) {
04578                 $this->Error('Missing or incorrect image file: '.$file);
04579             }
04580             if ($a[2] != 2) {
04581                 $this->Error('Not a JPEG file: '.$file);
04582             }
04583             if ((!isset($a['channels'])) OR ($a['channels'] == 3)) {
04584                 $colspace = 'DeviceRGB';
04585             } elseif ($a['channels'] == 4) {
04586                 $colspace = 'DeviceCMYK';
04587             } else {
04588                 $colspace = 'DeviceGray';
04589             }
04590             $bpc = isset($a['bits']) ? $a['bits'] : 8;
04591             $data = file_get_contents($file);
04592             return array('w' => $a[0], 'h' => $a[1], 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'DCTDecode', 'data' => $data);
04593         }
04594 
04601         protected function _parsepng($file) {
04602             $f = fopen($file, 'rb');
04603             if ($f === false) {
04604                 $this->Error('Can\'t open image file: '.$file);
04605             }
04606             
04607             if (fread($f, 8) != chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
04608                 $this->Error('Not a PNG file: '.$file);
04609             }
04610             
04611             fread($f, 4);
04612             if (fread($f, 4) != 'IHDR') {
04613                 $this->Error('Incorrect PNG file: '.$file);
04614             }
04615             $w = $this->_freadint($f);
04616             $h = $this->_freadint($f);
04617             $bpc = ord(fread($f, 1));
04618             if ($bpc > 8) {
04619                 
04620                 fclose($f);
04621                 return false;
04622             }
04623             $ct = ord(fread($f, 1));
04624             if ($ct == 0) {
04625                 $colspace = 'DeviceGray';
04626             } elseif ($ct == 2) {
04627                 $colspace = 'DeviceRGB';
04628             } elseif ($ct == 3) {
04629                 $colspace = 'Indexed';
04630             } else {
04631                 
04632                 fclose($f);
04633                 return 'pngalpha';
04634             }
04635             if (ord(fread($f, 1)) != 0) {
04636                 
04637                 fclose($f);
04638                 return false;
04639             }
04640             if (ord(fread($f, 1)) != 0) {
04641                 
04642                 fclose($f);
04643                 return false;
04644             }
04645             if (ord(fread($f, 1)) != 0) {
04646                 
04647                 fclose($f);
04648                 return false;
04649             }
04650             fread($f, 4);
04651             $parms = '/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
04652             
04653             $pal = '';
04654             $trns = '';
04655             $data = '';
04656             do {
04657                 $n = $this->_freadint($f);
04658                 $type = fread($f, 4);
04659                 if ($type == 'PLTE') {
04660                     
04661                     $pal = $this->rfread($f, $n);
04662                     fread($f, 4);
04663                 } elseif ($type == 'tRNS') {
04664                     
04665                     $t = $this->rfread($f, $n);
04666                     if ($ct == 0) {
04667                         $trns = array(ord(substr($t, 1, 1)));
04668                     } elseif ($ct == 2) {
04669                         $trns = array(ord(substr($t, 1, 1)), ord(substr($t, 3, 1)), ord(substr($t, 5, 1)));
04670                     } else {
04671                         $pos = strpos($t, chr(0));
04672                         if ($pos !== false) {
04673                             $trns = array($pos);
04674                         }
04675                     }
04676                     fread($f, 4);
04677                 } elseif ($type == 'IDAT') {
04678                     
04679                     $data .= $this->rfread($f, $n);
04680                     fread($f, 4);
04681                 } elseif ($type == 'IEND') {
04682                     break;
04683                 } else {
04684                     $this->rfread($f, $n + 4);
04685                 }
04686             } while ($n);
04687             if (($colspace == 'Indexed') AND (empty($pal))) {
04688                 
04689                 fclose($f);
04690                 return false;
04691             }
04692             fclose($f);
04693             return array('w' => $w, 'h' => $h, 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'FlateDecode', 'parms' => $parms, 'pal' => $pal, 'trns' => $trns, 'data' => $data);
04694         }
04695 
04706         protected function rfread($handle, $length) {
04707             $data = fread($handle, $length);
04708             if ($data === false) {
04709                 return false;
04710             }
04711             $rest = $length - strlen($data);
04712             if ($rest > 0) {
04713                 $data .= $this->rfread($handle, $rest);
04714             }
04715             return $data;
04716         }
04717 
04736         protected function ImagePngAlpha($file, $x='', $y='', $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='') {
04737             
04738             list($wpx, $hpx) = getimagesize($file);
04739             
04740             $img = imagecreatefrompng($file);
04741             $imgalpha = imagecreate($wpx, $hpx);
04742             
04743             for($c = 0; $c < 256; ++$c) {
04744                 ImageColorAllocate($imgalpha, $c, $c, $c);
04745             }
04746             
04747             for ($xpx = 0; $xpx < $wpx; ++$xpx) {
04748                 for ($ypx = 0; $ypx < $hpx; ++$ypx) {
04749                     $colorindex = imagecolorat($img, $xpx, $ypx);
04750                     $col = imagecolorsforindex($img, $colorindex);
04751                     imagesetpixel($imgalpha, $xpx, $ypx, $this->getGDgamma((127 - $col['alpha']) * 255 / 127));
04752                 }
04753             }
04754             
04755             $tempfile_alpha = tempnam(K_PATH_CACHE, 'mska_');
04756             imagepng($imgalpha, $tempfile_alpha);
04757             imagedestroy($imgalpha);
04758             
04759             $imgplain = imagecreatetruecolor($wpx, $hpx);
04760             imagecopy($imgplain, $img, 0, 0, 0, 0, $wpx, $hpx);
04761             
04762             $tempfile_plain = tempnam(K_PATH_CACHE, 'mskp_');
04763             imagepng($imgplain, $tempfile_plain);
04764             imagedestroy($imgplain);
04765             
04766             $imgmask = $this->Image($tempfile_alpha, $x, $y, $w, $h, 'PNG', '', '', $resize, $dpi, '', true, false);
04767             
04768             $this->Image($tempfile_plain, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, false, $imgmask);
04769             
04770             unlink($tempfile_alpha);
04771             unlink($tempfile_plain);
04772         }
04773 
04780         protected function getGDgamma($v) {
04781             return (pow(($v / 255), 2.2) * 255);
04782         } 
04783         
04793         public function Ln($h='', $cell=false) {
04794             
04795             if ($cell) {
04796                 $cellmargin = $this->cMargin;
04797             } else {
04798                 $cellmargin = 0;
04799             }
04800             if ($this->rtl) {
04801                 $this->x = $this->w - $this->rMargin - $cellmargin;
04802             } else {
04803                 $this->x = $this->lMargin + $cellmargin;
04804             }
04805             if (is_string($h)) {
04806                 $this->y += $this->lasth;
04807             } else {
04808                 $this->y += $h;
04809             }
04810             $this->newline = true;
04811         }
04812 
04821         public function GetX() {
04822             
04823             if ($this->rtl) {
04824                 return ($this->w - $this->x);
04825             } else {
04826                 return $this->x;
04827             }
04828         }
04829         
04837         public function GetAbsX() {
04838             return $this->x;
04839         }
04840         
04848         public function GetY() {
04849             
04850             return $this->y;
04851         }
04852         
04861         public function SetX($x) {
04862             
04863             if ($this->rtl) {
04864                 if ($x >= 0) {
04865                     $this->x = $this->w - $x;
04866                 } else {
04867                     $this->x = abs($x);
04868                 }
04869             } else {
04870                 if ($x >= 0) {
04871                     $this->x = $x;
04872                 } else {
04873                     $this->x = $this->w + $x;
04874                 }
04875             }
04876             if ($this->x < 0) {
04877                 $this->x = 0;
04878             }
04879             if ($this->x > $this->w) {
04880                 $this->x = $this->w;
04881             }
04882         }
04883         
04893         public function SetY($y, $resetx=true) {
04894             if ($resetx) {
04895                 
04896                 if ($this->rtl) {
04897                     $this->x = $this->w - $this->rMargin;
04898                 } else {
04899                     $this->x = $this->lMargin;
04900                 }
04901             }
04902             if ($y >= 0) {
04903                 $this->y = $y;
04904             } else {
04905                 $this->y = $this->h + $y;
04906             }
04907             if ($this->y < 0) {
04908                 $this->y = 0;
04909             }
04910             if ($this->y > $this->h) {
04911                 $this->y = $this->h;
04912             }
04913         }
04914         
04924         public function SetXY($x, $y) {
04925             
04926             $this->SetY($y);
04927             $this->SetX($x);
04928         }
04929 
04940         public function Output($name='doc.pdf', $dest='I') {
04941             
04942             
04943             if ($this->state < 3) {
04944                 $this->Close();
04945             }
04946             
04947             if (is_bool($dest)) {
04948                 $dest = $dest ? 'D' : 'F';
04949             }
04950             $dest = strtoupper($dest);
04951             if ($dest != 'F') {
04952                 $name = preg_replace('/[\s]+/', '_', $name);
04953                 $name = preg_replace('/[^a-zA-Z0-9_\.-]/', '', $name);
04954             }
04955             if ($this->sign) {
04956                 
04957                 
04958                 $pdfdoc = $this->getBuffer();
04959                 
04960                 $pdfdoc = substr($pdfdoc, 0, -1);
04961                 
04962                 if (isset($this->diskcache) AND $this->diskcache) {
04963                     
04964                     unlink($this->buffer);
04965                 }
04966                 unset($this->buffer);
04967                 
04968                 $tmppos = strpos($pdfdoc, '/ByteRange[0 ********** ********** **********]') + 58;
04969                 $pdfdoc = substr($pdfdoc, 0, $tmppos).substr($pdfdoc, $tmppos + $this->signature_max_lenght);
04970                 
04971                 $byte_range = array();
04972                 $byte_range[0] = 0;
04973                 $byte_range[1] = $tmppos - 1;
04974                 $byte_range[2] = $byte_range[1] + $this->signature_max_lenght;
04975                 $byte_range[3] = strlen($pdfdoc) - $byte_range[1];
04976                 
04977                 $byterange = sprintf('/ByteRange[0 %010u %010u %010u]', $byte_range[1], $byte_range[2], $byte_range[3]);
04978                 $pdfdoc = str_replace('/ByteRange[0 ********** ********** **********]', $byterange, $pdfdoc);
04979                 
04980                 $tempdoc = tempnam(K_PATH_CACHE, 'tmppdf_');
04981                 $f = fopen($tempdoc, 'wb');
04982                 if (!$f) {
04983                     $this->Error('Unable to create temporary file: '.$tempdoc);
04984                 }
04985                 $pdfdoc_lenght = strlen($pdfdoc);
04986                 fwrite($f, $pdfdoc, $pdfdoc_lenght);
04987                 fclose($f);
04988                 
04989                 
04990                 $tempsign = tempnam(K_PATH_CACHE, 'tmpsig_');
04991                 if (empty($this->signature_data['extracerts'])) {
04992                     openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED);
04993                 } else {
04994                     openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED, $this->signature_data['extracerts']);
04995                 }   
04996                 unlink($tempdoc);
04997                 
04998                 $signature = file_get_contents($tempsign, false, null, $pdfdoc_lenght);
04999                 unlink($tempsign);
05000                 
05001                 $signature = substr($signature, (strpos($signature, "%%EOF\n\n------") + 13));
05002                 $tmparr = explode("\n\n", $signature);
05003                 $signature = $tmparr[1];
05004                 unset($tmparr);
05005                 
05006                 $signature = base64_decode(trim($signature));
05007                 
05008                 $signature = current(unpack('H*', $signature));
05009                 $signature = str_pad($signature, $this->signature_max_lenght, '0');
05010                 
05011                 $pdfdoc = substr($pdfdoc, 0, $byte_range[1]).$signature.substr($pdfdoc, (0 - $byte_range[3]));
05012                 $this->diskcache = false;
05013                 $this->buffer = &$pdfdoc;
05014                 $this->bufferlen = strlen($pdfdoc);
05015             }
05016             switch($dest) {
05017                 case 'I': {
05018                     
05019                     if (ob_get_contents()) {
05020                         $this->Error('Some data has already been output, can\'t send PDF file');
05021                     }
05022                     if (php_sapi_name() != 'cli') {
05023                         
05024                         header('Content-Type: application/pdf');
05025                         if (headers_sent()) {
05026                             $this->Error('Some data has already been output to browser, can\'t send PDF file');
05027                         }
05028                         header('Cache-Control: public, must-revalidate, max-age=0'); 
05029                         header('Pragma: public');
05030                         header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); 
05031                         header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');  
05032                         header('Content-Length: '.$this->bufferlen);
05033                         header('Content-Disposition: inline; filename="'.basename($name).'";');
05034                     }
05035                     echo $this->getBuffer();
05036                     break;
05037                 }
05038                 case 'D': {
05039                     
05040                     if (ob_get_contents()) {
05041                         $this->Error('Some data has already been output, can\'t send PDF file');
05042                     }
05043                     header('Content-Description: File Transfer');
05044                     if (headers_sent()) {
05045                         $this->Error('Some data has already been output to browser, can\'t send PDF file');
05046                     }
05047                     header('Cache-Control: public, must-revalidate, max-age=0'); 
05048                     header('Pragma: public');
05049                     header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); 
05050                     header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
05051                     
05052                     header('Content-Type: application/force-download');
05053                     header('Content-Type: application/octet-stream', false);
05054                     header('Content-Type: application/download', false);
05055                     header('Content-Type: application/pdf', false);
05056                     
05057                     header('Content-Disposition: attachment; filename="'.basename($name).'";');
05058                     header('Content-Transfer-Encoding: binary');
05059                     header('Content-Length: '.$this->bufferlen);
05060                     echo $this->getBuffer();
05061                     break;
05062                 }
05063                 case 'F': {
05064                     
05065                     if ($this->diskcache) {
05066                         copy($this->buffer, $name);
05067                     } else {
05068                         $f = fopen($name, 'wb');
05069                         if (!$f) {
05070                             $this->Error('Unable to create output file: '.$name);
05071                         }
05072                         fwrite($f, $this->getBuffer(), $this->bufferlen);
05073                         fclose($f);
05074                     }
05075                     break;
05076                 }
05077                 case 'S': {
05078                     
05079                     return $this->getBuffer();
05080                 }
05081                 default: {
05082                     $this->Error('Incorrect output destination: '.$dest);
05083                 }
05084             }
05085             return '';
05086         }
05087 
05095         public function _destroy($destroyall=false, $preserve_objcopy=false) {
05096             if ($destroyall AND isset($this->diskcache) AND $this->diskcache AND (!$preserve_objcopy) AND (!$this->empty_string($this->buffer))) {
05097                 
05098                 unlink($this->buffer);
05099             }
05100             foreach (array_keys(get_object_vars($this)) as $val) {
05101                 if ($destroyall OR (
05102                     ($val != 'internal_encoding') 
05103                     AND ($val != 'state') 
05104                     AND ($val != 'bufferlen') 
05105                     AND ($val != 'buffer') 
05106                     AND ($val != 'diskcache')
05107                     AND ($val != 'sign')
05108                     AND ($val != 'signature_data')
05109                     AND ($val != 'signature_max_lenght')
05110                     )) {
05111                     if (!$preserve_objcopy OR ($val != 'objcopy')) {
05112                         unset($this->$val);
05113                     }
05114                 }
05115             }
05116         }
05117         
05122         protected function _dochecks() {
05123             
05124             if (1.1 == 1) {
05125                 $this->Error('Don\'t alter the locale before including class file');
05126             }
05127             
05128             if (sprintf('%.1F', 1.0) != '1.0') {
05129                 setlocale(LC_NUMERIC, 'C');
05130             }
05131         }
05132 
05138         protected function _getfontpath() {
05139             if (!defined('K_PATH_FONTS') AND is_dir(dirname(__FILE__).'/fonts')) {
05140                 define('K_PATH_FONTS', dirname(__FILE__).'/fonts/');
05141             }
05142             return defined('K_PATH_FONTS') ? K_PATH_FONTS : '';
05143         }
05144         
05149         protected function _putpages() {
05150             $nb = $this->numpages;
05151             if (!empty($this->AliasNbPages)) {
05152                 $nbs = $this->formatPageNumber($nb);
05153                 $nbu = $this->UTF8ToUTF16BE($nbs, false); 
05154                 $alias_a = $this->_escape($this->AliasNbPages);
05155                 $alias_au = $this->_escape('{'.$this->AliasNbPages.'}');
05156                 if ($this->isunicode) {
05157                     $alias_b = $this->_escape($this->UTF8ToLatin1($this->AliasNbPages));
05158                     $alias_bu = $this->_escape($this->UTF8ToLatin1('{'.$this->AliasNbPages.'}'));
05159                     $alias_c = $this->_escape($this->utf8StrRev($this->AliasNbPages, false, $this->tmprtl));
05160                     $alias_cu = $this->_escape($this->utf8StrRev('{'.$this->AliasNbPages.'}', false, $this->tmprtl));
05161                 }
05162             }
05163             if (!empty($this->AliasNumPage)) {
05164                 $alias_pa = $this->_escape($this->AliasNumPage);
05165                 $alias_pau = $this->_escape('{'.$this->AliasNumPage.'}');
05166                 if ($this->isunicode) {
05167                     $alias_pb = $this->_escape($this->UTF8ToLatin1($this->AliasNumPage));
05168                     $alias_pbu = $this->_escape($this->UTF8ToLatin1('{'.$this->AliasNumPage.'}'));
05169                     $alias_pc = $this->_escape($this->utf8StrRev($this->AliasNumPage, false, $this->tmprtl));
05170                     $alias_pcu = $this->_escape($this->utf8StrRev('{'.$this->AliasNumPage.'}', false, $this->tmprtl));
05171                 }
05172             }
05173             $pagegroupnum = 0;
05174             $filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
05175             for($n=1; $n <= $nb; ++$n) {
05176                 $temppage = $this->getPageBuffer($n);
05177                 if (!empty($this->pagegroups)) {
05178                     if(isset($this->newpagegroup[$n])) {
05179                         $pagegroupnum = 0;
05180                     }
05181                     ++$pagegroupnum;
05182                     foreach ($this->pagegroups as $k => $v) {
05183                         
05184                         $vs = $this->formatPageNumber($v);
05185                         $vu = $this->UTF8ToUTF16BE($vs, false);
05186                         $alias_ga = $this->_escape($k);
05187                         $alias_gau = $this->_escape('{'.$k.'}');
05188                         if ($this->isunicode) {
05189                             $alias_gb = $this->_escape($this->UTF8ToLatin1($k));
05190                             $alias_gbu = $this->_escape($this->UTF8ToLatin1('{'.$k.'}'));
05191                             $alias_gc = $this->_escape($this->utf8StrRev($k, false, $this->tmprtl));
05192                             $alias_gcu = $this->_escape($this->utf8StrRev('{'.$k.'}', false, $this->tmprtl));
05193                         }
05194                         $temppage = str_replace($alias_gau, $vu, $temppage);
05195                         if ($this->isunicode) {
05196                             $temppage = str_replace($alias_gbu, $vu, $temppage);
05197                             $temppage = str_replace($alias_gcu, $vu, $temppage);
05198                             $temppage = str_replace($alias_gb, $vs, $temppage);
05199                             $temppage = str_replace($alias_gc, $vs, $temppage);
05200                         }
05201                         $temppage = str_replace($alias_ga, $vs, $temppage);
05202                         
05203                         $pvs = $this->formatPageNumber($pagegroupnum);
05204                         $pvu = $this->UTF8ToUTF16BE($pvs, false);
05205                         $pk = str_replace('{nb', '{pnb', $k);
05206                         $alias_pga = $this->_escape($pk);
05207                         $alias_pgau = $this->_escape('{'.$pk.'}');
05208                         if ($this->isunicode) {
05209                             $alias_pgb = $this->_escape($this->UTF8ToLatin1($pk));
05210                             $alias_pgbu = $this->_escape($this->UTF8ToLatin1('{'.$pk.'}'));
05211                             $alias_pgc = $this->_escape($this->utf8StrRev($pk, false, $this->tmprtl));
05212                             $alias_pgcu = $this->_escape($this->utf8StrRev('{'.$pk.'}', false, $this->tmprtl));
05213                         }
05214                         $temppage = str_replace($alias_pgau, $pvu, $temppage);
05215                         if ($this->isunicode) {
05216                             $temppage = str_replace($alias_pgbu, $pvu, $temppage);
05217                             $temppage = str_replace($alias_pgcu, $pvu, $temppage);
05218                             $temppage = str_replace($alias_pgb, $pvs, $temppage);
05219                             $temppage = str_replace($alias_pgc, $pvs, $temppage);
05220                         }
05221                         $temppage = str_replace($alias_pga, $pvs, $temppage);
05222                     }
05223                 }
05224                 if (!empty($this->AliasNbPages)) {
05225                     
05226                     $temppage = str_replace($alias_au, $nbu, $temppage);
05227                     if ($this->isunicode) {
05228                         $temppage = str_replace($alias_bu, $nbu, $temppage);
05229                         $temppage = str_replace($alias_cu, $nbu, $temppage);
05230                         $temppage = str_replace($alias_b, $nbs, $temppage);
05231                         $temppage = str_replace($alias_c, $nbs, $temppage);
05232                     }
05233                     $temppage = str_replace($alias_a, $nbs, $temppage);
05234                 }
05235                 if (!empty($this->AliasNumPage)) {
05236                     
05237                     $pnbs = $this->formatPageNumber($n);
05238                     $pnbu = $this->UTF8ToUTF16BE($pnbs, false); 
05239                     $temppage = str_replace($alias_pau, $pnbu, $temppage);
05240                     if ($this->isunicode) {
05241                         $temppage = str_replace($alias_pbu, $pnbu, $temppage);
05242                         $temppage = str_replace($alias_pcu, $pnbu, $temppage);
05243                         $temppage = str_replace($alias_pb, $pnbs, $temppage);
05244                         $temppage = str_replace($alias_pc, $pnbs, $temppage);
05245                     }
05246                     $temppage = str_replace($alias_pa, $pnbs, $temppage);
05247                 }
05248                 $temppage = str_replace($this->epsmarker, '', $temppage);
05249                 
05250                 
05251                 $this->_newobj();
05252                 $this->_out('<</Type /Page');
05253                 $this->_out('/Parent 1 0 R');
05254                 $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]', $this->pagedim[$n]['w'], $this->pagedim[$n]['h']));
05255                 $this->_out('/Resources 2 0 R');
05256                 $this->_putannots($n);
05257                 $this->_out('/Contents '.($this->n + 1).' 0 R>>');
05258                 $this->_out('endobj');
05259                 
05260                 $p = ($this->compress) ? gzcompress($temppage) : $temppage;
05261                 $this->_newobj();
05262                 $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
05263                 $this->_putstream($p);
05264                 $this->_out('endobj');
05265                 if ($this->diskcache) {
05266                     
05267                     unlink($this->pages[$n]);
05268                 }
05269             }
05270             
05271             $this->offsets[1] = $this->bufferlen;
05272             $this->_out('1 0 obj');
05273             $this->_out('<</Type /Pages');
05274             $kids='/Kids [';
05275             for($i=0; $i < $nb; ++$i) {
05276                 $kids .= (3 + (2 * $i)).' 0 R ';
05277             }
05278             $this->_out($kids.']');
05279             $this->_out('/Count '.$nb);
05280             
05281             $this->_out('>>');
05282             $this->_out('endobj');
05283         }
05284 
05294         protected function _putannots($n) {
05295             if (isset($this->PageAnnots[$n])) {
05296                 $annots = '/Annots [';
05297                 foreach ($this->PageAnnots[$n] as $key => $pl) {
05298                     $pl['opt'] = array_change_key_case($pl['opt'], CASE_LOWER);
05299                     $a = $pl['x'] * $this->k;
05300                     $b = $this->pagedim[$n]['h'] - ($pl['y']  * $this->k);
05301                     $c = $pl['w'] * $this->k;
05302                     $d = $pl['h'] * $this->k;
05303                     $rect = sprintf('%.2F %.2F %.2F %.2F', $a, $b, $a+$c, $b-$d);
05304                     $annots .= "\n";
05305                     $annots .= '<</Type /Annot';
05306                     $annots .= ' /Subtype /'.$pl['opt']['subtype'];
05307                     $annots .= ' /Rect ['.$rect.']';
05308                     $annots .= ' /Contents '.$this->_textstring($pl['txt']);
05309                     
05310                     $annots .= ' /NM '.$this->_textstring(sprintf('%04u-%04u', $n, $key));
05311                     $annots .= ' /M '.$this->_datastring('D:'.date('YmdHis'));
05312                     if (isset($pl['opt']['f'])) {
05313                         $val = 0;
05314                         if (is_array($pl['opt']['f'])) {
05315                             foreach ($pl['opt']['f'] as $f) {
05316                                 switch (strtolower($f)) {
05317                                     case 'invisible': {
05318                                         $val += 1 << 0;
05319                                         break;
05320                                     }
05321                                     case 'hidden': {
05322                                         $val += 1 << 1;
05323                                         break;
05324                                     }
05325                                     case 'print': {
05326                                         $val += 1 << 2;
05327                                         break;
05328                                     }
05329                                     case 'nozoom': {
05330                                         $val += 1 << 3;
05331                                         break;
05332                                     }
05333                                     case 'norotate': {
05334                                         $val += 1 << 4;
05335                                         break;
05336                                     }
05337                                     case 'noview': {
05338                                         $val += 1 << 5;
05339                                         break;
05340                                     }
05341                                     case 'readonly': {
05342                                         $val += 1 << 6;
05343                                         break;
05344                                     }
05345                                     case 'locked': {
05346                                         $val += 1 << 8;
05347                                         break;
05348                                     }
05349                                     case 'togglenoview': {
05350                                         $val += 1 << 9;
05351                                         break;
05352                                     }
05353                                     case 'lockedcontents': {
05354                                         $val += 1 << 10;
05355                                         break;
05356                                     }
05357                                     default: {
05358                                         break;
05359                                     }
05360                                 }
05361                             }
05362                         }
05363                         $annots .= ' /F '.intval($val);
05364                     }
05365                     
05366                     
05367                     $annots .= ' /Border [';
05368                     if (isset($pl['opt']['border']) AND (count($pl['opt']['border']) >= 3)) {
05369                         $annots .= intval($pl['opt']['border'][0]).' ';
05370                         $annots .= intval($pl['opt']['border'][1]).' ';
05371                         $annots .= intval($pl['opt']['border'][2]);
05372                         if (isset($pl['opt']['border'][3]) AND is_array($pl['opt']['border'][3])) {
05373                             $annots .= ' [';
05374                             foreach ($pl['opt']['border'][3] as $dash) {
05375                                 $annots .= intval($dash).' ';
05376                             }
05377                             $annots .= ']';
05378                         }
05379                     } else {
05380                         $annots .= '0 0 0';
05381                     }
05382                     $annots .= ']';
05383                     if (isset($pl['opt']['bs']) AND (is_array($pl['opt']['bs']))) {
05384                         $annots .= ' /BS <<Type /Border';
05385                         if (isset($pl['opt']['bs']['w'])) {
05386                             $annots .= ' /W '.sprintf("%.4F", floatval($pl['opt']['bs']['w']));
05387                         }
05388                         $bstyles = array('S', 'D', 'B', 'I', 'U');
05389                         if (isset($pl['opt']['bs']['s']) AND in_array($pl['opt']['bs']['s'], $bstyles)) {
05390                             $annots .= ' /S /'.$pl['opt']['bs']['s'];
05391                         }
05392                         if (isset($pl['opt']['bs']['d']) AND (is_array($pl['opt']['bs']['d']))) {
05393                             $annots .= ' /D [';
05394                             foreach ($pl['opt']['bs']['d'] as $cord) {
05395                                 $cord = floatval($cord);
05396                                 $annots .= sprintf(" %.4F", $cord);
05397                             }
05398                             $annots .= ']';
05399                         }
05400                         $annots .= '>> ';
05401                     }
05402                     if (isset($pl['opt']['be']) AND (is_array($pl['opt']['be']))) {
05403                         $annots .= ' /BE <<';
05404                         $bstyles = array('S', 'C');
05405                         if (isset($pl['opt']['be']['s']) AND in_array($pl['opt']['be']['s'], $markups)) {
05406                             $annots .= ' /S /'.$pl['opt']['bs']['s'];
05407                         } else {
05408                             $annots .= ' /S /S';
05409                         }
05410                         if (isset($pl['opt']['be']['i']) AND ($pl['opt']['be']['i'] >= 0) AND ($pl['opt']['be']['i'] <= 2)) {
05411                             $annots .= ' /I '.sprintf(" %.4F", $pl['opt']['be']['i']);
05412                         }
05413                         $annots .= '>>';
05414                     }
05415                     $annots .= ' /C [';
05416                     if (isset($pl['opt']['c']) AND (is_array($pl['opt']['c']))) {
05417                         foreach ($pl['opt']['c'] as $col) {
05418                             $col = intval($col);
05419                             $color = $col <= 0 ? 0 : ($col >= 255 ? 1 : $col / 255);
05420                             $annots .= sprintf(" %.4F", $color);
05421                         }
05422                     }
05423                     $annots .= ']';
05424                     
05425                     
05426                     $markups = array('text', 'freetext', 'line', 'square', 'circle', 'polygon', 'polyline', 'highlight',  'underline', 'squiggly', 'strikeout', 'stamp', 'caret', 'ink', 'fileattachment', 'sound');
05427                     if (in_array(strtolower($pl['opt']['subtype']), $markups)) {
05428                         
05429                         if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) {
05430                             $annots .= ' /T '.$this->_textstring($pl['opt']['t']);
05431                         }
05432                         
05433                         if (isset($pl['opt']['ca'])) {
05434                             $annots .= ' /CA '.sprintf("%.4F", floatval($pl['opt']['ca']));
05435                         }
05436                         if (isset($pl['opt']['rc'])) {
05437                             $annots .= ' /RC '.$this->_textstring($pl['opt']['rc']);
05438                         }
05439                         $annots .= ' /CreationDate '.$this->_datastring('D:'.date('YmdHis'));
05440                         
05441                         if (isset($pl['opt']['subj'])) {
05442                             $annots .= ' /Subj '.$this->_textstring($pl['opt']['subj']);
05443                         }
05444                         
05445                         
05446                         
05447                     }
05448                     switch (strtolower($pl['opt']['subtype'])) {
05449                         case 'text': {
05450                             if (isset($pl['opt']['open'])) {
05451                                 $annots .= ' /Open '. (strtolower($pl['opt']['open']) == 'true' ? 'true' : 'false');
05452                             }
05453                             $iconsapp = array('Comment', 'Help', 'Insert', 'Key', 'NewParagraph', 'Note', 'Paragraph');
05454                             if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) {
05455                                 $annots .= ' /Name /'.$pl['opt']['name'];
05456                             } else {
05457                                 $annots .= ' /Name /Note';
05458                             }
05459                             $statemodels = array('Marked', 'Review');
05460                             if (isset($pl['opt']['statemodel']) AND in_array($pl['opt']['statemodel'], $statemodels)) {
05461                                 $annots .= ' /StateModel /'.$pl['opt']['statemodel'];
05462                             } else {
05463                                 $pl['opt']['statemodel'] = 'Marked';
05464                                 $annots .= ' /StateModel /'.$pl['opt']['statemodel'];
05465                             }
05466                             if ($pl['opt']['statemodel'] == 'Marked') {
05467                                 $states = array('Accepted', 'Unmarked');
05468                             } else {
05469                                 $states = array('Accepted', 'Rejected', 'Cancelled', 'Completed', 'None');
05470                             }
05471                             if (isset($pl['opt']['state']) AND in_array($pl['opt']['state'], $states)) {
05472                                 $annots .= ' /State /'.$pl['opt']['state'];
05473                             } else {
05474                                 if ($pl['opt']['statemodel'] == 'Marked') {
05475                                     $annots .= ' /State /Unmarked';
05476                                 } else {
05477                                     $annots .= ' /State /None';
05478                                 }
05479                             }
05480                             break;
05481                         }
05482                         case 'link': {
05483                             if(is_string($pl['txt'])) {
05484                                 
05485                                 $annots .= ' /A <</S /URI /URI '.$this->_datastring($pl['txt']).'>>';
05486                             } else {
05487                                 
05488                                 $l = $this->links[$pl['txt']];
05489                                 $annots .= sprintf(' /Dest [%d 0 R /XYZ 0 %.2F null]', (1 + (2 * $l[0])), ($this->pagedim[$l[0]]['h'] - ($l[1] * $this->k)));
05490                             }
05491                             $hmodes = array('N', 'I', 'O', 'P');
05492                             if (isset($pl['opt']['h']) AND in_array($pl['opt']['h'], $hmodes)) {
05493                                 $annots .= ' /H /'.$pl['opt']['h'];
05494                             } else {
05495                                 $annots .= ' /H /I';
05496                             }
05497                             
05498                             
05499                             break;
05500                         }
05501                         case 'freetext': {
05502                             $annots .= ' /DA '.$this->_textstring($pl['txt']);
05503                             if (isset($pl['opt']['q']) AND ($pl['opt']['q'] >= 0) AND ($pl['opt']['q'] <= 2)) {
05504                                 $annots .= ' /Q '.intval($pl['opt']['q']);
05505                             }
05506                             if (isset($pl['opt']['rc'])) {
05507                                 $annots .= ' /RC '.$this->_textstring($pl['opt']['rc']);
05508                             }
05509                             if (isset($pl['opt']['ds'])) {
05510                                 $annots .= ' /DS '.$this->_textstring($pl['opt']['ds']);
05511                             }
05512                             if (isset($pl['opt']['cl']) AND is_array($pl['opt']['cl'])) {
05513                                 $annots .= ' /CL [';
05514                                 foreach ($pl['opt']['cl'] as $cl) {
05515                                     $annots .= sprintf("%.4F ", $cl * $this->k);
05516                                 }
05517                                 $annots .= ']';
05518                             }
05519                             $tfit = array('FreeTextCallout', 'FreeTextTypeWriter');
05520                             if (isset($pl['opt']['it']) AND in_array($pl['opt']['it'], $tfit)) {
05521                                 $annots .= ' /IT '.$pl['opt']['it'];
05522                             }
05523                             if (isset($pl['opt']['rd']) AND is_array($pl['opt']['rd'])) {
05524                                 $l = $pl['opt']['rd'][0] * $this->k;
05525                                 $r = $pl['opt']['rd'][1] * $this->k;
05526                                 $t = $pl['opt']['rd'][2] * $this->k;
05527                                 $b = $pl['opt']['rd'][3] * $this->k;
05528                                 $annots .= ' /RD ['.sprintf('%.2F %.2F %.2F %.2F', $l, $r, $t, $b).']';
05529                             }
05530                             
05531                             break;
05532                         }
05533                         
05534                         case 'line': {
05535                             break;
05536                         }
05537                         case 'square': {
05538                             break;
05539                         }
05540                         case 'circle': {
05541                             break;
05542                         }
05543                         case 'polygon': {
05544                             break;
05545                         }
05546                         case 'polyline': {
05547                             break;
05548                         }
05549                         case 'highlight': {
05550                             break;
05551                         }
05552                         case 'underline': {
05553                             break;
05554                         }
05555                         case 'squiggly': {
05556                             break;
05557                         }
05558                         case 'strikeout': {
05559                             break;
05560                         }
05561                         case 'stamp': {
05562                             break;
05563                         }
05564                         case 'caret': {
05565                             break;
05566                         }
05567                         case 'ink': {
05568                             break;
05569                         }
05570                         case 'popup': {
05571                             break;
05572                         }
05573                         case 'fileattachment': {
05574                             if (!isset($pl['opt']['fs'])) {
05575                                 break;
05576                             }
05577                             $filename = basename($pl['opt']['fs']);
05578                             if (isset($this->embeddedfiles[$filename]['n'])) {
05579                                 $annots .= ' /FS <</Type /Filespec /F '.$this->_datastring($filename).' /EF <</F '.$this->embeddedfiles[$filename]['n'].' 0 R>> >>';
05580                                 $iconsapp = array('Graph', 'Paperclip', 'PushPin', 'Tag');
05581                                 if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) {
05582                                     $annots .= ' /Name /'.$pl['opt']['name'];
05583                                 } else {
05584                                     $annots .= ' /Name /PushPin';
05585                                 }
05586                             }
05587                             break;
05588                         }
05589                         case 'sound': {
05590                             if (!isset($pl['opt']['sound'])) {
05591                                 break;
05592                             }
05593                             $filename = basename($pl['opt']['sound']);
05594                             if (isset($this->embeddedfiles[$filename]['n'])) {
05595                                 
05596                                 $iconsapp = array('Speaker', 'Mic');
05597                                 if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) {
05598                                     $annots .= ' /Name /'.$pl['opt']['name'];
05599                                 } else {
05600                                     $annots .= ' /Name /Speaker';
05601                                 }
05602                             }
05603                             break;
05604                         }
05605                         case 'movie': {
05606                             break;
05607                         }
05608                         case 'widget': {
05609                             if (isset($pl['opt']['h'])) {
05610                                 $annots .= ' /H '.intval($pl['opt']['h']);
05611                             }
05612                             if (isset($pl['opt']['mk']) AND (is_array($pl['opt']['mk']))) {
05613                                 $annots .= ' /MK <<';
05614                                 
05615                                 $annots .= '>>';
05616                             }
05617                             break;
05618                         }
05619                         case 'screen': {
05620                             break;
05621                         }
05622                         case 'printermark': {
05623                             break;
05624                         }
05625                         case 'trapnet': {
05626                             break;
05627                         }
05628                         case 'watermark': {
05629                             break;
05630                         }
05631                         case '3d': {
05632                             break;
05633                         }
05634                         default: {
05635                             break;
05636                         }
05637                     }
05638                     
05639                 $annots .= '>>';
05640                 }
05641                 $annots .= "\n]";
05642                 $this->_out($annots);
05643             }
05644         }
05645 
05650         protected function _putfonts() {
05651             $nf = $this->n;
05652             foreach ($this->diffs as $diff) {
05653                 
05654                 $this->_newobj();
05655                 $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
05656                 $this->_out('endobj');
05657             }
05658             $mqr = get_magic_quotes_runtime();
05659             set_magic_quotes_runtime(0);
05660             foreach ($this->FontFiles as $file => $info) {
05661                 
05662                 $fontdir = $info['fontdir'];
05663                 $file = strtolower($file);
05664                 $fontfile = '';
05665                 
05666                 if (file_exists($fontdir.$file)) {
05667                     $fontfile = $fontdir.$file;
05668                 } elseif (file_exists($this->_getfontpath().$file)) {
05669                     $fontfile = $this->_getfontpath().$file;
05670                 } elseif (file_exists($file)) {
05671                     $fontfile = $file;
05672                 }
05673                 if (!$this->empty_string($fontfile)) {
05674                     $font = file_get_contents($fontfile);
05675                     $compressed = (substr($file, -2) == '.z');
05676                     if ((!$compressed) AND (isset($info['length2']))) {
05677                         $header = (ord($font{0}) == 128);
05678                         if ($header) {
05679                             
05680                             $font = substr($font, 6);
05681                         }
05682                         if ($header AND (ord($font{$info['length1']}) == 128)) {
05683                             
05684                             $font = substr($font, 0, $info['length1']).substr($font, ($info['length1'] + 6));
05685                         }
05686                     }
05687                     $this->_newobj();
05688                     $this->FontFiles[$file]['n'] = $this->n;
05689                     $this->_out('<</Length '.strlen($font));
05690                     if ($compressed) {
05691                         $this->_out('/Filter /FlateDecode');
05692                     }
05693                     $this->_out('/Length1 '.$info['length1']);
05694                     if (isset($info['length2'])) {
05695                         $this->_out('/Length2 '.$info['length2'].' /Length3 0');
05696                     }
05697                     $this->_out('>>');
05698                     $this->_putstream($font);
05699                     $this->_out('endobj');
05700                 }
05701             }
05702             set_magic_quotes_runtime($mqr);
05703             foreach ($this->fontkeys as $k) {
05704                 
05705                 $this->setFontSubBuffer($k, 'n', $this->n + 1);
05706                 $font = $this->getFontBuffer($k);
05707                 $type = $font['type'];
05708                 $name = $font['name'];
05709                 if ($type == 'core') {
05710                     
05711                     $this->_newobj();
05712                     $this->_out('<</Type /Font');
05713                     $this->_out('/BaseFont /'.$name);
05714                     $this->_out('/Subtype /Type1');
05715                     if (($name != 'symbol') AND ($name != 'zapfdingbats')) {
05716                         $this->_out('/Encoding /WinAnsiEncoding');
05717                     }
05718                     $this->_out('>>');
05719                     $this->_out('endobj');
05720                 } elseif (($type == 'Type1') OR ($type == 'TrueType')) {
05721                     
05722                     $this->_newobj();
05723                     $this->_out('<</Type /Font');
05724                     $this->_out('/BaseFont /'.$name);
05725                     $this->_out('/Subtype /'.$type);
05726                     $this->_out('/FirstChar 32 /LastChar 255');
05727                     $this->_out('/Widths '.($this->n + 1).' 0 R');
05728                     $this->_out('/FontDescriptor '.($this->n + 2).' 0 R');
05729                     if ($font['enc']) {
05730                         if (isset($font['diff'])) {
05731                             $this->_out('/Encoding '.($nf + $font['diff']).' 0 R');
05732                         } else {
05733                             $this->_out('/Encoding /WinAnsiEncoding');
05734                         }
05735                     }
05736                     $this->_out('>>');
05737                     $this->_out('endobj');
05738                     
05739                     $this->_newobj();
05740                     $cw = &$font['cw'];
05741                     $s = '[';
05742                     for($i = 32; $i < 256; ++$i) {
05743                         $s .= $cw[$i].' ';
05744                     }
05745                     $this->_out($s.']');
05746                     $this->_out('endobj');
05747                     
05748                     $this->_newobj();
05749                     $s = '<</Type /FontDescriptor /FontName /'.$name;
05750                     foreach ($font['desc'] as $k => $v) {
05751                         $s .= ' /'.$k.' '.$v.'';
05752                     }
05753                     if (!$this->empty_string($font['file'])) {
05754                         $s .= ' /FontFile'.($type == 'Type1' ? '' : '2').' '.$this->FontFiles[$font['file']]['n'].' 0 R';
05755                     }
05756                     $this->_out($s.'>>');
05757                     $this->_out('endobj');
05758                 } else {
05759                     
05760                     $mtd = '_put'.strtolower($type);
05761                     if (!method_exists($this, $mtd)) {
05762                         $this->Error('Unsupported font type: '.$type);
05763                     }
05764                     $this->$mtd($font);
05765                 }
05766             }
05767         }
05768         
05777         protected function _putfontwidths($font, $cidoffset=0) {
05778             ksort($font['cw']);
05779             $rangeid = 0;
05780             $range = array();
05781             $prevcid = -2;
05782             $prevwidth = -1;
05783             $interval = false;
05784             
05785             foreach ($font['cw'] as $cid => $width) {
05786                 $cid -= $cidoffset;
05787                 if ($width != $font['dw']) {
05788                     if ($cid == ($prevcid + 1)) {
05789                         
05790                         if ($width == $prevwidth) {
05791                             if ($width == $range[$rangeid][0]) {
05792                                 $range[$rangeid][] = $width;
05793                             } else {
05794                                 array_pop($range[$rangeid]);
05795                                 
05796                                 $rangeid = $prevcid;
05797                                 $range[$rangeid] = array();
05798                                 $range[$rangeid][] = $prevwidth;
05799                                 $range[$rangeid][] = $width;
05800                             }
05801                             $interval = true;
05802                             $range[$rangeid]['interval'] = true;
05803                         } else {
05804                             if ($interval) {
05805                                 
05806                                 $rangeid = $cid;
05807                                 $range[$rangeid] = array();
05808                                 $range[$rangeid][] = $width;
05809                             } else {
05810                                 $range[$rangeid][] = $width;
05811                             }
05812                             $interval = false;
05813                         }
05814                     } else {
05815                         
05816                         $rangeid = $cid;
05817                         $range[$rangeid] = array();
05818                         $range[$rangeid][] = $width;
05819                         $interval = false;
05820                     }
05821                     $prevcid = $cid;
05822                     $prevwidth = $width;
05823                 }
05824             }
05825             
05826             $prevk = -1;
05827             $nextk = -1;
05828             $prevint = false;
05829             foreach ($range as $k => $ws) {
05830                 $cws = count($ws);
05831                 if (($k == $nextk) AND (!$prevint) AND ((!isset($ws['interval'])) OR ($cws < 4))) {
05832                     if (isset($range[$k]['interval'])) {
05833                         unset($range[$k]['interval']);
05834                     }
05835                     $range[$prevk] = array_merge($range[$prevk], $range[$k]);
05836                     unset($range[$k]);
05837                 } else {
05838                     $prevk = $k;
05839                 }
05840                 $nextk = $k + $cws;
05841                 if (isset($ws['interval'])) {
05842                     if ($cws > 3) {
05843                         $prevint = true;
05844                     } else {
05845                         $prevint = false;
05846                     }
05847                     unset($range[$k]['interval']);
05848                     --$nextk;
05849                 } else {
05850                     $prevint = false;
05851                 }
05852             }
05853             
05854             $w = '';
05855             foreach ($range as $k => $ws) {
05856                 if (count(array_count_values($ws)) == 1) {
05857                     
05858                     $w .= ' '.$k.' '.($k + count($ws) - 1).' '.$ws[0];
05859                 } else {
05860                     
05861                     $w .= ' '.$k.' [ '.implode(' ', $ws).' ]';
05862                 }
05863             }
05864             $this->_out('/W ['.$w.' ]');
05865         }
05866         
05875         protected function _puttruetypeunicode($font) {
05876             
05877             
05878             $this->_newobj();
05879             $this->_out('<</Type /Font');
05880             $this->_out('/Subtype /Type0');
05881             $this->_out('/BaseFont /'.$font['name'].'');
05882             $this->_out('/Encoding /Identity-H'); 
05883             $this->_out('/ToUnicode /Identity-H');
05884             $this->_out('/DescendantFonts ['.($this->n + 1).' 0 R]');
05885             $this->_out('>>');
05886             $this->_out('endobj');
05887             
05888             
05889             $this->_newobj();
05890             $this->_out('<</Type /Font');
05891             $this->_out('/Subtype /CIDFontType2');
05892             $this->_out('/BaseFont /'.$font['name'].'');
05893             
05894             $cidinfo = '/Registry '.$this->_datastring('Adobe');
05895             $cidinfo .= ' /Ordering '.$this->_datastring('Identity');
05896             $cidinfo .= ' /Supplement 0';
05897             $this->_out('/CIDSystemInfo <<'.$cidinfo.'>>');
05898             $this->_out('/FontDescriptor '.($this->n + 1).' 0 R');
05899             $this->_out('/DW '.$font['dw'].''); 
05900             $this->_putfontwidths($font, 0);
05901             $this->_out('/CIDToGIDMap '.($this->n + 2).' 0 R');
05902             $this->_out('>>');
05903             $this->_out('endobj');          
05904             
05905             
05906             $this->_newobj();
05907             $this->_out('<</Type /FontDescriptor');
05908             $this->_out('/FontName /'.$font['name']);
05909             foreach ($font['desc'] as $key => $value) {
05910                 $this->_out('/'.$key.' '.$value);
05911             }
05912             $fontdir = '';
05913             if (!$this->empty_string($font['file'])) {
05914                 
05915                 $this->_out('/FontFile2 '.$this->FontFiles[$font['file']]['n'].' 0 R');
05916                 $fontdir = $this->FontFiles[$font['file']]['fontdir'];
05917             }
05918             $this->_out('>>');
05919             $this->_out('endobj');
05920             $this->_newobj();
05921             if (isset($font['ctg']) AND (!$this->empty_string($font['ctg']))) {
05922                 
05923                 
05924                 
05925                 $ctgfile = strtolower($font['ctg']);
05926                 
05927                 $fontfile = '';
05928                 
05929                 if (file_exists($fontdir.$ctgfile)) {
05930                     $fontfile = $fontdir.$ctgfile;
05931                 } elseif (file_exists($this->_getfontpath().$ctgfile)) {
05932                     $fontfile = $this->_getfontpath().$ctgfile;
05933                 } elseif (file_exists($ctgfile)) {
05934                     $fontfile = $ctgfile;
05935                 }
05936                 if ($this->empty_string($fontfile)) {
05937                     $this->Error('Font file not found: '.$ctgfile);
05938                 }
05939                 $size = filesize($fontfile);
05940                 $this->_out('<</Length '.$size.'');
05941                 if (substr($fontfile, -2) == '.z') { 
05942                     
05943                     
05944                     
05945                     $this->_out('/Filter /FlateDecode');
05946                 }
05947                 $this->_out('>>');
05948                 $this->_putstream(file_get_contents($fontfile));
05949             }
05950             $this->_out('endobj');
05951         }
05952         
05960         protected function _putcidfont0($font) {
05961             $cidoffset = 31;
05962             if (isset($font['cidinfo']['uni2cid'])) {
05963                 
05964                 $uni2cid = $font['cidinfo']['uni2cid'];
05965                 $cw = array();
05966                 foreach ($font['cw'] as $uni => $width) {
05967                     if (isset($uni2cid[$uni])) {
05968                         $cw[($uni2cid[$uni] + $cidoffset)] = $width;
05969                     } elseif ($uni < 256) {
05970                         $cw[$uni] = $width;
05971                     } 
05972                 }
05973                 $font = array_merge($font, array('cw' => $cw));
05974             }
05975             $name = $font['name'];
05976             $enc = $font['enc'];
05977             if ($enc) {
05978                 $longname = $name.'-'.$enc;
05979             } else {
05980                 $longname = $name;
05981             }
05982             $this->_newobj();
05983             $this->_out('<</Type /Font');
05984             $this->_out('/BaseFont /'.$longname);
05985             $this->_out('/Subtype /Type0');
05986             if ($enc) {
05987                 $this->_out('/Encoding /'.$enc);
05988             }
05989             $this->_out('/DescendantFonts ['.($this->n + 1).' 0 R]');
05990             $this->_out('>>');
05991             $this->_out('endobj');
05992             $this->_newobj();
05993             $this->_out('<</Type /Font');
05994             $this->_out('/BaseFont /'.$name);
05995             $this->_out('/Subtype /CIDFontType0');
05996             $cidinfo = '/Registry '.$this->_datastring($font['cidinfo']['Registry']);
05997             $cidinfo .= ' /Ordering '.$this->_datastring($font['cidinfo']['Ordering']);
05998             $cidinfo .= ' /Supplement '.$font['cidinfo']['Supplement'];
05999             $this->_out('/CIDSystemInfo <<'.$cidinfo.'>>');
06000             $this->_out('/FontDescriptor '.($this->n + 1).' 0 R');
06001             $this->_out('/DW '.$font['dw']);
06002             $this->_putfontwidths($font, $cidoffset);
06003             $this->_out('>>');
06004             $this->_out('endobj');
06005             $this->_newobj();
06006             $s = '<</Type /FontDescriptor /FontName /'.$name;
06007             foreach ($font['desc'] as $k => $v) {
06008                 if ($k != 'Style') {
06009                     $s .= ' /'.$k.' '.$v.'';
06010                 }
06011             }
06012             $this->_out($s.'>>');
06013             $this->_out('endobj');
06014         }
06015 
06020         protected function _putimages() {
06021             $filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
06022             foreach ($this->imagekeys as $file) {
06023                 $info = $this->getImageBuffer($file);
06024                 $this->_newobj();
06025                 $this->setImageSubBuffer($file, 'n', $this->n);
06026                 $this->_out('<</Type /XObject');
06027                 $this->_out('/Subtype /Image');
06028                 $this->_out('/Width '.$info['w']);
06029                 $this->_out('/Height '.$info['h']);
06030                 if (isset($info['masked'])) {
06031                     $this->_out('/SMask '.($this->n - 1).' 0 R');
06032                 }
06033                 if ($info['cs'] == 'Indexed') {
06034                     $this->_out('/ColorSpace [/Indexed /DeviceRGB '.((strlen($info['pal']) / 3) - 1).' '.($this->n + 1).' 0 R]');
06035                 } else {
06036                     $this->_out('/ColorSpace /'.$info['cs']);
06037                     if ($info['cs'] == 'DeviceCMYK') {
06038                         $this->_out('/Decode [1 0 1 0 1 0 1 0]');
06039                     }
06040                 }
06041                 $this->_out('/BitsPerComponent '.$info['bpc']);
06042                 if (isset($info['f'])) {
06043                     $this->_out('/Filter /'.$info['f']);
06044                 }
06045                 if (isset($info['parms'])) {
06046                     $this->_out($info['parms']);
06047                 }
06048                 if (isset($info['trns']) AND is_array($info['trns'])) {
06049                     $trns='';
06050                     $count_info = count($info['trns']);
06051                     for($i=0; $i < $count_info; ++$i) {
06052                         $trns .= $info['trns'][$i].' '.$info['trns'][$i].' ';
06053                     }
06054                     $this->_out('/Mask ['.$trns.']');
06055                 }
06056                 $this->_out('/Length '.strlen($info['data']).'>>');
06057                 $this->_putstream($info['data']);
06058                 $this->_out('endobj');
06059                 
06060                 if ($info['cs'] == 'Indexed') {
06061                     $this->_newobj();
06062                     $pal = ($this->compress) ? gzcompress($info['pal']) : $info['pal'];
06063                     $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
06064                     $this->_putstream($pal);
06065                     $this->_out('endobj');
06066                 }
06067             }
06068         }
06069 
06075         protected function _putspotcolors() {
06076             foreach ($this->spot_colors as $name => $color) {
06077                 $this->_newobj();
06078                 $this->spot_colors[$name]['n'] = $this->n;
06079                 $this->_out('[/Separation /'.str_replace(' ', '#20', $name));
06080                 $this->_out('/DeviceCMYK <<');
06081                 $this->_out('/Range [0 1 0 1 0 1 0 1] /C0 [0 0 0 0] ');
06082                 $this->_out(sprintf('/C1 [%.4F %.4F %.4F %.4F] ', $color['c']/100, $color['m']/100, $color['y']/100, $color['k']/100));
06083                 $this->_out('/FunctionType 2 /Domain [0 1] /N 1>>]');
06084                 $this->_out('endobj');
06085             }
06086         }
06087 
06092         protected function _putxobjectdict() {
06093             foreach ($this->imagekeys as $file) {
06094                 $info = $this->getImageBuffer($file);
06095                 $this->_out('/I'.$info['i'].' '.$info['n'].' 0 R');
06096             }
06097         }
06098 
06103         protected function _putresourcedict() {
06104             $this->_out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
06105             $this->_out('/Font <<');
06106             foreach ($this->fontkeys as $fontkey) {
06107                 $font = $this->getFontBuffer($fontkey);
06108                 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
06109             }
06110             $this->_out('>>');
06111             $this->_out('/XObject <<');
06112             $this->_putxobjectdict();
06113             $this->_out('>>');
06114             
06115             $this->_out('/Properties <</OC1 '.$this->n_ocg_print.' 0 R /OC2 '.$this->n_ocg_view.' 0 R>>');
06116             
06117             $this->_out('/ExtGState <<');
06118             foreach ($this->extgstates as $k => $extgstate) {
06119                 $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
06120             }
06121             $this->_out('>>');
06122             
06123             if (isset($this->gradients) AND (count($this->gradients) > 0)) {
06124                 $this->_out('/Shading <<');
06125                 foreach ($this->gradients as $id => $grad) {
06126                     $this->_out('/Sh'.$id.' '.$grad['id'].' 0 R');
06127                 }
06128                 $this->_out('>>');
06129             }
06130             
06131             if (isset($this->spot_colors) AND (count($this->spot_colors) > 0)) {
06132                 $this->_out('/ColorSpace <<');
06133                 foreach ($this->spot_colors as $color) {
06134                     $this->_out('/CS'.$color['i'].' '.$color['n'].' 0 R');
06135                 }
06136                 $this->_out('>>');
06137             }
06138         }
06139         
06144         protected function _putresources() {
06145             $this->_putextgstates();
06146             $this->_putocg();
06147             $this->_putfonts();
06148             $this->_putimages();
06149             $this->_putspotcolors();
06150             $this->_putshaders();
06151             
06152             $this->offsets[2] = $this->bufferlen;
06153             $this->_out('2 0 obj');
06154             $this->_out('<<');
06155             $this->_putresourcedict();
06156             $this->_out('>>');
06157             $this->_out('endobj');
06158             $this->_putjavascript();
06159             $this->_putbookmarks();
06160             $this->_putEmbeddedFiles();
06161             
06162             if ($this->encrypted) {
06163                 $this->_newobj();
06164                 $this->enc_obj_id = $this->n;
06165                 $this->_out('<<');
06166                 $this->_putencryption();
06167                 $this->_out('>>');
06168                 $this->_out('endobj');
06169             }
06170         }
06171         
06177         protected function _putinfo() {
06178             if (!$this->empty_string($this->title)) {
06179                 $this->_out('/Title '.$this->_textstring($this->title));
06180             }
06181             if (!$this->empty_string($this->author)) {
06182                 $this->_out('/Author '.$this->_textstring($this->author));
06183             }
06184             if (!$this->empty_string($this->subject)) {
06185                 $this->_out('/Subject '.$this->_textstring($this->subject));
06186             }
06187             if (!$this->empty_string($this->keywords)) {
06188                 $this->_out('/Keywords '.$this->_textstring($this->keywords));
06189             }
06190             if (!$this->empty_string($this->creator)) {
06191                 $this->_out('/Creator '.$this->_textstring($this->creator));
06192             }
06193             if (defined('PDF_PRODUCER')) {
06194                 $this->_out('/Producer '.$this->_textstring(PDF_PRODUCER));
06195             }
06196             $this->_out('/CreationDate '.$this->_datastring('D:'.date('YmdHis')));
06197             $this->_out('/ModDate '.$this->_datastring('D:'.date('YmdHis')));   
06198         }
06199         
06204         protected function _putcatalog() {
06205             $this->_out('/Type /Catalog');
06206             $this->_out('/Pages 1 0 R');
06207             if ($this->ZoomMode == 'fullpage') {
06208                 $this->_out('/OpenAction [3 0 R /Fit]');
06209             } elseif ($this->ZoomMode == 'fullwidth') {
06210                 $this->_out('/OpenAction [3 0 R /FitH null]');
06211             } elseif ($this->ZoomMode == 'real') {
06212                 $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
06213             } elseif (!is_string($this->ZoomMode)) {
06214                 $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode / 100).']');
06215             }
06216             if (isset($this->LayoutMode) AND (!$this->empty_string($this->LayoutMode))) {
06217                 $this->_out('/PageLayout /'.$this->LayoutMode.'');
06218             }
06219             if (isset($this->PageMode) AND (!$this->empty_string($this->PageMode))) {
06220                 $this->_out('/PageMode /'.$this->PageMode);
06221             }
06222             if (isset($this->l['a_meta_language'])) {
06223                 $this->_out('/Lang /'.$this->l['a_meta_language']);
06224             }
06225             $this->_out('/Names <<');
06226             if (!$this->empty_string($this->javascript)) {
06227                 $this->_out('/JavaScript '.($this->n_js).' 0 R');
06228             }
06229             $this->_out('>>');
06230             if (count($this->outlines) > 0) {
06231                 $this->_out('/Outlines '.$this->OutlineRoot.' 0 R');
06232                 $this->_out('/PageMode /UseOutlines');
06233             }
06234             $this->_putviewerpreferences();
06235             $p = $this->n_ocg_print.' 0 R';
06236             $v = $this->n_ocg_view.' 0 R';
06237             $as = '<</Event /Print /OCGs ['.$p.' '.$v.'] /Category [/Print]>> <</Event /View /OCGs ['.$p.' '.$v.'] /Category [/View]>>';
06238             $this->_out('/OCProperties <</OCGs ['.$p.' '.$v.'] /D <</ON ['.$p.'] /OFF ['.$v.'] /AS ['.$as.']>>>>');
06239         }
06240         
06247         protected function _putviewerpreferences() {
06248             $this->_out('/ViewerPreferences<<');
06249             if ($this->rtl) {
06250                 $this->_out('/Direction /R2L');
06251             } else {
06252                 $this->_out('/Direction /L2R');
06253             }
06254             if (isset($this->viewer_preferences['HideToolbar']) AND ($this->viewer_preferences['HideToolbar'])) {
06255                 $this->_out('/HideToolbar true');
06256             }
06257             if (isset($this->viewer_preferences['HideMenubar']) AND ($this->viewer_preferences['HideMenubar'])) {
06258                 $this->_out('/HideMenubar true');
06259             }
06260             if (isset($this->viewer_preferences['HideWindowUI']) AND ($this->viewer_preferences['HideWindowUI'])) {
06261                 $this->_out('/HideWindowUI true');
06262             }
06263             if (isset($this->viewer_preferences['FitWindow']) AND ($this->viewer_preferences['FitWindow'])) {
06264                 $this->_out('/FitWindow true');
06265             }
06266             if (isset($this->viewer_preferences['CenterWindow']) AND ($this->viewer_preferences['CenterWindow'])) {
06267                 $this->_out('/CenterWindow true');
06268             }
06269             if (isset($this->viewer_preferences['DisplayDocTitle']) AND ($this->viewer_preferences['DisplayDocTitle'])) {
06270                 $this->_out('/DisplayDocTitle true');
06271             }
06272             if (isset($this->viewer_preferences['NonFullScreenPageMode'])) {
06273                 $this->_out('/NonFullScreenPageMode /'.$this->viewer_preferences['NonFullScreenPageMode'].'');
06274             }
06275             if (isset($this->viewer_preferences['ViewArea'])) {
06276                 $this->_out('/ViewArea /'.$this->viewer_preferences['ViewArea']);
06277             }
06278             if (isset($this->viewer_preferences['ViewClip'])) {
06279                 $this->_out('/ViewClip /'.$this->viewer_preferences['ViewClip']);
06280             }
06281             if (isset($this->viewer_preferences['PrintArea'])) {
06282                 $this->_out('/PrintArea /'.$this->viewer_preferences['PrintArea']);
06283             }
06284             if (isset($this->viewer_preferences['PrintClip'])) {
06285                 $this->_out('/PrintClip /'.$this->viewer_preferences['PrintClip']);
06286             }
06287             if (isset($this->viewer_preferences['PrintScaling'])) {
06288                 $this->_out('/PrintScaling /'.$this->viewer_preferences['PrintScaling']);
06289             }
06290             if (isset($this->viewer_preferences['Duplex']) AND (!$this->empty_string($this->viewer_preferences['Duplex']))) {
06291                 $this->_out('/Duplex /'.$this->viewer_preferences['Duplex']);
06292             }
06293             if (isset($this->viewer_preferences['PickTrayByPDFSize'])) {
06294                 if ($this->viewer_preferences['PickTrayByPDFSize']) {
06295                     $this->_out('/PickTrayByPDFSize true');
06296                 } else {
06297                     $this->_out('/PickTrayByPDFSize false');
06298                 }
06299             }
06300             if (isset($this->viewer_preferences['PrintPageRange'])) {
06301                 $PrintPageRangeNum = '';
06302                 foreach ($this->viewer_preferences['PrintPageRange'] as $k => $v) {
06303                     $PrintPageRangeNum .= ' '.($v - 1).'';
06304                 }
06305                 $this->_out('/PrintPageRange ['.substr($PrintPageRangeNum,1).']');
06306             }
06307             if (isset($this->viewer_preferences['NumCopies'])) {
06308                 $this->_out('/NumCopies '.intval($this->viewer_preferences['NumCopies']));
06309             }
06310             $this->_out('>>');
06311         }
06312 
06317         protected function _puttrailer() {
06318             $this->_out('/Size '.($this->n + 1));
06319             $this->_out('/Root '.$this->n.' 0 R');
06320             $this->_out('/Info '.($this->n - 1).' 0 R');
06321             if ($this->encrypted) {
06322                 $this->_out('/Encrypt '.$this->enc_obj_id.' 0 R');
06323                 $this->_out('/ID [()()]');
06324             }
06325         }
06326 
06331         protected function _putheader() {
06332             $this->_out('%PDF-'.$this->PDFVersion);
06333         }
06334 
06339         protected function _enddoc() {
06340             $this->state = 1;
06341             $this->_putheader();
06342             $this->_putpages();
06343             $this->_putresources();
06344             
06345             $this->_newobj();
06346             $this->_out('<<');
06347             $this->_putinfo();
06348             $this->_out('>>');
06349             $this->_out('endobj');
06350             
06351             $this->_newobj();
06352             $this->_out('<<');
06353             $this->_putcatalog();
06354             $this->_putcertification();
06355             $this->_putuserrights();
06356             $this->_out('>>');
06357             $this->_out('endobj');
06358             
06359             $o = $this->bufferlen;
06360             $this->_out('xref');
06361             $this->_out('0 '.($this->n + 1));
06362             $this->_out('0000000000 65535 f ');
06363             for($i=1; $i <= $this->n; ++$i) {
06364                 $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
06365             }
06366             foreach ($this->embeddedfiles as $filename => $filedata) {
06367                 $this->_out(sprintf('%010d 00000 n ',$this->offsets[$filedata['n']]));
06368             }
06369             
06370             $this->_out('trailer');
06371             $this->_out('<<');
06372             $this->_puttrailer();
06373             $this->_out('>>');
06374             $this->_out('startxref');
06375             $this->_out($o);
06376             $this->_out('%%EOF');
06377             $this->state = 3; 
06378             if ($this->diskcache) {
06379                 
06380                 foreach ($this->imagekeys as $key) {
06381                     
06382                     unlink($this->images[$key]);
06383                 }
06384                 foreach ($this->fontkeys as $key) {
06385                     
06386                     unlink($this->fonts[$key]);
06387                 }
06388             }
06389         }
06390 
06397         protected function _beginpage($orientation='', $format='') {
06398             ++$this->page;
06399             $this->setPageBuffer($this->page, '');
06400             
06401             $this->transfmrk[$this->page] = array();
06402             $this->state = 2;
06403             if ($this->empty_string($orientation)) {
06404                 if (isset($this->CurOrientation)) {
06405                     $orientation = $this->CurOrientation;
06406                 } else {
06407                     $orientation = 'P';
06408                 }
06409             }
06410             if ($this->empty_string($format)) {
06411                 $this->setPageOrientation($orientation);
06412             } else {
06413                 $this->setPageFormat($format, $orientation);
06414             }
06415             if ($this->rtl) {
06416                 $this->x = $this->w - $this->rMargin;
06417             } else {
06418                 $this->x = $this->lMargin;
06419             }
06420             $this->y = $this->tMargin;
06421             if (isset($this->newpagegroup[$this->page])) {
06422                 
06423                 $n = sizeof($this->pagegroups) + 1;
06424                 $alias = '{nb'.$n.'}';
06425                 $this->pagegroups[$alias] = 1;
06426                 $this->currpagegroup = $alias;
06427             } elseif ($this->currpagegroup) {
06428                 ++$this->pagegroups[$this->currpagegroup];
06429             }
06430         }
06431 
06436         protected function _endpage() {
06437             $this->setVisibility('all');
06438             $this->state = 1;
06439         }
06440 
06445         protected function _newobj() {
06446             ++$this->n;
06447             $this->offsets[$this->n] = $this->bufferlen;
06448             $this->_out($this->n.' 0 obj');
06449         }
06450 
06458         protected function _dounderline($x, $y, $txt) {
06459             $up = $this->CurrentFont['up'];
06460             $ut = $this->CurrentFont['ut'];
06461             $w = $this->GetStringWidth($txt);
06462             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);
06463         }
06464         
06472         protected function _dolinethrough($x, $y, $txt) {
06473             $up = $this->CurrentFont['up'];
06474             $ut = $this->CurrentFont['ut'];
06475             $w = $this->GetStringWidth($txt);
06476             return sprintf('%.2F %.2F %.2F %.2F re f', $x * $this->k, ($this->h - ($y - ($this->FontSize/2) - $up / 1000 * $this->FontSize)) * $this->k, $w * $this->k, -$ut / 1000 * $this->FontSizePt);
06477         }
06478         
06485         protected function _freadint($f) {
06486             $a = unpack('Ni', fread($f, 4));
06487             return $a['i'];
06488         }
06489         
06496         protected function _escape($s) {
06497             
06498             return strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r'));
06499         }
06500         
06507         protected function _datastring($s) {
06508             if ($this->encrypted) {
06509                 $s = $this->_RC4($this->_objectkey($this->n), $s);
06510             }
06511             return '('. $this->_escape($s).')';
06512         }
06513         
06520         protected function _textstring($s) {
06521             if ($this->isunicode) {
06522                 
06523                 $s = $this->UTF8ToUTF16BE($s, true);
06524             }
06525             return $this->_datastring($s);
06526         }
06527                 
06534         protected function _escapetext($s) {
06535             if ($this->isunicode) {
06536                 if (($this->CurrentFont['type'] == 'core') OR ($this->CurrentFont['type'] == 'TrueType') OR ($this->CurrentFont['type'] == 'Type1')) {
06537                     $s = $this->UTF8ToLatin1($s);
06538                 } else {
06539                     
06540                     $s = $this->utf8StrRev($s, false, $this->tmprtl);
06541                 }
06542             }
06543             return $this->_escape($s);
06544         }
06545         
06551         protected function _putstream($s) {
06552             if ($this->encrypted) {
06553                 $s = $this->_RC4($this->_objectkey($this->n), $s);
06554             }
06555             $this->_out('stream');
06556             $this->_out($s);
06557             $this->_out('endstream');
06558         }
06559         
06565         protected function _out($s) {
06566             if ($this->state == 2) {
06567                 if ((!$this->InFooter) AND isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) {
06568                     
06569                     $pagebuff = $this->getPageBuffer($this->page);
06570                     $page = substr($pagebuff, 0, -$this->footerlen[$this->page]);
06571                     $footer = substr($pagebuff, -$this->footerlen[$this->page]);
06572                     $this->setPageBuffer($this->page, $page.$s."\n".$footer);
06573                     
06574                     $this->footerpos[$this->page] += strlen($s."\n");   
06575                 } else {
06576                     $this->setPageBuffer($this->page, $s."\n", true);
06577                 }
06578             } else {
06579                 $this->setBuffer($s."\n");
06580             }
06581         }
06582         
06617         protected function UTF8StringToArray($str) {
06618             if (isset($this->cache_UTF8StringToArray['_'.$str])) {
06619                 
06620                 return($this->cache_UTF8StringToArray['_'.$str]);
06621             }
06622             
06623             if ($this->cache_size_UTF8StringToArray >= $this->cache_maxsize_UTF8StringToArray) {
06624                 
06625                 array_shift($this->cache_UTF8StringToArray);
06626             }
06627             ++$this->cache_size_UTF8StringToArray;
06628             if (!$this->isunicode) {
06629                 
06630                 $strarr = array();
06631                 $strlen = strlen($str);
06632                 for($i=0; $i < $strlen; ++$i) {
06633                     $strarr[] = ord($str{$i});
06634                 }
06635                 
06636                 $this->cache_UTF8StringToArray['_'.$str] = $strarr;
06637                 return $strarr;
06638             }
06639             $unicode = array(); 
06640             $bytes  = array(); 
06641             $numbytes  = 1; 
06642             $str .= ''; 
06643             $length = strlen($str);
06644             for($i = 0; $i < $length; ++$i) {
06645                 $char = ord($str{$i}); 
06646                 if (count($bytes) == 0) { 
06647                     if ($char <= 0x7F) {
06648                         $unicode[] = $char; 
06649                         $numbytes = 1;
06650                     } elseif (($char >> 0x05) == 0x06) { 
06651                         $bytes[] = ($char - 0xC0) << 0x06; 
06652                         $numbytes = 2;
06653                     } elseif (($char >> 0x04) == 0x0E) { 
06654                         $bytes[] = ($char - 0xE0) << 0x0C; 
06655                         $numbytes = 3;
06656                     } elseif (($char >> 0x03) == 0x1E) { 
06657                         $bytes[] = ($char - 0xF0) << 0x12; 
06658                         $numbytes = 4;
06659                     } else {
06660                         
06661                         $unicode[] = 0xFFFD;
06662                         $bytes = array();
06663                         $numbytes = 1;
06664                     }
06665                 } elseif (($char >> 0x06) == 0x02) { 
06666                     $bytes[] = $char - 0x80;
06667                     if (count($bytes) == $numbytes) {
06668                         
06669                         $char = $bytes[0];
06670                         for($j = 1; $j < $numbytes; ++$j) {
06671                             $char += ($bytes[$j] << (($numbytes - $j - 1) * 0x06));
06672                         }
06673                         if ((($char >= 0xD800) AND ($char <= 0xDFFF)) OR ($char >= 0x10FFFF)) {
06674                             
06675 
06676 
06677 
06678                             $unicode[] = 0xFFFD; 
06679                         } else {
06680                             $unicode[] = $char; 
06681                         }
06682                         
06683                         $bytes = array(); 
06684                         $numbytes = 1;
06685                     }
06686                 } else {
06687                     
06688                     $unicode[] = 0xFFFD;
06689                     $bytes = array();
06690                     $numbytes = 1;
06691                 }
06692             }
06693             
06694             $this->cache_UTF8StringToArray['_'.$str] = $unicode;
06695             return $unicode;
06696         }
06697         
06708         protected function UTF8ToUTF16BE($str, $setbom=true) {
06709             if (!$this->isunicode) {
06710                 return $str; 
06711             }
06712             $unicode = $this->UTF8StringToArray($str); 
06713             return $this->arrUTF8ToUTF16BE($unicode, $setbom);
06714         }
06715         
06724         protected function UTF8ToLatin1($str) {
06725             global $utf8tolatin;
06726             if (!$this->isunicode) {
06727                 return $str; 
06728             }
06729             $outstr = ''; 
06730             $unicode = $this->UTF8StringToArray($str); 
06731             foreach ($unicode as $char) {
06732                 if ($char < 256) {
06733                     $outstr .= chr($char);
06734                 } elseif (array_key_exists($char, $utf8tolatin)) {
06735                     
06736                     $outstr .= chr($utf8tolatin[$char]);
06737                 } elseif ($char == 0xFFFD) {
06738                     
06739                 } else {
06740                     $outstr .= '?';
06741                 }
06742             }
06743             return $outstr;
06744         }
06745 
06784         protected function arrUTF8ToUTF16BE($unicode, $setbom=true) {
06785             $outstr = ''; 
06786             if ($setbom) {
06787                 $outstr .= "\xFE\xFF"; 
06788             }
06789             foreach ($unicode as $char) {
06790                 if ($char == 0xFFFD) {
06791                     $outstr .= "\xFF\xFD"; 
06792                 } elseif ($char < 0x10000) {
06793                     $outstr .= chr($char >> 0x08);
06794                     $outstr .= chr($char & 0xFF);
06795                 } else {
06796                     $char -= 0x10000;
06797                     $w1 = 0xD800 | ($char >> 0x10);
06798                     $w2 = 0xDC00 | ($char & 0x3FF); 
06799                     $outstr .= chr($w1 >> 0x08);
06800                     $outstr .= chr($w1 & 0xFF);
06801                     $outstr .= chr($w2 >> 0x08);
06802                     $outstr .= chr($w2 & 0xFF);
06803                 }
06804             }
06805             return $outstr;
06806         }
06807         
06808         
06815         public function setHeaderFont($font) {
06816             $this->header_font = $font;
06817         }
06818         
06825         public function getHeaderFont() {
06826             return $this->header_font;
06827         }
06828         
06835         public function setFooterFont($font) {
06836             $this->footer_font = $font;
06837         }
06838         
06845         public function getFooterFont() {
06846             return $this->footer_font;
06847         }
06848         
06855         public function setLanguageArray($language) {
06856             $this->l = $language;
06857             $this->rtl = $this->l['a_meta_dir']=='rtl' ? true : false;
06858         }
06859         
06864         public function getPDFData() {
06865             if ($this->state < 3) {
06866                 $this->Close();
06867             }
06868             return $this->buffer;
06869         }
06870                 
06882         public function addHtmlLink($url, $name, $fill=0, $firstline=false, $color='', $style=-1) {
06883             if (!$this->empty_string($url) AND ($url{0} == '#')) {
06884                 
06885                 $page = intval(substr($url, 1));
06886                 $url = $this->AddLink();
06887                 $this->SetLink($url, 0, $page);
06888             }
06889             
06890             $prevcolor = $this->fgcolor;
06891             $prevstyle = $this->FontStyle;
06892             if (empty($color)) {
06893                 $this->SetTextColorArray($this->htmlLinkColorArray);
06894             } else {
06895                 $this->SetTextColorArray($color);
06896             }
06897             if ($style == -1) {
06898                 $this->SetFont('', $this->FontStyle.$this->htmlLinkFontStyle);
06899             } else {
06900                 $this->SetFont('', $this->FontStyle.$style);
06901             }
06902             $ret = $this->Write($this->lasth, $name, $url, $fill, '', false, 0, $firstline);
06903             
06904             $this->SetFont('', $prevstyle);
06905             $this->SetTextColorArray($prevcolor);
06906             return $ret;
06907         }
06908         
06915         public function convertHTMLColorToDec($color='#FFFFFF') {
06916             global $webcolor;
06917             $color = preg_replace('/[\s]*/', '', $color); 
06918             $color = strtolower($color);
06919             if (strlen($color) == 0) {
06920                 return false;
06921             }
06922             if (substr($color, 0, 3) == 'rgb') {
06923                 $codes = substr($color, 4);
06924                 $codes = str_replace(')', '', $codes);
06925                 $returncolor = explode(',', $codes, 3);
06926                 return $returncolor;
06927             }
06928             if (substr($color, 0, 1) != '#') {
06929                 
06930                 if (isset($webcolor[$color])) {
06931                     $color_code = $webcolor[$color];
06932                 } else {
06933                     return false;
06934                 }
06935             } else {
06936                 $color_code = substr($color, 1);
06937             }
06938             switch (strlen($color_code)) {
06939                 case 3: {
06940                     
06941                     $r = substr($color_code, 0, 1);
06942                     $g = substr($color_code, 1, 1);
06943                     $b = substr($color_code, 2, 1);
06944                     $returncolor['R'] = hexdec($r.$r);
06945                     $returncolor['G'] = hexdec($g.$g);
06946                     $returncolor['B'] = hexdec($b.$b);
06947                     break;
06948                 }
06949                 case 6: {
06950                     
06951                     $returncolor['R'] = hexdec(substr($color_code, 0, 2));
06952                     $returncolor['G'] = hexdec(substr($color_code, 2, 2));
06953                     $returncolor['B'] = hexdec(substr($color_code, 4, 2));
06954                     break;
06955                 }
06956             }
06957             return $returncolor;
06958         }
06959         
06967         public function pixelsToUnits($px) {
06968             return ($px / ($this->imgscale * $this->k));
06969         }
06970             
06978         public function unhtmlentities($text_to_convert) {
06979             return html_entity_decode($text_to_convert, ENT_QUOTES, $this->encoding);
06980         }
06981         
06982         
06983         
06984         
06991         protected function _objectkey($n) {
06992             return substr($this->_md5_16($this->encryption_key.pack('VXxx', $n)), 0, 10);
06993         }
06994         
07000         protected function _putencryption() {
07001             $this->_out('/Filter /Standard');
07002             $this->_out('/V 1');
07003             $this->_out('/R 2');
07004             $this->_out('/O ('.$this->_escape($this->Ovalue).')');
07005             $this->_out('/U ('.$this->_escape($this->Uvalue).')');
07006             $this->_out('/P '.$this->Pvalue);
07007         }
07008         
07019         protected function _RC4($key, $text) {
07020             if ($this->last_rc4_key != $key) {
07021                 $k = str_repeat($key, ((256 / strlen($key)) + 1));
07022                 $rc4 = range(0, 255);
07023                 $j = 0;
07024                 for ($i = 0; $i < 256; ++$i) {
07025                     $t = $rc4[$i];
07026                     $j = ($j + $t + ord($k{$i})) % 256;
07027                     $rc4[$i] = $rc4[$j];
07028                     $rc4[$j] = $t;
07029                 }
07030                 $this->last_rc4_key = $key;
07031                 $this->last_rc4_key_c = $rc4;
07032             } else {
07033                 $rc4 = $this->last_rc4_key_c;
07034             }
07035             $len = strlen($text);
07036             $a = 0;
07037             $b = 0;
07038             $out = '';
07039             for ($i = 0; $i < $len; ++$i) {
07040                 $a = ($a + 1) % 256;
07041                 $t = $rc4[$a];
07042                 $b = ($b + $t) % 256;
07043                 $rc4[$a] = $rc4[$b];
07044                 $rc4[$b] = $t;
07045                 $k = $rc4[($rc4[$a] + $rc4[$b]) % 256];
07046                 $out .= chr(ord($text{$i}) ^ $k);
07047             }
07048             return $out;
07049         }
07050         
07059         protected function _md5_16($str) {
07060             return pack('H*', md5($str));
07061         }
07062         
07072         protected function _Ovalue($user_pass, $owner_pass) {
07073             $tmp = $this->_md5_16($owner_pass);
07074             $owner_RC4_key = substr($tmp, 0, 5);
07075             return $this->_RC4($owner_RC4_key, $user_pass);
07076         }
07077         
07085         protected function _Uvalue() {
07086             return $this->_RC4($this->encryption_key, $this->padding);
07087         }
07088         
07098         protected function _generateencryptionkey($user_pass, $owner_pass, $protection) {
07099             
07100             $user_pass = substr($user_pass.$this->padding, 0, 32);
07101             $owner_pass = substr($owner_pass.$this->padding, 0, 32);
07102             
07103             $this->Ovalue = $this->_Ovalue($user_pass, $owner_pass);
07104             
07105             $tmp = $this->_md5_16($user_pass.$this->Ovalue.chr($protection)."\xFF\xFF\xFF");
07106             $this->encryption_key = substr($tmp, 0, 5);
07107             
07108             $this->Uvalue = $this->_Uvalue();
07109             
07110             $this->Pvalue = -(($protection^255) + 1);
07111         }
07112         
07130         public function SetProtection($permissions=array(), $user_pass='', $owner_pass=null) {
07131             $options = array('print' => 4, 'modify' => 8, 'copy' => 16, 'annot-forms' => 32);
07132             $protection = 192;
07133             foreach ($permissions as $permission) {
07134                 if (!isset($options[$permission])) {
07135                     $this->Error('Incorrect permission: '.$permission);
07136                 }
07137                 $protection += $options[$permission];
07138             }
07139             if ($owner_pass === null) {
07140                 $owner_pass = uniqid(rand());
07141             }
07142             $this->encrypted = true;
07143             $this->_generateencryptionkey($user_pass, $owner_pass, $protection);
07144         }
07145         
07146         
07147         
07148         
07149         
07158         public function StartTransform() {
07159             $this->_out('q');
07160             $this->transfmrk[$this->page][] = $this->pagelen[$this->page];
07161         }
07162         
07171         public function StopTransform() {
07172             $this->_out('Q');
07173             if (isset($this->transfmatrix)) {
07174                 array_pop($this->transfmatrix);
07175             }
07176             array_pop($this->transfmrk[$this->page]);
07177         }
07187         public function ScaleX($s_x, $x='', $y='') {
07188             $this->Scale($s_x, 100, $x, $y);
07189         }
07190         
07200         public function ScaleY($s_y, $x='', $y='') {
07201             $this->Scale(100, $s_y, $x, $y);
07202         }
07203         
07213         public function ScaleXY($s, $x='', $y='') {
07214             $this->Scale($s, $s, $x, $y);
07215         }
07216         
07227         public function Scale($s_x, $s_y, $x='', $y='') {
07228             if ($x === '') {
07229                 $x = $this->x;
07230             }
07231             if ($y === '') {
07232                 $y = $this->y;
07233             }
07234             if ($this->rtl) {
07235                 $x = $this->w - $x;
07236             }
07237             if (($s_x == 0) OR ($s_y == 0)) {
07238                 $this->Error('Please do not use values equal to zero for scaling');
07239             }
07240             $y = ($this->h - $y) * $this->k;
07241             $x *= $this->k;
07242             
07243             $s_x /= 100;
07244             $s_y /= 100;
07245             $tm[0] = $s_x;
07246             $tm[1] = 0;
07247             $tm[2] = 0;
07248             $tm[3] = $s_y;
07249             $tm[4] = $x * (1 - $s_x);
07250             $tm[5] = $y * (1 - $s_y);
07251             
07252             $this->Transform($tm);
07253         }
07254         
07262         public function MirrorH($x='') {
07263             $this->Scale(-100, 100, $x);
07264         }
07265         
07273         public function MirrorV($y='') {
07274             $this->Scale(100, -100, '', $y);
07275         }
07276         
07285         public function MirrorP($x='',$y='') {
07286             $this->Scale(-100, -100, $x, $y);
07287         }
07288         
07298         public function MirrorL($angle=0, $x='',$y='') {
07299             $this->Scale(-100, 100, $x, $y);
07300             $this->Rotate(-2*($angle-90), $x, $y);
07301         }
07302         
07310         public function TranslateX($t_x) {
07311             $this->Translate($t_x, 0);
07312         }
07313         
07321         public function TranslateY($t_y) {
07322             $this->Translate(0, $t_y);
07323         }
07324         
07333         public function Translate($t_x, $t_y) {
07334             if ($this->rtl) {
07335                 $t_x = -$t_x;
07336             }
07337             
07338             $tm[0] = 1;
07339             $tm[1] = 0;
07340             $tm[2] = 0;
07341             $tm[3] = 1;
07342             $tm[4] = $t_x * $this->k;
07343             $tm[5] = -$t_y * $this->k;
07344             
07345             $this->Transform($tm);
07346         }
07347         
07357         public function Rotate($angle, $x='', $y='') {
07358             if ($x === '') {
07359                 $x = $this->x;
07360             }
07361             if ($y === '') {
07362                 $y = $this->y;
07363             }
07364             if ($this->rtl) {
07365                 $x = $this->w - $x;
07366                 $angle = -$angle;
07367             }
07368             $y = ($this->h - $y) * $this->k;
07369             $x *= $this->k;
07370             
07371             $tm[0] = cos(deg2rad($angle));
07372             $tm[1] = sin(deg2rad($angle));
07373             $tm[2] = -$tm[1];
07374             $tm[3] = $tm[0];
07375             $tm[4] = $x + ($tm[1] * $y) - ($tm[0] * $x);
07376             $tm[5] = $y - ($tm[0] * $y) - ($tm[1] * $x);
07377             
07378             $this->Transform($tm);
07379         }
07380         
07390         public function SkewX($angle_x, $x='', $y='') {
07391             $this->Skew($angle_x, 0, $x, $y);
07392         }
07393         
07403         public function SkewY($angle_y, $x='', $y='') {
07404             $this->Skew(0, $angle_y, $x, $y);
07405         }
07406         
07417         public function Skew($angle_x, $angle_y, $x='', $y='') {
07418             if ($x === '') {
07419                 $x = $this->x;
07420             }
07421             if ($y === '') {
07422                 $y = $this->y;
07423             }
07424             if ($this->rtl) {
07425                 $x = $this->w - $x;
07426                 $angle_x = -$angle_x;
07427             }
07428             if (($angle_x <= -90) OR ($angle_x >= 90) OR ($angle_y <= -90) OR ($angle_y >= 90)) {
07429                 $this->Error('Please use values between -90 and +90 degrees for Skewing.');
07430             }
07431             $x *= $this->k;
07432             $y = ($this->h - $y) * $this->k;
07433             
07434             $tm[0] = 1;
07435             $tm[1] = tan(deg2rad($angle_y));
07436             $tm[2] = tan(deg2rad($angle_x));
07437             $tm[3] = 1;
07438             $tm[4] = -$tm[2] * $y;
07439             $tm[5] = -$tm[1] * $x;
07440             
07441             $this->Transform($tm);
07442         }
07443         
07450         protected function Transform($tm) {
07451             $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5]));
07452             
07453             $this->transfmatrix[] = array('a' => $tm[0], 'b' => $tm[1], 'c' => $tm[2], 'd' => $tm[3], 'e' => $tm[4], 'f' => $tm[5]);
07454             
07455             if (end($this->transfmrk[$this->page]) !== false) {
07456                 $key = key($this->transfmrk[$this->page]);
07457                 $this->transfmrk[$this->page][$key] = $this->pagelen[$this->page];
07458             }
07459         }
07460         
07461         
07462         
07463         
07464         
07465         
07466         
07474         public function SetLineWidth($width) {
07475             
07476             $this->LineWidth = $width;
07477             $this->linestyleWidth = sprintf('%.2F w', ($width * $this->k));
07478             $this->_out($this->linestyleWidth);
07479         }
07480         
07488         public function GetLineWidth() {
07489             return $this->LineWidth;
07490         }
07491         
07513         public function SetLineStyle($style) {
07514             extract($style);
07515             if (isset($width)) {
07516                 $width_prev = $this->LineWidth;
07517                 $this->SetLineWidth($width);
07518                 $this->LineWidth = $width_prev;
07519             }
07520             if (isset($cap)) {
07521                 $ca = array('butt' => 0, 'round'=> 1, 'square' => 2);
07522                 if (isset($ca[$cap])) {
07523                     $this->linestyleCap = $ca[$cap].' J';
07524                     $this->_out($this->linestyleCap);
07525                 }
07526             }
07527             if (isset($join)) {
07528                 $ja = array('miter' => 0, 'round' => 1, 'bevel' => 2);
07529                 if (isset($ja[$join])) {
07530                     $this->linestyleJoin = $ja[$join].' j';
07531                     $this->_out($this->linestyleJoin);
07532                 }
07533             }
07534             if (isset($dash)) {
07535                 $dash_string = '';
07536                 if ($dash) {
07537                     if (ereg('^.+,', $dash)) {
07538                         $tab = explode(',', $dash);
07539                     } else {
07540                         $tab = array($dash);
07541                     }
07542                     $dash_string = '';
07543                     foreach ($tab as $i => $v) {
07544                         if ($i) {
07545                             $dash_string .= ' ';
07546                         }
07547                         $dash_string .= sprintf("%.2F", $v);
07548                     }
07549                 }
07550                 if (!isset($phase) OR !$dash) {
07551                     $phase = 0;
07552                 }
07553                 $this->linestyleDash = sprintf("[%s] %.2F d", $dash_string, $phase);
07554                 $this->_out($this->linestyleDash);
07555             }
07556             if (isset($color)) {
07557                 $this->SetDrawColorArray($color);
07558             }
07559         }
07560         
07561         
07562 
07563 
07564 
07565 
07566 
07567 
07568         protected function _outPoint($x, $y) {
07569             if ($this->rtl) {
07570                 $x = $this->w - $x;
07571             }
07572             $this->_out(sprintf("%.2F %.2F m", $x * $this->k, ($this->h - $y) * $this->k));
07573         }
07574         
07575         
07576 
07577 
07578 
07579 
07580 
07581 
07582         protected function _outLine($x, $y) {
07583             if ($this->rtl) {
07584                 $x = $this->w - $x;
07585             }
07586             $this->_out(sprintf("%.2F %.2F l", $x * $this->k, ($this->h - $y) * $this->k));
07587         }
07588         
07599         protected function _outRect($x, $y, $w, $h, $op) {
07600             if ($this->rtl) {
07601                 $x = $this->w - $x - $w;
07602             }
07603             $this->_out(sprintf('%.2F %.2F %.2F %.2F re %s', $x*$this->k, ($this->h-$y)*$this->k, $w*$this->k, -$h*$this->k, $op));
07604         }
07605         
07606         
07607 
07608 
07609 
07610 
07611 
07612 
07613 
07614 
07615 
07616 
07617 
07618         protected function _outCurve($x1, $y1, $x2, $y2, $x3, $y3) {
07619             if ($this->rtl) {
07620                 $x1 = $this->w - $x1;
07621                 $x2 = $this->w - $x2;
07622                 $x3 = $this->w - $x3;
07623             }
07624             $this->_out(sprintf("%.2F %.2F %.2F %.2F %.2F %.2F c", $x1 * $this->k, ($this->h - $y1) * $this->k, $x2 * $this->k, ($this->h - $y2) * $this->k, $x3 * $this->k, ($this->h - $y3) * $this->k));
07625         }
07626         
07638         public function Line($x1, $y1, $x2, $y2, $style=array()) {
07639             if ($style) {
07640                 $this->SetLineStyle($style);
07641             }
07642             $this->_outPoint($x1, $y1);
07643             $this->_outLine($x2, $y2);
07644             $this->_out(' S');
07645         }
07646         
07673         public function Rect($x, $y, $w, $h, $style='', $border_style=array(), $fill_color=array()) {
07674             if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
07675                 $this->SetFillColorArray($fill_color);
07676             }
07677             switch ($style) {
07678                 case 'F': {
07679                     $op = 'f';
07680                     $border_style = array();
07681                     $this->_outRect($x, $y, $w, $h, $op);
07682                     break;
07683                 }
07684                 case 'DF':
07685                 case 'FD': {
07686                     if ((!$border_style) OR (isset($border_style['all']))) {
07687                         $op = 'B';
07688                         if (isset($border_style['all'])) {
07689                             $this->SetLineStyle($border_style['all']);
07690                             $border_style = array();
07691                         }
07692                     } else {
07693                         $op = 'f';
07694                     }
07695                     $this->_outRect($x, $y, $w, $h, $op);
07696                     break;
07697                 }
07698                 case 'CNZ': {
07699                     $op = 'W n';
07700                     $this->_outRect($x, $y, $w, $h, $op);
07701                     break;
07702                 }
07703                 case 'CEO': {
07704                     $op = 'W* n';
07705                     $this->_outRect($x, $y, $w, $h, $op);
07706                     break;
07707                 }
07708                 default: {
07709                     $op = 'S';
07710                     if ((!$border_style) OR (isset($border_style['all']))) {
07711                         if (isset($border_style['all']) AND $border_style['all']) {
07712                             $this->SetLineStyle($border_style['all']);
07713                             $border_style = array();
07714                         }
07715                         $this->_outRect($x, $y, $w, $h, $op);
07716                     }
07717                     break;
07718                 }
07719             }
07720             if ($border_style) {
07721                 $border_style2 = array();
07722                 foreach ($border_style as $line => $value) {
07723                     $lenght = strlen($line);
07724                     for ($i = 0; $i < $lenght; ++$i) {
07725                         $border_style2[$line[$i]] = $value;
07726                     }
07727                 }
07728                 $border_style = $border_style2;
07729                 if (isset($border_style['L']) AND $border_style['L']) {
07730                     $this->Line($x, $y, $x, $y + $h, $border_style['L']);
07731                 }
07732                 if (isset($border_style['T']) AND $border_style['T']) {
07733                     $this->Line($x, $y, $x + $w, $y, $border_style['T']);
07734                 }
07735                 if (isset($border_style['R']) AND $border_style['R']) {
07736                     $this->Line($x + $w, $y, $x + $w, $y + $h, $border_style['R']);
07737                 }
07738                 if (isset($border_style['B']) AND $border_style['B']) {
07739                     $this->Line($x, $y + $h, $x + $w, $y + $h, $border_style['B']);
07740                 }
07741             }
07742         }
07743         
07744         
07771         public function Curve($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3, $style='', $line_style=array(), $fill_color=array()) {
07772             if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
07773                 $this->SetFillColorArray($fill_color);
07774             }
07775             switch ($style) {
07776                 case 'F': {
07777                     $op = 'f';
07778                     $line_style = array();
07779                     break;
07780                 }
07781                 case 'FD': 
07782                 case 'DF': {
07783                     $op = 'B';
07784                     break;
07785                 }
07786                 case 'CNZ': {
07787                     $op = 'W n';
07788                     break;
07789                 }
07790                 case 'CEO': {
07791                     $op = 'W* n';
07792                     break;
07793                 }
07794                 default: {
07795                     $op = 'S';
07796                     break;
07797                 }
07798             }
07799             if ($line_style) {
07800                 $this->SetLineStyle($line_style);
07801             }
07802             $this->_outPoint($x0, $y0);
07803             $this->_outCurve($x1, $y1, $x2, $y2, $x3, $y3);
07804             $this->_out($op);
07805         }
07806         
07828         public function Polycurve($x0, $y0, $segments, $style='', $line_style=array(), $fill_color=array()) {
07829             if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
07830                 $this->SetFillColorArray($fill_color);
07831             }
07832             switch ($style) {
07833                 case 'F': {
07834                     $op = 'f';
07835                     $line_style = array();
07836                     break;
07837                 }
07838                 case 'FD':
07839                 case 'DF': {
07840                     $op = 'B';
07841                     break;
07842                 }
07843                 case 'CNZ': {
07844                     $op = 'W n';
07845                     break;
07846                 }
07847                 case 'CEO': {
07848                     $op = 'W* n';
07849                     break;
07850                 }
07851                 default: {
07852                     $op = 'S';
07853                     break;
07854                 }
07855             }
07856             if ($line_style) {
07857                 $this->SetLineStyle($line_style);
07858             }
07859             $this->_outPoint($x0, $y0);
07860             foreach ($segments as $segment) {
07861                 list($x1, $y1, $x2, $y2, $x3, $y3) = $segment;
07862                 $this->_outCurve($x1, $y1, $x2, $y2, $x3, $y3);
07863             }   
07864             $this->_out($op);
07865         }
07866         
07892         public function Ellipse($x0, $y0, $rx, $ry=0, $angle=0, $astart=0, $afinish=360, $style='', $line_style=array(), $fill_color=array(), $nc=8) {
07893             if ($angle) {
07894                 $this->StartTransform();
07895                 $this->Rotate($angle, $x0, $y0);
07896                 $this->Ellipse($x0, $y0, $rx, $ry, 0, $astart, $afinish, $style, $line_style, $fill_color, $nc);
07897                 $this->StopTransform();
07898                 return;
07899             }
07900             if ($rx) {
07901                 if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
07902                     $this->SetFillColorArray($fill_color);
07903                 }
07904                 switch ($style) {
07905                     case 'F': {
07906                         $op = 'f';
07907                         $line_style = array();
07908                         break;
07909                     }
07910                     case 'FD': 
07911                     case 'DF': {
07912                         $op = 'B';
07913                         break;
07914                     }
07915                     case 'C': {
07916                         $op = 's'; 
07917                         break;
07918                     }
07919                     case 'CNZ': {
07920                         $op = 'W n';
07921                         break;
07922                     }
07923                     case 'CEO': {
07924                         $op = 'W* n';
07925                         break;
07926                     }
07927                     default: {
07928                         $op = 'S';
07929                         break;
07930                     }
07931                 }
07932                 if ($line_style) {
07933                     $this->SetLineStyle($line_style);
07934                 }
07935                 if (!$ry) {
07936                     $ry = $rx;
07937                 }
07938                 $rx *= $this->k;
07939                 $ry *= $this->k;
07940                 if ($nc < 2) {
07941                     $nc = 2;
07942                 }
07943                 $astart = deg2rad((float) $astart);
07944                 $afinish = deg2rad((float) $afinish);
07945                 $total_angle = $afinish - $astart;
07946                 $dt = $total_angle / $nc;
07947                 $dtm = $dt / 3;
07948                 $x0 *= $this->k;
07949                 $y0 = ($this->h - $y0) * $this->k;
07950                 $t1 = $astart;
07951                 $a0 = $x0 + ($rx * cos($t1));
07952                 $b0 = $y0 + ($ry * sin($t1));
07953                 $c0 = -$rx * sin($t1);
07954                 $d0 = $ry * cos($t1);
07955                 $this->_outPoint($a0 / $this->k, $this->h - ($b0 / $this->k));
07956                 for ($i = 1; $i <= $nc; ++$i) {
07957                     
07958                     $t1 = ($i * $dt) + $astart;
07959                     $a1 = $x0 + ($rx * cos($t1));
07960                     $b1 = $y0 + ($ry * sin($t1));
07961                     $c1 = -$rx * sin($t1);
07962                     $d1 = $ry * cos($t1);
07963                     $this->_outCurve(($a0 + ($c0 * $dtm)) / $this->k, $this->h - (($b0 + ($d0 * $dtm)) / $this->k), ($a1 - ($c1 * $dtm)) / $this->k, $this->h - (($b1 - ($d1 * $dtm)) / $this->k), $a1 / $this->k, $this->h - ($b1 / $this->k));
07964                     $a0 = $a1;
07965                     $b0 = $b1;
07966                     $c0 = $c1;
07967                     $d0 = $d1;
07968                 }
07969                 $this->_out($op);
07970             }
07971         }
07972         
07996         public function Circle($x0, $y0, $r, $astart=0, $afinish=360, $style='', $line_style=array(), $fill_color=array(), $nc=8) {
07997             $this->Ellipse($x0, $y0, $r, 0, 0, $astart, $afinish, $style, $line_style, $fill_color, $nc);
07998         }
07999         
08021         public function Polygon($p, $style='', $line_style=array(), $fill_color=array()) {
08022             $np = count($p) / 2;
08023             if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
08024                 $this->SetFillColorArray($fill_color);
08025             }
08026             switch ($style) {
08027                 case 'F': {
08028                     $line_style = array();
08029                     $op = 'f';
08030                     break;
08031                 }
08032                 case 'FD': 
08033                 case 'DF': {
08034                     $op = 'B';
08035                     break;
08036                 }
08037                 case 'CNZ': {
08038                     $op = 'W n';
08039                     break;
08040                 }
08041                 case 'CEO': {
08042                     $op = 'W* n';
08043                     break;
08044                 }               
08045                 default: {
08046                     $op = 'S';
08047                     break;
08048                 }
08049             }
08050             $draw = true;
08051             if ($line_style) {
08052                 if (isset($line_style['all'])) {
08053                     $this->SetLineStyle($line_style['all']);
08054                 } else { 
08055                     $draw = false;
08056                     if ('B' == $op) {
08057                         $op = 'f';
08058                         $this->_outPoint($p[0], $p[1]);
08059                         for ($i = 2; $i < ($np * 2); $i = $i + 2) {
08060                             $this->_outLine($p[$i], $p[$i + 1]);
08061                         }
08062                         $this->_outLine($p[0], $p[1]);
08063                         $this->_out($op);
08064                     }
08065                     $p[($np * 2)] = $p[0];
08066                     $p[(($np * 2) + 1)] = $p[1];
08067                     for ($i = 0; $i < $np; ++$i) {
08068                         if (isset($line_style[$i]) AND ($line_style[$i] != 0)) {
08069                             $this->Line($p[($i * 2)], $p[(($i * 2) + 1)], $p[(($i * 2) + 2)], $p[(($i * 2) + 3)], $line_style[$i]);
08070                         }
08071                     }
08072                 }
08073             }
08074             if ($draw) {
08075                 $this->_outPoint($p[0], $p[1]);
08076                 for ($i = 2; $i < ($np * 2); $i = $i + 2) {
08077                     $this->_outLine($p[$i], $p[$i + 1]);
08078                 }
08079                 $this->_outLine($p[0], $p[1]);
08080                 $this->_out($op);
08081             }
08082         }
08083         
08120         public function RegularPolygon($x0, $y0, $r, $ns, $angle=0, $draw_circle=false, $style='', $line_style=array(), $fill_color=array(), $circle_style='', $circle_outLine_style=array(), $circle_fill_color=array()) {
08121             if (3 > $ns) {
08122                 $ns = 3;
08123             }
08124             if ($draw_circle) {
08125                 $this->Circle($x0, $y0, $r, 0, 360, $circle_style, $circle_outLine_style, $circle_fill_color);
08126             }
08127             $p = array();
08128             for ($i = 0; $i < $ns; ++$i) {
08129                 $a = $angle + ($i * 360 / $ns);
08130                 $a_rad = deg2rad((float) $a);
08131                 $p[] = $x0 + ($r * sin($a_rad));
08132                 $p[] = $y0 + ($r * cos($a_rad));
08133             }
08134             $this->Polygon($p, $style, $line_style, $fill_color);
08135         }
08136         
08175         public function StarPolygon($x0, $y0, $r, $nv, $ng, $angle=0, $draw_circle=false, $style='', $line_style=array(), $fill_color=array(), $circle_style='', $circle_outLine_style=array(), $circle_fill_color=array()) {
08176             if (2 > $nv) {
08177                 $nv = 2;
08178             }
08179             if ($draw_circle) {
08180                 $this->Circle($x0, $y0, $r, 0, 360, $circle_style, $circle_outLine_style, $circle_fill_color);
08181             }
08182             $p2 = array();
08183             $visited = array();
08184             for ($i = 0; $i < $nv; ++$i) {
08185                 $a = $angle + ($i * 360 / $nv);
08186                 $a_rad = deg2rad((float) $a);
08187                 $p2[] = $x0 + ($r * sin($a_rad));
08188                 $p2[] = $y0 + ($r * cos($a_rad));
08189                 $visited[] = false;
08190             }
08191             $p = array();
08192             $i = 0;
08193             do {
08194                 $p[] = $p2[$i * 2];
08195                 $p[] = $p2[($i * 2) + 1];
08196                 $visited[$i] = true;
08197                 $i += $ng;
08198                 $i %= $nv;
08199             } while (!$visited[$i]);
08200             $this->Polygon($p, $style, $line_style, $fill_color);
08201         }
08202         
08224         public function RoundedRect($x, $y, $w, $h, $r, $round_corner='1111', $style='', $border_style=array(), $fill_color=array()) {
08225             if ('0000' == $round_corner) { 
08226                 $this->Rect($x, $y, $w, $h, $style, $border_style, $fill_color);
08227             } else { 
08228                 if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
08229                     $this->SetFillColorArray($fill_color);
08230                 }
08231                 switch ($style) {
08232                     case 'F': {
08233                         $border_style = array();
08234                         $op = 'f';
08235                         break;
08236                     }
08237                     case 'FD': 
08238                     case 'DF': {
08239                         $op = 'B';
08240                         break;
08241                     }
08242                     case 'CNZ': {
08243                         $op = 'W n';
08244                         break;
08245                     }
08246                     case 'CEO': {
08247                         $op = 'W* n';
08248                         break;
08249                     }
08250                     default: {
08251                         $op = 'S';
08252                         break;
08253                     }
08254                 }
08255                 if ($border_style) {
08256                     $this->SetLineStyle($border_style);
08257                 }
08258                 $MyArc = 4 / 3 * (sqrt(2) - 1);
08259                 $this->_outPoint($x + $r, $y);
08260                 $xc = $x + $w - $r;
08261                 $yc = $y + $r;
08262                 $this->_outLine($xc, $y);
08263                 if ($round_corner[0]) {
08264                     $this->_outCurve($xc + ($r * $MyArc), $yc - $r, $xc + $r, $yc - ($r * $MyArc), $xc + $r, $yc);
08265                 } else {
08266                     $this->_outLine($x + $w, $y);
08267                 }
08268                 $xc = $x + $w - $r;
08269                 $yc = $y + $h - $r;
08270                 $this->_outLine($x + $w, $yc);
08271                 if ($round_corner[1]) {
08272                     $this->_outCurve($xc + $r, $yc + ($r * $MyArc), $xc + ($r * $MyArc), $yc + $r, $xc, $yc + $r);
08273                 } else {
08274                     $this->_outLine($x + $w, $y + $h);
08275                 }
08276                 $xc = $x + $r;
08277                 $yc = $y + $h - $r;
08278                 $this->_outLine($xc, $y + $h);
08279                 if ($round_corner[2]) {
08280                     $this->_outCurve($xc - ($r * $MyArc), $yc + $r, $xc - $r, $yc + ($r * $MyArc), $xc - $r, $yc);
08281                 } else {
08282                     $this->_outLine($x, $y + $h);
08283                 }
08284                 $xc = $x + $r;
08285                 $yc = $y + $r;
08286                 $this->_outLine($x, $yc);
08287                 if ($round_corner[3]) {
08288                     $this->_outCurve($xc - $r, $yc - ($r * $MyArc), $xc - ($r * $MyArc), $yc - $r, $xc, $yc - $r);
08289                 } else {
08290                     $this->_outLine($x, $y);
08291                     $this->_outLine($x + $r, $y);
08292                 }
08293                 $this->_out($op);
08294             }
08295         }
08296         
08297         
08298         
08299         
08309         protected function utf8StrRev($str, $setbom=false, $forcertl=false) {
08310             return $this->arrUTF8ToUTF16BE($this->utf8Bidi($this->UTF8StringToArray($str), $str, $forcertl), $setbom);
08311         }
08312         
08323         protected function utf8Bidi($ta, $str='', $forcertl=false) {
08324             global $unicode, $unicode_mirror, $unicode_arlet, $laa_array, $diacritics;
08325             
08326             $pel = 0;
08327             
08328             $maxlevel = 0;
08329             if ($this->empty_string($str)) {
08330                 
08331                 $str = $this->UTF8ArrSubString($ta);
08332             }
08333             
08334             if (preg_match(K_RE_PATTERN_ARABIC, $str)) {
08335                 $arabic = true;
08336             } else {
08337                 $arabic = false;
08338             }
08339             
08340             if (!($forcertl OR $arabic OR preg_match(K_RE_PATTERN_RTL, $str))) {
08341                 return $ta;
08342             }
08343             
08344             
08345             $numchars = count($ta);
08346             
08347             if ($forcertl == 'R') {
08348                     $pel = 1;
08349             } elseif ($forcertl == 'L') {
08350                     $pel = 0;
08351             } else {
08352                 
08353                 
08354                 for ($i=0; $i < $numchars; ++$i) {
08355                     $type = $unicode[$ta[$i]];
08356                     if ($type == 'L') {
08357                         $pel = 0;
08358                         break;
08359                     } elseif (($type == 'AL') OR ($type == 'R')) {
08360                         $pel = 1;
08361                         break;
08362                     }
08363                 }
08364             }
08365             
08366             
08367             $cel = $pel;
08368             
08369             $dos = 'N';
08370             $remember = array();
08371             
08372             $sor = $pel % 2 ? 'R' : 'L';
08373             $eor = $sor;
08374             
08375             
08376             $chardata = Array();
08377             
08378             
08379             
08380             for ($i=0; $i < $numchars; ++$i) {
08381                 if ($ta[$i] == K_RLE) {
08382                     
08383                     
08384                     
08385                     $next_level = $cel + ($cel % 2) + 1;
08386                     if ($next_level < 62) {
08387                         $remember[] = array('num' => K_RLE, 'cel' => $cel, 'dos' => $dos);
08388                         $cel = $next_level;
08389                         $dos = 'N';
08390                         $sor = $eor;
08391                         $eor = $cel % 2 ? 'R' : 'L';
08392                     }
08393                 } elseif ($ta[$i] == K_LRE) {
08394                     
08395                     
08396                     
08397                     $next_level = $cel + 2 - ($cel % 2);
08398                     if ( $next_level < 62 ) {
08399                         $remember[] = array('num' => K_LRE, 'cel' => $cel, 'dos' => $dos);
08400                         $cel = $next_level;
08401                         $dos = 'N';
08402                         $sor = $eor;
08403                         $eor = $cel % 2 ? 'R' : 'L';
08404                     }
08405                 } elseif ($ta[$i] == K_RLO) {
08406                     
08407                     
08408                     
08409                     $next_level = $cel + ($cel % 2) + 1;
08410                     if ($next_level < 62) {
08411                         $remember[] = array('num' => K_RLO, 'cel' => $cel, 'dos' => $dos);
08412                         $cel = $next_level;
08413                         $dos = 'R';
08414                         $sor = $eor;
08415                         $eor = $cel % 2 ? 'R' : 'L';
08416                     }
08417                 } elseif ($ta[$i] == K_LRO) {
08418                     
08419                     
08420                     
08421                     $next_level = $cel + 2 - ($cel % 2);
08422                     if ( $next_level < 62 ) {
08423                         $remember[] = array('num' => K_LRO, 'cel' => $cel, 'dos' => $dos);
08424                         $cel = $next_level;
08425                         $dos = 'L';
08426                         $sor = $eor;
08427                         $eor = $cel % 2 ? 'R' : 'L';
08428                     }
08429                 } elseif ($ta[$i] == K_PDF) {
08430                     
08431                     if (count($remember)) {
08432                         $last = count($remember ) - 1;
08433                         if (($remember[$last]['num'] == K_RLE) OR 
08434                               ($remember[$last]['num'] == K_LRE) OR 
08435                               ($remember[$last]['num'] == K_RLO) OR 
08436                               ($remember[$last]['num'] == K_LRO)) {
08437                             $match = array_pop($remember);
08438                             $cel = $match['cel'];
08439                             $dos = $match['dos'];
08440                             $sor = $eor;
08441                             $eor = ($cel > $match['cel'] ? $cel : $match['cel']) % 2 ? 'R' : 'L';
08442                         }
08443                     }
08444                 } elseif (($ta[$i] != K_RLE) AND
08445                                  ($ta[$i] != K_LRE) AND
08446                                  ($ta[$i] != K_RLO) AND
08447                                  ($ta[$i] != K_LRO) AND
08448                                  ($ta[$i] != K_PDF)) {
08449                     
08450                     
08451                     
08452                     if ($dos != 'N') {
08453                         $chardir = $dos;
08454                     } else {
08455                         $chardir = $unicode[$ta[$i]];
08456                     }
08457                     
08458                     $chardata[] = array('char' => $ta[$i], 'level' => $cel, 'type' => $chardir, 'sor' => $sor, 'eor' => $eor);
08459                 }
08460             } 
08461             
08462             
08463             
08464             
08465             
08466             
08467             
08468             
08469             $numchars = count($chardata);
08470             
08471             
08472             $prevlevel = -1; 
08473             $levcount = 0; 
08474             for ($i=0; $i < $numchars; ++$i) {
08475                 if ($chardata[$i]['type'] == 'NSM') {
08476                     if ($levcount) {
08477                         $chardata[$i]['type'] = $chardata[$i]['sor'];
08478                     } elseif ($i > 0) {
08479                         $chardata[$i]['type'] = $chardata[($i-1)]['type'];
08480                     }
08481                 }
08482                 if ($chardata[$i]['level'] != $prevlevel) {
08483                     $levcount = 0;
08484                 } else {
08485                     ++$levcount;
08486                 }
08487                 $prevlevel = $chardata[$i]['level'];
08488             }
08489             
08490             
08491             $prevlevel = -1;
08492             $levcount = 0;
08493             for ($i=0; $i < $numchars; ++$i) {
08494                 if ($chardata[$i]['char'] == 'EN') {
08495                     for ($j=$levcount; $j >= 0; $j--) {
08496                         if ($chardata[$j]['type'] == 'AL') {
08497                             $chardata[$i]['type'] = 'AN';
08498                         } elseif (($chardata[$j]['type'] == 'L') OR ($chardata[$j]['type'] == 'R')) {
08499                             break;
08500                         }
08501                     }
08502                 }
08503                 if ($chardata[$i]['level'] != $prevlevel) {
08504                     $levcount = 0;
08505                 } else {
08506                     ++$levcount;
08507                 }
08508                 $prevlevel = $chardata[$i]['level'];
08509             }
08510             
08511             
08512             for ($i=0; $i < $numchars; ++$i) {
08513                 if ($chardata[$i]['type'] == 'AL') {
08514                     $chardata[$i]['type'] = 'R';
08515                 } 
08516             }
08517             
08518             
08519             $prevlevel = -1;
08520             $levcount = 0;
08521             for ($i=0; $i < $numchars; ++$i) {
08522                 if (($levcount > 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) {
08523                     if (($chardata[$i]['type'] == 'ES') AND ($chardata[($i-1)]['type'] == 'EN') AND ($chardata[($i+1)]['type'] == 'EN')) {
08524                         $chardata[$i]['type'] = 'EN';
08525                     } elseif (($chardata[$i]['type'] == 'CS') AND ($chardata[($i-1)]['type'] == 'EN') AND ($chardata[($i+1)]['type'] == 'EN')) {
08526                         $chardata[$i]['type'] = 'EN';
08527                     } elseif (($chardata[$i]['type'] == 'CS') AND ($chardata[($i-1)]['type'] == 'AN') AND ($chardata[($i+1)]['type'] == 'AN')) {
08528                         $chardata[$i]['type'] = 'AN';
08529                     }
08530                 }
08531                 if ($chardata[$i]['level'] != $prevlevel) {
08532                     $levcount = 0;
08533                 } else {
08534                     ++$levcount;
08535                 }
08536                 $prevlevel = $chardata[$i]['level'];
08537             }
08538             
08539             
08540             $prevlevel = -1;
08541             $levcount = 0;
08542             for ($i=0; $i < $numchars; ++$i) {
08543                 if ($chardata[$i]['type'] == 'ET') {
08544                     if (($levcount > 0) AND ($chardata[($i-1)]['type'] == 'EN')) {
08545                         $chardata[$i]['type'] = 'EN';
08546                     } else {
08547                         $j = $i+1;
08548                         while (($j < $numchars) AND ($chardata[$j]['level'] == $prevlevel)) {
08549                             if ($chardata[$j]['type'] == 'EN') {
08550                                 $chardata[$i]['type'] = 'EN';
08551                                 break;
08552                             } elseif ($chardata[$j]['type'] != 'ET') {
08553                                 break;
08554                             }
08555                             ++$j;
08556                         }
08557                     }
08558                 }
08559                 if ($chardata[$i]['level'] != $prevlevel) {
08560                     $levcount = 0;
08561                 } else {
08562                     ++$levcount;
08563                 }
08564                 $prevlevel = $chardata[$i]['level'];
08565             }
08566             
08567             
08568             $prevlevel = -1;
08569             $levcount = 0;
08570             for ($i=0; $i < $numchars; ++$i) {
08571                 if (($chardata[$i]['type'] == 'ET') OR ($chardata[$i]['type'] == 'ES') OR ($chardata[$i]['type'] == 'CS')) {
08572                     $chardata[$i]['type'] = 'ON';
08573                 }
08574                 if ($chardata[$i]['level'] != $prevlevel) {
08575                     $levcount = 0;
08576                 } else {
08577                     ++$levcount;
08578                 }
08579                 $prevlevel = $chardata[$i]['level'];
08580             }
08581             
08582             
08583             $prevlevel = -1;
08584             $levcount = 0;
08585             for ($i=0; $i < $numchars; ++$i) {
08586                 if ($chardata[$i]['char'] == 'EN') {
08587                     for ($j=$levcount; $j >= 0; $j--) {
08588                         if ($chardata[$j]['type'] == 'L') {
08589                             $chardata[$i]['type'] = 'L';
08590                         } elseif ($chardata[$j]['type'] == 'R') {
08591                             break;
08592                         }
08593                     }
08594                 }
08595                 if ($chardata[$i]['level'] != $prevlevel) {
08596                     $levcount = 0;
08597                 } else {
08598                     ++$levcount;
08599                 }
08600                 $prevlevel = $chardata[$i]['level'];
08601             }
08602             
08603             
08604             $prevlevel = -1;
08605             $levcount = 0;
08606             for ($i=0; $i < $numchars; ++$i) {
08607                 if (($levcount > 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) {
08608                     if (($chardata[$i]['type'] == 'N') AND ($chardata[($i-1)]['type'] == 'L') AND ($chardata[($i+1)]['type'] == 'L')) {
08609                         $chardata[$i]['type'] = 'L';
08610                     } elseif (($chardata[$i]['type'] == 'N') AND
08611                      (($chardata[($i-1)]['type'] == 'R') OR ($chardata[($i-1)]['type'] == 'EN') OR ($chardata[($i-1)]['type'] == 'AN')) AND
08612                      (($chardata[($i+1)]['type'] == 'R') OR ($chardata[($i+1)]['type'] == 'EN') OR ($chardata[($i+1)]['type'] == 'AN'))) {
08613                         $chardata[$i]['type'] = 'R';
08614                     } elseif ($chardata[$i]['type'] == 'N') {
08615                         
08616                         $chardata[$i]['type'] = $chardata[$i]['sor'];
08617                     }
08618                 } elseif (($levcount == 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) {
08619                     
08620                     if (($chardata[$i]['type'] == 'N') AND ($chardata[$i]['sor'] == 'L') AND ($chardata[($i+1)]['type'] == 'L')) {
08621                         $chardata[$i]['type'] = 'L';
08622                     } elseif (($chardata[$i]['type'] == 'N') AND
08623                      (($chardata[$i]['sor'] == 'R') OR ($chardata[$i]['sor'] == 'EN') OR ($chardata[$i]['sor'] == 'AN')) AND
08624                      (($chardata[($i+1)]['type'] == 'R') OR ($chardata[($i+1)]['type'] == 'EN') OR ($chardata[($i+1)]['type'] == 'AN'))) {
08625                         $chardata[$i]['type'] = 'R';
08626                     } elseif ($chardata[$i]['type'] == 'N') {
08627                         
08628                         $chardata[$i]['type'] = $chardata[$i]['sor'];
08629                     }
08630                 } elseif (($levcount > 0) AND ((($i+1) == $numchars) OR (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] != $prevlevel))) {
08631                     
08632                     if (($chardata[$i]['type'] == 'N') AND ($chardata[($i-1)]['type'] == 'L') AND ($chardata[$i]['eor'] == 'L')) {
08633                         $chardata[$i]['type'] = 'L';
08634                     } elseif (($chardata[$i]['type'] == 'N') AND
08635                      (($chardata[($i-1)]['type'] == 'R') OR ($chardata[($i-1)]['type'] == 'EN') OR ($chardata[($i-1)]['type'] == 'AN')) AND
08636                      (($chardata[$i]['eor'] == 'R') OR ($chardata[$i]['eor'] == 'EN') OR ($chardata[$i]['eor'] == 'AN'))) {
08637                         $chardata[$i]['type'] = 'R';
08638                     } elseif ($chardata[$i]['type'] == 'N') {
08639                         
08640                         $chardata[$i]['type'] = $chardata[$i]['sor'];
08641                     }
08642                 } elseif ($chardata[$i]['type'] == 'N') {
08643                     
08644                     $chardata[$i]['type'] = $chardata[$i]['sor'];
08645                 }
08646                 if ($chardata[$i]['level'] != $prevlevel) {
08647                     $levcount = 0;
08648                 } else {
08649                     ++$levcount;
08650                 }
08651                 $prevlevel = $chardata[$i]['level'];
08652             }
08653             
08654             
08655             
08656             for ($i=0; $i < $numchars; ++$i) {
08657                 $odd = $chardata[$i]['level'] % 2;
08658                 if ($odd) {
08659                     if (($chardata[$i]['type'] == 'L') OR ($chardata[$i]['type'] == 'AN') OR ($chardata[$i]['type'] == 'EN')) {
08660                         $chardata[$i]['level'] += 1;
08661                     }
08662                 } else {
08663                     if ($chardata[$i]['type'] == 'R') {
08664                         $chardata[$i]['level'] += 1;
08665                     } elseif (($chardata[$i]['type'] == 'AN') OR ($chardata[$i]['type'] == 'EN')) {
08666                         $chardata[$i]['level'] += 2;
08667                     }
08668                 }
08669                 $maxlevel = max($chardata[$i]['level'],$maxlevel);
08670             }
08671             
08672             
08673             
08674             
08675             
08676             
08677             for ($i=0; $i < $numchars; ++$i) {
08678                 if (($chardata[$i]['type'] == 'B') OR ($chardata[$i]['type'] == 'S')) {
08679                     $chardata[$i]['level'] = $pel;
08680                 } elseif ($chardata[$i]['type'] == 'WS') {
08681                     $j = $i+1;
08682                     while ($j < $numchars) {
08683                         if ((($chardata[$j]['type'] == 'B') OR ($chardata[$j]['type'] == 'S')) OR
08684                             (($j == ($numchars-1)) AND ($chardata[$j]['type'] == 'WS'))) {
08685                             $chardata[$i]['level'] = $pel;
08686                             break;
08687                         } elseif ($chardata[$j]['type'] != 'WS') {
08688                             break;
08689                         }
08690                         ++$j;
08691                     }
08692                 }
08693             }
08694             
08695             
08696             
08697             if ($arabic) {
08698                 $endedletter = array(1569,1570,1571,1572,1573,1575,1577,1583,1584,1585,1586,1608,1688);
08699                 $alfletter = array(1570,1571,1573,1575);
08700                 $chardata2 = $chardata;
08701                 $laaletter = false;
08702                 $charAL = array();
08703                 $x = 0;
08704                 for ($i=0; $i < $numchars; ++$i) {
08705                     if (($unicode[$chardata[$i]['char']] == 'AL') OR ($chardata[$i]['char'] == 32) OR ($chardata[$i]['char'] == 8204)) {
08706                         $charAL[$x] = $chardata[$i];
08707                         $charAL[$x]['i'] = $i;
08708                         $chardata[$i]['x'] = $x;
08709                         ++$x;
08710                     }
08711                 }
08712                 $numAL = $x;
08713                 for ($i=0; $i < $numchars; ++$i) {
08714                     $thischar = $chardata[$i];
08715                     if ($i > 0) {
08716                         $prevchar = $chardata[($i-1)];
08717                     } else {
08718                         $prevchar = false;
08719                     }
08720                     if (($i+1) < $numchars) {
08721                         $nextchar = $chardata[($i+1)];
08722                     } else {
08723                         $nextchar = false;
08724                     }
08725                     if ($unicode[$thischar['char']] == 'AL') {
08726                         $x = $thischar['x'];
08727                         if ($x > 0) {
08728                             $prevchar = $charAL[($x-1)];
08729                         } else {
08730                             $prevchar = false;
08731                         }
08732                         if (($x+1) < $numAL) {
08733                             $nextchar = $charAL[($x+1)];
08734                         } else {
08735                             $nextchar = false;
08736                         }
08737                         
08738                         if (($prevchar !== false) AND ($prevchar['char'] == 1604) AND (in_array($thischar['char'], $alfletter))) {
08739                             $arabicarr = $laa_array;
08740                             $laaletter = true;
08741                             if ($x > 1) {
08742                                 $prevchar = $charAL[($x-2)];
08743                             } else {
08744                                 $prevchar = false;
08745                             }
08746                         } else {
08747                             $arabicarr = $unicode_arlet;
08748                             $laaletter = false;
08749                         }
08750                         if (($prevchar !== false) AND ($nextchar !== false) AND
08751                             (($unicode[$prevchar['char']] == 'AL') OR ($unicode[$prevchar['char']] == 'NSM')) AND
08752                             (($unicode[$nextchar['char']] == 'AL') OR ($unicode[$nextchar['char']] == 'NSM')) AND
08753                             ($prevchar['type'] == $thischar['type']) AND
08754                             ($nextchar['type'] == $thischar['type']) AND
08755                             ($nextchar['char'] != 1567)) {
08756                             if (in_array($prevchar['char'], $endedletter)) {
08757                                 if (isset($arabicarr[$thischar['char']][2])) {
08758                                     
08759                                     $chardata2[$i]['char'] = $arabicarr[$thischar['char']][2];
08760                                 }
08761                             } else {
08762                                 if (isset($arabicarr[$thischar['char']][3])) {
08763                                     
08764                                     $chardata2[$i]['char'] = $arabicarr[$thischar['char']][3];
08765                                 }
08766                             }
08767                         } elseif (($nextchar !== false) AND
08768                             (($unicode[$nextchar['char']] == 'AL') OR ($unicode[$nextchar['char']] == 'NSM')) AND
08769                             ($nextchar['type'] == $thischar['type']) AND
08770                             ($nextchar['char'] != 1567)) {
08771                             if (isset($arabicarr[$chardata[$i]['char']][2])) {
08772                                 
08773                                 $chardata2[$i]['char'] = $arabicarr[$thischar['char']][2];
08774                             }
08775                         } elseif ((($prevchar !== false) AND
08776                             (($unicode[$prevchar['char']] == 'AL') OR ($unicode[$prevchar['char']] == 'NSM')) AND
08777                             ($prevchar['type'] == $thischar['type'])) OR
08778                             (($nextchar !== false) AND ($nextchar['char'] == 1567))) {
08779                             
08780                             if (($i > 1) AND ($thischar['char'] == 1607) AND
08781                                 ($chardata[$i-1]['char'] == 1604) AND
08782                                 ($chardata[$i-2]['char'] == 1604)) {
08783                                 
08784                                 
08785                                 $chardata2[$i-2]['char'] = false;
08786                                 $chardata2[$i-1]['char'] = false; 
08787                                 $chardata2[$i]['char'] = 65010;
08788                             } else {
08789                                 if (($prevchar !== false) AND in_array($prevchar['char'], $endedletter)) {
08790                                     if (isset($arabicarr[$thischar['char']][0])) {
08791                                         
08792                                         $chardata2[$i]['char'] = $arabicarr[$thischar['char']][0];
08793                                     }
08794                                 } else {
08795                                     if (isset($arabicarr[$thischar['char']][1])) {
08796                                         
08797                                         $chardata2[$i]['char'] = $arabicarr[$thischar['char']][1];
08798                                     }
08799                                 }
08800                             }
08801                         } elseif (isset($arabicarr[$thischar['char']][0])) {
08802                             
08803                             $chardata2[$i]['char'] = $arabicarr[$thischar['char']][0];
08804                         }
08805                         
08806                         if ($laaletter) {
08807                             
08808                             $chardata2[($charAL[($x-1)]['i'])]['char'] = false;
08809                         }
08810                     } 
08811                 } 
08812                 
08813 
08814 
08815 
08816                 $cw = &$this->CurrentFont['cw'];
08817                 for ($i = 0; $i < ($numchars-1); ++$i) {
08818                     if (($chardata2[$i]['char'] == 1617) AND (isset($diacritics[($chardata2[$i+1]['char'])]))) {
08819                         
08820                         if (isset($cw[($diacritics[($chardata2[$i+1]['char'])])])) {
08821                             $chardata2[$i]['char'] = false;
08822                             $chardata2[$i+1]['char'] = $diacritics[($chardata2[$i+1]['char'])];
08823                         }
08824                     }
08825                 }
08826                 
08827                 foreach ($chardata2 as $key => $value) {
08828                     if ($value['char'] === false) {
08829                         unset($chardata2[$key]);
08830                     }
08831                 }
08832                 $chardata = array_values($chardata2);
08833                 $numchars = count($chardata);
08834                 unset($chardata2);
08835                 unset($arabicarr);
08836                 unset($laaletter);
08837                 unset($charAL);
08838             }
08839             
08840             
08841             for ($j=$maxlevel; $j > 0; $j--) {
08842                 $ordarray = Array();
08843                 $revarr = Array();
08844                 $onlevel = false;
08845                 for ($i=0; $i < $numchars; ++$i) {
08846                     if ($chardata[$i]['level'] >= $j) {
08847                         $onlevel = true;
08848                         if (isset($unicode_mirror[$chardata[$i]['char']])) {
08849                             
08850                             $chardata[$i]['char'] = $unicode_mirror[$chardata[$i]['char']];
08851                         }
08852                         $revarr[] = $chardata[$i];
08853                     } else {
08854                         if ($onlevel) {
08855                             $revarr = array_reverse($revarr);
08856                             $ordarray = array_merge($ordarray, $revarr);
08857                             $revarr = Array();
08858                             $onlevel = false;
08859                         }
08860                         $ordarray[] = $chardata[$i];
08861                     }
08862                 }
08863                 if ($onlevel) {
08864                     $revarr = array_reverse($revarr);
08865                     $ordarray = array_merge($ordarray, $revarr);
08866                 }
08867                 $chardata = $ordarray;
08868             }
08869             
08870             $ordarray = array();
08871             for ($i=0; $i < $numchars; ++$i) {
08872                 $ordarray[] = $chardata[$i]['char'];
08873             }
08874             
08875             return $ordarray;
08876         }
08877         
08878         
08879         
08880         
08881 
08882 
08883 
08884 
08885 
08886 
08887 
08888 
08889 
08890         public function Bookmark($txt, $level=0, $y=-1, $page='') {
08891             if ($level < 0) {
08892                 $level = 0;
08893             }
08894             if (isset($this->outlines[0])) {
08895                 $lastoutline = end($this->outlines);
08896                 $maxlevel = $lastoutline['l'] + 1;
08897             } else {
08898                 $maxlevel = 0;
08899             }
08900             if ($level > $maxlevel) {
08901                 $level = $maxlevel;
08902             }
08903             if ($y == -1) {
08904                 $y = $this->GetY();
08905             }
08906             if (empty($page)) {
08907                 $page = $this->PageNo();
08908             }
08909             $this->outlines[] = array('t' => $txt, 'l' => $level, 'y' => $y, 'p' => $page);
08910         }
08911         
08912         
08913 
08914 
08915 
08916 
08917 
08918         protected function _putbookmarks() {
08919             $nb = count($this->outlines);
08920             if ($nb == 0) {
08921                 return;
08922             }
08923             $lru = array();
08924             $level = 0;
08925             foreach ($this->outlines as $i => $o) {
08926                 if ($o['l'] > 0) {
08927                     $parent = $lru[($o['l'] - 1)];
08928                     
08929                     $this->outlines[$i]['parent'] = $parent;
08930                     $this->outlines[$parent]['last'] = $i;
08931                     if ($o['l'] > $level) {
08932                         
08933                         $this->outlines[$parent]['first'] = $i;
08934                     }
08935                 } else {
08936                     $this->outlines[$i]['parent'] = $nb;
08937                 }
08938                 if (($o['l'] <= $level) AND ($i > 0)) {
08939                     
08940                     $prev = $lru[$o['l']];
08941                     $this->outlines[$prev]['next'] = $i;
08942                     $this->outlines[$i]['prev'] = $prev;
08943                 }
08944                 $lru[$o['l']] = $i;
08945                 $level = $o['l'];
08946             }
08947             
08948             $n = $this->n + 1;
08949             foreach ($this->outlines as $i => $o) {
08950                 $this->_newobj();
08951                 $this->_out('<</Title '.$this->_textstring($o['t']));
08952                 $this->_out('/Parent '.($n + $o['parent']).' 0 R');
08953                 if (isset($o['prev']))
08954                 $this->_out('/Prev '.($n + $o['prev']).' 0 R');
08955                 if (isset($o['next']))
08956                 $this->_out('/Next '.($n + $o['next']).' 0 R');
08957                 if (isset($o['first']))
08958                 $this->_out('/First '.($n + $o['first']).' 0 R');
08959                 if (isset($o['last']))
08960                 $this->_out('/Last '.($n + $o['last']).' 0 R');
08961                 $this->_out(sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]', (1 + (2 * $o['p'])), ($this->pagedim[$o['p']]['h'] - ($o['y'] * $this->k))));
08962                 $this->_out('/Count 0>>');
08963                 $this->_out('endobj');
08964             }
08965             
08966             $this->_newobj();
08967             $this->OutlineRoot = $this->n;
08968             $this->_out('<</Type /Outlines /First '.$n.' 0 R');
08969             $this->_out('/Last '.($n + $lru[0]).' 0 R>>');
08970             $this->_out('endobj');
08971         }
08972         
08973         
08974         
08975         
08976         
08977 
08978 
08979 
08980 
08981 
08982         public function IncludeJS($script) {
08983             $this->javascript .= $script;
08984         }
08985         
08986         
08987 
08988 
08989 
08990 
08991 
08992         protected function _putjavascript() {
08993             if (empty($this->javascript)) {
08994                 return;
08995             }
08996             
08997             $js1 = sprintf("ftcpdfdocsaved=this.addField('%s','%s',%d,[%.2F,%.2F,%.2F,%.2F]);", 'tcpdfdocsaved', 'text', 0, 0, 1, 0, 1);
08998             $js2 = "getField('tcpdfdocsaved').value = 'saved';";
08999             $this->_newobj();
09000             $this->n_js = $this->n;
09001             $this->_out('<<');
09002             $this->_out('/Names [(EmbeddedJS) '.($this->n + 1).' 0 R ]');
09003             $this->_out('>>');
09004             $this->_out('endobj');
09005             $this->_newobj();
09006             $this->_out('<<');
09007             $this->_out('/S /JavaScript');
09008             $this->_out('/JS '.$this->_textstring($js1."\n".$this->javascript."\n".$js2));
09009             $this->_out('>>');
09010             $this->_out('endobj');
09011         }
09012         
09013         
09014 
09015 
09016 
09017 
09018 
09019 
09020         protected function _JScolor($color) {
09021             static $aColors = array('transparent', 'black', 'white', 'red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'dkGray', 'gray', 'ltGray');
09022             if (substr($color,0,1) == '#') {
09023                 return sprintf("['RGB',%.3F,%.3F,%.3F]", hexdec(substr($color,1,2))/255, hexdec(substr($color,3,2))/255, hexdec(substr($color,5,2))/255);
09024             }
09025             if (!in_array($color,$aColors)) {
09026                 $this->Error('Invalid color: '.$color);
09027             }
09028             return 'color.'.$color;
09029         }
09030         
09031         
09032 
09033 
09034 
09035 
09036 
09037 
09038 
09039 
09040 
09041 
09042 
09043 
09044         protected function _addfield($type, $name, $x, $y, $w, $h, $prop) {
09045             if ($this->rtl) {
09046                 $x = $x - $w;
09047             }
09048             
09049             $this->javascript .= "if(getField('tcpdfdocsaved').value != 'saved') {";
09050             $k = $this->k;
09051             $this->javascript .= sprintf("f".$name."=this.addField('%s','%s',%d,[%.2F,%.2F,%.2F,%.2F]);", $name, $type, $this->PageNo()-1, $x*$k, ($this->h-$y)*$k+1, ($x+$w)*$k, ($this->h-$y-$h)*$k+1)."\n";
09052             $this->javascript .= 'f'.$name.'.textSize='.$this->FontSizePt.";\n";
09053             while (list($key, $val) = each($prop)) {
09054                 if (strcmp(substr($key, -5), 'Color') == 0) {
09055                     $val = $this->_JScolor($val);
09056                 } else {
09057                     $val = "'".$val."'";
09058                 }
09059                 $this->javascript .= 'f'.$name.'.'.$key.'='.$val.";\n";
09060             }
09061             if ($this->rtl) {
09062                 $this->x -= $w;
09063             } else {
09064                 $this->x += $w;
09065             }
09066             $this->javascript .= '}';
09067         }
09068         
09069         
09070 
09071 
09072 
09073 
09074 
09075 
09076 
09077 
09078 
09079         public function TextField($name, $w, $h, $prop=array()) {
09080             $this->_addfield('text', $name, $this->x, $this->y, $w, $h, $prop);
09081         }
09082         
09083         
09084 
09085 
09086 
09087 
09088 
09089 
09090 
09091 
09092         public function RadioButton($name, $w, $prop=array()) {
09093             if (!isset($prop['strokeColor'])) {
09094                 $prop['strokeColor']='black';
09095             }
09096             $this->_addfield('radiobutton', $name, $this->x, $this->y, $w, $w, $prop);
09097         }
09098         
09099         
09100 
09101 
09102 
09103 
09104 
09105 
09106 
09107 
09108 
09109 
09110         public function ListBox($name, $w, $h, $values, $prop=array()) {
09111             if (!isset($prop['strokeColor'])) {
09112                 $prop['strokeColor'] = 'ltGray';
09113             }
09114             $this->_addfield('listbox', $name, $this->x, $this->y, $w, $h, $prop);
09115             $s = '';
09116             foreach ($values as $value) {
09117                 $s .= "'".addslashes($value)."',";
09118             }
09119             $this->javascript .= 'f'.$name.'.setItems(['.substr($s, 0, -1)."]);\n";
09120         }
09121         
09122         
09123 
09124 
09125 
09126 
09127 
09128 
09129 
09130 
09131 
09132 
09133         public function ComboBox($name, $w, $h, $values, $prop=array()) {
09134             $this->_addfield('combobox', $name, $this->x, $this->y, $w, $h, $prop);
09135             $s = '';
09136             foreach ($values as $value) {
09137                 $s .= "'".addslashes($value)."',";
09138             }
09139             $this->javascript .= 'f'.$name.'.setItems(['.substr($s, 0, -1)."]);\n";
09140         }
09141         
09142         
09143 
09144 
09145 
09146 
09147 
09148 
09149 
09150 
09151 
09152         public function CheckBox($name, $w, $checked=false, $prop=array()) {
09153             $prop['value'] = ($checked ? 'Yes' : 'Off');
09154             if (!isset($prop['strokeColor'])) {
09155                 $prop['strokeColor'] = 'black';
09156             }
09157             $this->_addfield('checkbox', $name, $this->x, $this->y, $w, $w, $prop);
09158         }
09159         
09160         
09161 
09162 
09163 
09164 
09165 
09166 
09167 
09168 
09169 
09170 
09171 
09172         public function Button($name, $w, $h, $caption, $action, $prop=array()) {
09173             if (!isset($prop['strokeColor'])) {
09174                 $prop['strokeColor'] = 'black';
09175             }
09176             if (!isset($prop['borderStyle'])) {
09177                 $prop['borderStyle'] = 'beveled';
09178             }
09179             $this->_addfield('button', $name, $this->x, $this->y, $w, $h, $prop);
09180             $this->javascript .= 'f'.$name.".buttonSetCaption('".addslashes($caption)."');\n";
09181             $this->javascript .= 'f'.$name.".setAction('MouseUp','".addslashes($action)."');\n";
09182             $this->javascript .= 'f'.$name.".highlight='push';\n";
09183             $this->javascript .= 'f'.$name.".print=false;\n";
09184         }
09185         
09186         
09187         
09188         
09189 
09190 
09191 
09192 
09193 
09194 
09195         protected function _putuserrights() {
09196             if ((!$this->sign) OR (isset($this->signature_data['cert_type']) AND ($this->signature_data['cert_type'] > 0))) {
09197                 return;
09198             }
09199             $this->_out('/Perms');
09200             $this->_out('<<');
09201             $this->_out('/UR3');
09202             $this->_out('<<');
09203             $this->_out('/Type/Sig');
09204             $this->_out('/Filter/Adobe.PPKLite');
09205             $this->_out('/SubFilter/adbe.pkcs7.detached');
09206             $this->_out('/ByteRange[0 ********** ********** **********]');
09207             $this->_out('/Contents<>'.str_repeat(' ', $this->signature_max_lenght));
09208             if ($this->ur) {
09209                 $this->_out('/Reference');
09210                 $this->_out('[');
09211                 $this->_out('<<');
09212                 $this->_out('/Type/SigRef');
09213                 $this->_out('/TransformMethod/UR3');
09214                 $this->_out('/TransformParams');
09215                 $this->_out('<<');
09216                 $this->_out('/Type/TransformParams');
09217                 $this->_out('/V/2.2');
09218                 if (!$this->empty_string($this->ur_document)) {
09219                     $this->_out('/Document['.$this->ur_document.']');
09220                 }
09221                 if (!$this->empty_string($this->ur_annots)) {
09222                     $this->_out('/Annots['.$this->ur_annots.']');
09223                 }
09224                 if (!$this->empty_string($this->ur_form)) {
09225                     $this->_out('/Form['.$this->ur_form.']');
09226                 }
09227                 if (!$this->empty_string($this->ur_signature)) {
09228                     $this->_out('/Signature['.$this->ur_signature.']');
09229                 }           
09230                 $this->_out('>>');
09231                 $this->_out('>>');
09232                 $this->_out(']');
09233             }
09234             $this->_out('/M '.$this->_datastring('D:'.date('YmdHisO')));
09235             $this->_out('>>');
09236             $this->_out('>>');
09237         }
09238         
09239         
09240 
09241 
09242 
09243 
09244 
09245         protected function _putcertification() {
09246             if ((!$this->sign) OR (isset($this->signature_data['cert_type']) AND ($this->signature_data['cert_type'] <= 0))) {
09247                 return;
09248             }
09249             $this->_out('/Perms');
09250             $this->_out('<<');
09251             $this->_out('/DocMDP');
09252             $this->_out('<<');
09253             $this->_out('/Type/Sig');
09254             $this->_out('/Filter/Adobe.PPKLite');
09255             $this->_out('/SubFilter/adbe.pkcs7.detached');
09256             $this->_out('/ByteRange[0 ********** ********** **********]');
09257             $this->_out('/Contents<>'.str_repeat(' ', $this->signature_max_lenght));
09258             $this->_out('/Reference');
09259             $this->_out('[');
09260             $this->_out('<<');
09261             $this->_out('/Type/SigRef');
09262             $this->_out('/TransformMethod/DocMDP');
09263             $this->_out('/TransformParams');
09264             $this->_out('<<');
09265             $this->_out('/Type/TransformParams');
09266             $this->_out('/V/1.2');
09267             $this->_out('/P '.$this->signature_data['cert_type'].'');
09268             $this->_out('>>');
09269             $this->_out('>>');
09270             $this->_out(']');
09271             $this->_out('/M '.$this->_datastring('D:'.date('YmdHisO')));
09272             if (isset($this->signature_data['info']['Name']) AND !$this->empty_string($this->signature_data['info']['Name'])) {
09273                 $this->_out('/Name '.$this->_textstring($this->signature_data['info']['Name']).'');
09274             }
09275             if (isset($this->signature_data['info']['Location']) AND !$this->empty_string($this->signature_data['info']['Location'])) {
09276                 $this->_out('/Location '.$this->_textstring($this->signature_data['info']['Location']).'');
09277             }
09278             if (isset($this->signature_data['info']['Reason']) AND !$this->empty_string($this->signature_data['info']['Reason'])) {
09279                 $this->_out('/Reason '.$this->_textstring($this->signature_data['info']['Reason']).'');
09280             }
09281             if (isset($this->signature_data['info']['ContactInfo']) AND !$this->empty_string($this->signature_data['info']['ContactInfo'])) {
09282                 $this->_out('/ContactInfo '.$this->_textstring($this->signature_data['info']['ContactInfo']).'');
09283             }
09284             $this->_out('>>');
09285             $this->_out('>>');
09286         }
09287         
09288         
09289 
09290 
09291 
09292 
09293 
09294 
09295 
09296 
09297 
09298 
09299 
09300 
09301 
09302         public function setUserRights(
09303                 $enable=true, 
09304                 $document='/FullSave',
09305                 $annots='/Create/Delete/Modify/Copy/Import/Export',
09306                 $form='/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate',
09307                 $signature='/Modify') {
09308             $this->ur = $enable;
09309             $this->ur_document = $document;
09310             $this->ur_annots = $annots;
09311             $this->ur_form = $form;
09312             $this->ur_signature = $signature;
09313             if ($this->ur) {
09314                 $this->setSignature('', '', '', '', 0);
09315             }
09316         }
09317         
09318         
09319 
09320 
09321 
09322 
09323 
09324 
09325 
09326 
09327 
09328 
09329 
09330 
09331         public function setSignature($signing_cert='', $private_key='', $private_key_password='', $extracerts='', $cert_type=2, $info=array()) {
09332             
09333             $this->sign = true;
09334             $this->signature_data = array();
09335             if (strlen($signing_cert) == 0) {
09336                 $signing_cert = 'file://'.dirname(__FILE__).'/tcpdf.pem';
09337             }
09338             if (strlen($private_key) == 0) {
09339                 $private_key = $signing_cert;
09340             }
09341             $this->signature_data['signcert'] = $signing_cert;
09342             $this->signature_data['privkey'] = $private_key;
09343             $this->signature_data['password'] = $private_key_password;
09344             $this->signature_data['extracerts'] = $extracerts;
09345             $this->signature_data['cert_type'] = $cert_type;
09346             $this->signature_data['info'] = array();
09347         }
09348         
09349         
09350 
09351 
09352 
09353 
09354 
09355 
09356         public function startPageGroup($page='') {
09357             if (empty($page)) {
09358                 $page = $this->page + 1;
09359             }
09360             $this->newpagegroup[$page] = true;
09361         }
09362 
09371         public function AliasNbPages($alias='{nb}') {
09372             $this->AliasNbPages = $alias;
09373         }
09374         
09383         public function getAliasNbPages() {
09384             if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
09385                 return '{'.$this->AliasNbPages.'}';
09386             }
09387             return $this->AliasNbPages;
09388         }
09389 
09398         public function AliasNumPage($alias='{pnb}') {
09399             
09400             $this->AliasNumPage = $alias;
09401         }
09402         
09411         public function getAliasNumPage() {
09412             if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
09413                 return '{'.$this->AliasNumPage.'}';
09414             }
09415             return $this->AliasNumPage;
09416         }
09417         
09418         
09419 
09420 
09421 
09422 
09423 
09424         public function getGroupPageNo() {
09425             return $this->pagegroups[$this->currpagegroup];
09426         }
09427 
09434         public function getGroupPageNoFormatted() {
09435             return $this->formatPageNumber($this->getGroupPageNo());
09436         }
09437         
09438         
09439 
09440 
09441 
09442 
09443 
09444 
09445 
09446         public function getPageGroupAlias() {
09447             if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
09448                 return '{'.$this->currpagegroup.'}';
09449             }
09450             return $this->currpagegroup;
09451         }
09452         
09453         
09454 
09455 
09456 
09457 
09458 
09459 
09460 
09461         public function getPageNumGroupAlias() {
09462             if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
09463                 return '{'.str_replace('{nb', '{pnb', $this->currpagegroup).'}';
09464             }
09465             return str_replace('{nb', '{pnb', $this->currpagegroup);
09466         }
09467 
09475         protected function formatPageNumber($num) {
09476             return number_format((float)$num, 0, '', '.');
09477         }
09478 
09487         protected function formatTOCPageNumber($num) {
09488             return number_format((float)$num, 0, '', '.');
09489         }
09490 
09497         public function PageNoFormatted() {
09498             return $this->formatPageNumber($this->PageNo());
09499         }
09500 
09501         
09502 
09503 
09504 
09505 
09506         protected function _putocg() {
09507             $this->_newobj();
09508             $this->n_ocg_print = $this->n;
09509             $this->_out('<</Type /OCG /Name '.$this->_textstring('print'));
09510             $this->_out('/Usage <</Print <</PrintState /ON>> /View <</ViewState /OFF>>>>>>');
09511             $this->_out('endobj');
09512             $this->_newobj();
09513             $this->n_ocg_view=$this->n;
09514             $this->_out('<</Type /OCG /Name '.$this->_textstring('view'));
09515             $this->_out('/Usage <</Print <</PrintState /OFF>> /View <</ViewState /ON>>>>>>');
09516             $this->_out('endobj');
09517         }
09518         
09519         
09520 
09521 
09522 
09523 
09524 
09525 
09526 
09527         public function setVisibility($v) {
09528             if ($this->openMarkedContent) {
09529                 
09530                 $this->_out('EMC');
09531                 $this->openMarkedContent = false;
09532             }
09533             switch($v) {
09534                 case 'print': {
09535                     $this->_out('/OC /OC1 BDC');
09536                     $this->openMarkedContent = true;
09537                     break;
09538                 }
09539                 case 'screen': {
09540                     $this->_out('/OC /OC2 BDC');
09541                     $this->openMarkedContent = true;
09542                     break;
09543                 }
09544                 case 'all': {
09545                     $this->_out('');
09546                     break;
09547                 }
09548                 default: {
09549                     $this->Error('Incorrect visibility: '.$v);
09550                     break;
09551                 }
09552             }
09553             $this->visibility = $v;
09554         }
09555         
09556         
09557 
09558 
09559 
09560 
09561 
09562 
09563         protected function addExtGState($parms) {
09564             $n = count($this->extgstates) + 1;
09565             $this->extgstates[$n]['parms'] = $parms;
09566             return $n;
09567         }
09568         
09569         
09570 
09571 
09572 
09573 
09574 
09575         protected function setExtGState($gs) {
09576             $this->_out(sprintf('/GS%d gs', $gs));
09577         }
09578         
09579         
09580 
09581 
09582 
09583 
09584 
09585         protected function _putextgstates() {
09586             $ne = count($this->extgstates);
09587             for ($i = 1; $i <= $ne; ++$i) {
09588                 $this->_newobj();
09589                 $this->extgstates[$i]['n'] = $this->n;
09590                 $this->_out('<</Type /ExtGState');
09591                 foreach ($this->extgstates[$i]['parms'] as $k => $v) {
09592                     $this->_out('/'.$k.' '.$v);
09593                 }
09594                 $this->_out('>>');
09595                 $this->_out('endobj');
09596             }
09597         }
09598         
09599         
09600 
09601 
09602 
09603 
09604 
09605 
09606         public function setAlpha($alpha, $bm='Normal') {
09607             $gs = $this->addExtGState(array('ca' => $alpha, 'CA' => $alpha, 'BM' => '/'.$bm));
09608             $this->setExtGState($gs);
09609         }
09610 
09611         
09612 
09613 
09614 
09615 
09616 
09617         public function setJPEGQuality($quality) {
09618             if (($quality < 1) OR ($quality > 100)) {
09619                 $quality = 75;
09620             }
09621             $this->jpeg_quality = intval($quality);
09622         }
09623         
09624         
09625 
09626 
09627 
09628 
09629 
09630         public function setDefaultTableColumns($cols=4) { 
09631             $this->default_table_columns = intval($cols); 
09632         }
09633         
09634         
09635 
09636 
09637 
09638 
09639 
09640         public function setCellHeightRatio($h) { 
09641             $this->cell_height_ratio = $h; 
09642         }
09643         
09644         
09645 
09646 
09647 
09648 
09649         public function getCellHeightRatio() { 
09650             return $this->cell_height_ratio; 
09651         }
09652         
09653         
09654 
09655 
09656 
09657 
09658 
09659         public function setPDFVersion($version='1.7') { 
09660             $this->PDFVersion = $version;
09661         }
09662         
09663         
09664 
09665 
09666 
09667 
09668 
09669 
09670 
09671 
09672 
09673 
09674 
09675 
09676 
09677 
09678 
09679 
09680 
09681 
09682 
09683 
09684 
09685 
09686 
09687 
09688 
09689         public function setViewerPreferences($preferences) { 
09690             $this->viewer_preferences = $preferences;
09691         }
09692         
09706         public function LinearGradient($x, $y, $w, $h, $col1=array(), $col2=array(), $coords=array(0,0,1,0)) {
09707             $this->Clip($x, $y, $w, $h);
09708             $this->Gradient(2, $col1, $col2, $coords);
09709         }
09710         
09724         public function RadialGradient($x, $y, $w, $h, $col1=array(), $col2=array(), $coords=array(0.5,0.5,0.5,0.5,1)) {
09725             $this->Clip($x, $y, $w, $h);
09726             $this->Gradient(3, $col1, $col2, $coords);
09727         }
09728         
09746         public function CoonsPatchMesh($x, $y, $w, $h, $col1=array(), $col2=array(), $col3=array(), $col4=array(), $coords=array(0.00,0.0,0.33,0.00,0.67,0.00,1.00,0.00,1.00,0.33,1.00,0.67,1.00,1.00,0.67,1.00,0.33,1.00,0.00,1.00,0.00,0.67,0.00,0.33), $coords_min=0, $coords_max=1) {
09747             $this->Clip($x, $y, $w, $h);        
09748             $n = count($this->gradients) + 1;
09749             $this->gradients[$n]['type'] = 6; 
09750             
09751             if (!isset($coords[0]['f'])) {
09752                 
09753                 if (!isset($col1[1])) {
09754                     $col1[1] = $col1[2] = $col1[0];
09755                 }
09756                 if (!isset($col2[1])) {
09757                     $col2[1] = $col2[2] = $col2[0];
09758                 }
09759                 if (!isset($col3[1])) {
09760                     $col3[1] = $col3[2] = $col3[0];
09761                 }
09762                 if (!isset($col4[1])) {
09763                     $col4[1] = $col4[2] = $col4[0];
09764                 }
09765                 $patch_array[0]['f'] = 0;
09766                 $patch_array[0]['points'] = $coords;
09767                 $patch_array[0]['colors'][0]['r'] = $col1[0];
09768                 $patch_array[0]['colors'][0]['g'] = $col1[1];
09769                 $patch_array[0]['colors'][0]['b'] = $col1[2];
09770                 $patch_array[0]['colors'][1]['r'] = $col2[0];
09771                 $patch_array[0]['colors'][1]['g'] = $col2[1];
09772                 $patch_array[0]['colors'][1]['b'] = $col2[2];
09773                 $patch_array[0]['colors'][2]['r'] = $col3[0];
09774                 $patch_array[0]['colors'][2]['g'] = $col3[1];
09775                 $patch_array[0]['colors'][2]['b'] = $col3[2];
09776                 $patch_array[0]['colors'][3]['r'] = $col4[0];
09777                 $patch_array[0]['colors'][3]['g'] = $col4[1];
09778                 $patch_array[0]['colors'][3]['b'] = $col4[2];
09779             } else {
09780                 
09781                 $patch_array = $coords;
09782             }
09783             $bpcd = 65535; 
09784             
09785             $this->gradients[$n]['stream'] = '';
09786             $count_patch = count($patch_array);
09787             for($i=0; $i < $count_patch; ++$i) {
09788                 $this->gradients[$n]['stream'] .= chr($patch_array[$i]['f']); 
09789                 $count_points = count($patch_array[$i]['points']);
09790                 for($j=0; $j < $count_points; ++$j) {
09791                     
09792                     $patch_array[$i]['points'][$j] = (($patch_array[$i]['points'][$j] - $coords_min) / ($coords_max - $coords_min)) * $bpcd;
09793                     if ($patch_array[$i]['points'][$j] < 0) {
09794                         $patch_array[$i]['points'][$j] = 0;
09795                     }
09796                     if ($patch_array[$i]['points'][$j] > $bpcd) {
09797                         $patch_array[$i]['points'][$j] = $bpcd;
09798                     }
09799                     $this->gradients[$n]['stream'] .= chr(floor($patch_array[$i]['points'][$j] / 256));
09800                     $this->gradients[$n]['stream'] .= chr(floor($patch_array[$i]['points'][$j] % 256));
09801                 }
09802                 $count_cols = count($patch_array[$i]['colors']);
09803                 for($j=0; $j < $count_cols; ++$j) {
09804                     
09805                     $this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['r']);
09806                     $this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['g']);
09807                     $this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['b']);
09808                 }
09809             }
09810             
09811             $this->_out('/Sh'.$n.' sh');
09812             
09813             $this->_out('Q');
09814         }
09815         
09826         protected function Clip($x, $y, $w, $h) {
09827             if ($this->rtl) {
09828                 $x = $this->w - $x - $w;
09829             }
09830             
09831             $s = 'q';
09832             
09833             $s .= sprintf(' %.2F %.2F %.2F %.2F re W n', $x*$this->k, ($this->h-$y)*$this->k, $w*$this->k, -$h*$this->k);
09834             
09835             $s .= sprintf(' %.3F 0 0 %.3F %.3F %.3F cm', $w*$this->k, $h*$this->k, $x*$this->k, ($this->h-($y+$h))*$this->k);
09836             $this->_out($s);
09837         }
09838                 
09849         protected function Gradient($type, $col1, $col2, $coords) {
09850             $n = count($this->gradients) + 1;
09851             $this->gradients[$n]['type'] = $type;
09852             if (!isset($col1[1])) {
09853                 $col1[1]=$col1[2]=$col1[0];
09854             }
09855             $this->gradients[$n]['col1'] = sprintf('%.3F %.3F %.3F', ($col1[0]/255), ($col1[1]/255), ($col1[2]/255));
09856             if (!isset($col2[1])) {
09857                 $col2[1] = $col2[2] = $col2[0];
09858             }
09859             $this->gradients[$n]['col2'] = sprintf('%.3F %.3F %.3F', ($col2[0]/255), ($col2[1]/255), ($col2[2]/255));
09860             $this->gradients[$n]['coords'] = $coords;
09861             
09862             $this->_out('/Sh'.$n.' sh');
09863             
09864             $this->_out('Q');
09865         }
09866         
09873         function _putshaders() {
09874             foreach ($this->gradients as $id => $grad) {  
09875                 if (($grad['type'] == 2) OR ($grad['type'] == 3)) {
09876                     $this->_newobj();
09877                     $this->_out('<<');
09878                     $this->_out('/FunctionType 2');
09879                     $this->_out('/Domain [0.0 1.0]');
09880                     $this->_out('/C0 ['.$grad['col1'].']');
09881                     $this->_out('/C1 ['.$grad['col2'].']');
09882                     $this->_out('/N 1');
09883                     $this->_out('>>');
09884                     $this->_out('endobj');
09885                     $f1 = $this->n;
09886                 }
09887                 $this->_newobj();
09888                 $this->_out('<<');
09889                 $this->_out('/ShadingType '.$grad['type']);
09890                 $this->_out('/ColorSpace /DeviceRGB');
09891                 if ($grad['type'] == 2) {
09892                     $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]));
09893                     $this->_out('/Function '.$f1.' 0 R');
09894                     $this->_out('/Extend [true true] ');
09895                     $this->_out('>>');
09896                 } elseif ($grad['type'] == 3) {
09897                     
09898                     
09899                     $this->_out(sprintf('/Coords [%.3F %.3F 0 %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3], $grad['coords'][4]));
09900                     $this->_out('/Function '.$f1.' 0 R');
09901                     $this->_out('/Extend [true true] ');
09902                     $this->_out('>>');
09903                 } elseif ($grad['type'] == 6) {
09904                     $this->_out('/BitsPerCoordinate 16');
09905                     $this->_out('/BitsPerComponent 8');
09906                     $this->_out('/Decode[0 1 0 1 0 1 0 1 0 1]');
09907                     $this->_out('/BitsPerFlag 8');
09908                     $this->_out('/Length '.strlen($grad['stream']));
09909                     $this->_out('>>');
09910                     $this->_putstream($grad['stream']);
09911                 }
09912                 $this->_out('endobj');
09913                 $this->gradients[$id]['id'] = $this->n;
09914             }
09915         }
09916 
09923         protected function _outarc($x1, $y1, $x2, $y2, $x3, $y3 ) {
09924             $h = $this->h;
09925             $this->_out(sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c', $x1*$this->k, ($h-$y1)*$this->k, $x2*$this->k, ($h-$y2)*$this->k, $x3*$this->k, ($h-$y3)*$this->k));
09926         }
09927         
09943         public function PieSector($xc, $yc, $r, $a, $b, $style='FD', $cw=true, $o=90) {
09944             if ($this->rtl) {
09945                 $xc = $this->w - $xc;
09946             }
09947             if ($cw) {
09948                 $d = $b;
09949                 $b = $o - $a;
09950                 $a = $o - $d;
09951             } else {
09952                 $b += $o;
09953                 $a += $o;
09954             }
09955             $a = ($a % 360) + 360;
09956             $b = ($b % 360) + 360;
09957             if ($a > $b) {
09958                 $b +=360;
09959             }
09960             $b = $b / 360 * 2 * M_PI;
09961             $a = $a / 360 * 2 * M_PI;
09962             $d = $b - $a;
09963             if ($d == 0 ) {
09964                 $d = 2 * M_PI;
09965             }
09966             $k = $this->k;
09967             $hp = $this->h;
09968             if ($style=='F') {
09969                 $op = 'f';
09970             } elseif ($style=='FD' or $style=='DF') {
09971                 $op = 'b';
09972             } else {
09973                 $op = 's';
09974             }
09975             if (sin($d/2)) {
09976                 $MyArc = 4/3 * (1 - cos($d/2)) / sin($d/2) * $r;
09977             }
09978             
09979             $this->_out(sprintf('%.2F %.2F m', ($xc)*$k, ($hp-$yc)*$k));
09980             
09981             $this->_out(sprintf('%.2F %.2F l', ($xc+$r*cos($a))*$k, (($hp-($yc-$r*sin($a)))*$k)));
09982             
09983             if ($d < (M_PI/2)) {
09984                 $this->_outarc($xc+$r*cos($a)+$MyArc*cos(M_PI/2+$a), $yc-$r*sin($a)-$MyArc*sin(M_PI/2+$a), $xc+$r*cos($b)+$MyArc*cos($b-M_PI/2), $yc-$r*sin($b)-$MyArc*sin($b-M_PI/2), $xc+$r*cos($b), $yc-$r*sin($b));
09985             } else {
09986                 $b = $a + $d/4;
09987                 $MyArc = 4/3*(1-cos($d/8))/sin($d/8)*$r;
09988                 $this->_outarc($xc+$r*cos($a)+$MyArc*cos(M_PI/2+$a), $yc-$r*sin($a)-$MyArc*sin(M_PI/2+$a), $xc+$r*cos($b)+$MyArc*cos($b-M_PI/2), $yc-$r*sin($b)-$MyArc*sin($b-M_PI/2), $xc+$r*cos($b), $yc-$r*sin($b));
09989                 $a = $b;
09990                 $b = $a + $d/4;
09991                 $this->_outarc($xc+$r*cos($a)+$MyArc*cos(M_PI/2+$a), $yc-$r*sin($a)-$MyArc*sin(M_PI/2+$a), $xc+$r*cos($b)+$MyArc*cos($b-M_PI/2), $yc-$r*sin($b)-$MyArc*sin($b-M_PI/2), $xc+$r*cos($b), $yc-$r*sin($b));
09992                 $a = $b;
09993                 $b = $a + $d/4;
09994                 $this->_outarc($xc+$r*cos($a)+$MyArc*cos(M_PI/2+$a), $yc-$r*sin($a)-$MyArc*sin(M_PI/2+$a), $xc+$r*cos($b)+$MyArc*cos($b-M_PI/2), $yc-$r*sin($b)-$MyArc*sin($b-M_PI/2), $xc+$r*cos($b), $yc-$r*sin($b) );
09995                 $a = $b;
09996                 $b = $a + $d/4;
09997                 $this->_outarc($xc+$r*cos($a)+$MyArc*cos(M_PI/2+$a), $yc-$r*sin($a)-$MyArc*sin(M_PI/2+$a), $xc+$r*cos($b)+$MyArc*cos($b-M_PI/2), $yc-$r*sin($b)-$MyArc*sin($b-M_PI/2), $xc+$r*cos($b), $yc-$r*sin($b));
09998             }
09999             
10000             $this->_out($op);
10001         }
10002         
10021         public function ImageEps($file, $x='', $y='', $w=0, $h=0, $link='', $useBoundingBox=true, $align='', $palign='', $border=0) {
10022             if ($x === '') {
10023                 $x = $this->x;
10024             }
10025             if ($y === '') {
10026                 $y = $this->y;
10027             }
10028             $k = $this->k;
10029             $data = file_get_contents($file);
10030             if ($data === false) {
10031                 $this->Error('EPS file not found: '.$file);
10032             }
10033             $regs = array();
10034             
10035             preg_match("/%%Creator:([^\r\n]+)/", $data, $regs); # find Creator
10036             if (count($regs) > 1) {
10037                 $version_str = trim($regs[1]); # e.g. "Adobe Illustrator(R) 8.0"
10038                 if (strpos($version_str, 'Adobe Illustrator') !== false) {
10039                     $versexp = explode(' ', $version_str);
10040                     $version = (float)array_pop($versexp);
10041                     if ($version >= 9) {
10042                         $this->Error('This version of Adobe Illustrator file is not supported: '.$file);
10043                     }
10044                 }
10045             }
10046             
10047             $start = strpos($data, '%!PS-Adobe');
10048             if ($start > 0) {
10049                 $data = substr($data, $start);
10050             }
10051             
10052             preg_match("/%%BoundingBox:([^\r\n]+)/", $data, $regs);
10053             if (count($regs) > 1) {
10054                 list($x1, $y1, $x2, $y2) = explode(' ', trim($regs[1]));
10055             } else {
10056                 $this->Error('No BoundingBox found in EPS file: '.$file);
10057             }
10058             $start = strpos($data, '%%EndSetup');
10059             if ($start === false) {
10060                 $start = strpos($data, '%%EndProlog');
10061             }
10062             if ($start === false) {
10063                 $start = strpos($data, '%%BoundingBox');
10064             }
10065             $data = substr($data, $start);
10066             $end = strpos($data, '%%PageTrailer');
10067             if ($end===false) {
10068                 $end = strpos($data, 'showpage');
10069             }
10070             if ($end) {
10071                 $data = substr($data, 0, $end);
10072             }
10073             if ($w > 0) {
10074                 $scale_x = $w / (($x2 - $x1) / $k);
10075                 if ($h > 0) {
10076                     $scale_y = $h / (($y2 - $y1) / $k);
10077                 } else {
10078                     $scale_y = $scale_x;
10079                     $h = ($y2 - $y1) / $k * $scale_y;
10080                 }
10081             } else {
10082                 if ($h > 0) {
10083                     $scale_y = $h / (($y2 - $y1) / $k);
10084                     $scale_x = $scale_y;
10085                     $w = ($x2-$x1) / $k * $scale_x;
10086                 } else {
10087                     $w = ($x2 - $x1) / $k;
10088                     $h = ($y2 - $y1) / $k;
10089                 }
10090             }
10091             
10092             if ((($y + $h) > $this->PageBreakTrigger) AND (!$this->InFooter) AND $this->AcceptPageBreak()) {
10093                 
10094                 $this->AddPage($this->CurOrientation);
10095                 
10096                 $y = $this->GetY() + $this->cMargin;
10097             }
10098             
10099             $this->img_rb_y = $y + $h;
10100             
10101             if ($this->rtl) {
10102                 if ($palign == 'L') {
10103                     $ximg = $this->lMargin;
10104                     
10105                     $this->img_rb_x = $ximg + $w;
10106                 } elseif ($palign == 'C') {
10107                     $ximg = ($this->w - $x - $w) / 2;
10108                     
10109                     $this->img_rb_x = $ximg + $w;
10110                 } else {
10111                     $ximg = $this->w - $x - $w;
10112                     
10113                     $this->img_rb_x = $ximg;
10114                 }
10115             } else {
10116                 if ($palign == 'R') {
10117                     $ximg = $this->w - $this->rMargin - $w;
10118                     
10119                     $this->img_rb_x = $ximg;
10120                 } elseif ($palign == 'C') {
10121                     $ximg = ($this->w - $x - $w) / 2;
10122                     
10123                     $this->img_rb_x = $ximg + $w;
10124                 } else {
10125                     $ximg = $x;
10126                     
10127                     $this->img_rb_x = $ximg + $w;
10128                 }
10129             }
10130             if ($useBoundingBox) {
10131                 $dx = $ximg * $k - $x1;
10132                 $dy = $y * $k - $y1;
10133             } else {
10134                 $dx = $ximg * $k;
10135                 $dy = $y * $k;
10136             }
10137             
10138             $this->_out('q'.$this->epsmarker);
10139             
10140             $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', 1, 0, 0, 1, $dx, $dy + ($this->hPt - (2 * $y * $k) - ($y2 - $y1))));
10141             
10142             if (isset($scale_x)) {
10143                 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', $scale_x, 0, 0, $scale_y, $x1 * (1 - $scale_x), $y2 * (1 - $scale_y)));
10144             }
10145             
10146             preg_match('/[\r\n]+/s', $data, $regs);
10147             $lines = explode($regs[0], $data);
10148             $u=0;
10149             $cnt = count($lines);
10150             for ($i=0; $i < $cnt; ++$i) {
10151                 $line = $lines[$i];
10152                 if (($line == '') OR ($line{0} == '%')) {
10153                     continue;
10154                 }
10155                 $len = strlen($line);
10156                 $chunks = explode(' ', $line);
10157                 $cmd = array_pop($chunks);
10158                 
10159                 if (($cmd == 'Xa') OR ($cmd == 'XA')) {
10160                     $b = array_pop($chunks); 
10161                     $g = array_pop($chunks); 
10162                     $r = array_pop($chunks);
10163                     $this->_out(''.$r.' '.$g.' '.$b.' '.($cmd=='Xa'?'rg':'RG')); 
10164                     continue;
10165                 }
10166                 switch ($cmd) {
10167                     case 'm':
10168                     case 'l':
10169                     case 'v':
10170                     case 'y':
10171                     case 'c':
10172                     case 'k':
10173                     case 'K':
10174                     case 'g':
10175                     case 'G':
10176                     case 's':
10177                     case 'S':
10178                     case 'J':
10179                     case 'j':
10180                     case 'w':
10181                     case 'M':
10182                     case 'd':
10183                     case 'n':
10184                     case 'v': {
10185                         $this->_out($line);
10186                         break;
10187                     }
10188                     case 'x': {
10189                         list($c,$m,$y,$k) = $chunks;
10190                         $this->_out(''.$c.' '.$m.' '.$y.' '.$k.' k');
10191                         break;
10192                     }
10193                     case 'X': { 
10194                         list($c,$m,$y,$k) = $chunks;
10195                         $this->_out(''.$c.' '.$m.' '.$y.' '.$k.' K');
10196                         break;
10197                     }
10198                     case 'Y':
10199                     case 'N':
10200                     case 'V':
10201                     case 'L':
10202                     case 'C': {
10203                         $line{$len-1} = strtolower($cmd);
10204                         $this->_out($line);
10205                         break;
10206                     }
10207                     case 'b':
10208                     case 'B': {
10209                         $this->_out($cmd . '*');
10210                         break;
10211                     }
10212                     case 'f':
10213                     case 'F': {
10214                         if ($u > 0) {
10215                             $isU = false;
10216                             $max = min($i+5, $cnt);
10217                             for ($j=$i+1; $j < $max; ++$j)
10218                               $isU = ($isU OR (($lines[$j] == 'U') OR ($lines[$j] == '*U')));
10219                             if ($isU) {
10220                                 $this->_out('f*');
10221                             }
10222                         } else {
10223                             $this->_out('f*');
10224                         }
10225                         break;
10226                     }
10227                     case '*u': {
10228                         ++$u;
10229                         break;
10230                     }
10231                     case '*U': {
10232                         --$u;
10233                         break;
10234                     }
10235                 }
10236             }
10237             
10238             $this->_out($this->epsmarker.'Q');
10239             if (!empty($border)) {
10240                 $bx = $x;
10241                 $by = $y;
10242                 $this->x = $x;
10243                 $this->y = $y;
10244                 $this->Cell($w, $h, '', $border, 0, '', 0, '', 0);
10245                 $this->x = $bx;
10246                 $this->y = $by;
10247             }
10248             if ($link) {
10249                 $this->Link($ximg, $y, $w, $h, $link, 0);
10250             }
10251             
10252             switch($align) {
10253                 case 'T':{
10254                     $this->y = $y;
10255                     $this->x = $this->img_rb_x;
10256                     break;
10257                 }
10258                 case 'M':{
10259                     $this->y = $y + round($h/2);
10260                     $this->x = $this->img_rb_x;
10261                     break;
10262                 }
10263                 case 'B':{
10264                     $this->y = $this->img_rb_y;
10265                     $this->x = $this->img_rb_x;
10266                     break;
10267                 }
10268                 case 'N':{
10269                     $this->SetY($this->img_rb_y);
10270                     break;
10271                 }
10272                 default:{
10273                     break;
10274                 }
10275             }
10276             $this->endlinex = $this->img_rb_x;
10277         }
10278         
10284         public function setBarcode($bc='') {
10285             $this->barcode = $bc;
10286         }
10287         
10294         public function getBarcode() {
10295             return $this->barcode;
10296         }
10297         
10313         public function write1DBarcode($code, $type, $x='', $y='', $w='', $h='', $xres=0.4, $style='', $align='') {
10314             if ($this->empty_string($code)) {
10315                 return;
10316             }
10317             require_once(dirname(__FILE__).'/barcodes.php');
10318             
10319             $gvars = $this->getGraphicVars();
10320             
10321             $barcodeobj = new TCPDFBarcode($code, $type);
10322             $arrcode = $barcodeobj->getBarcodeArray();
10323             if ($arrcode === false) {
10324                 $this->Error('Error in 1D barcode string');
10325             }
10326             
10327             if (!isset($style['position'])) {
10328                 if ($this->rtl) {
10329                     $style['position'] = 'R';
10330                 } else {
10331                     $style['position'] = 'L';
10332                 }
10333             }
10334             if (!isset($style['padding'])) {
10335                 $style['padding'] = 0;
10336             }
10337             if (!isset($style['fgcolor'])) {
10338                 $style['fgcolor'] = array(0,0,0); 
10339             }
10340             if (!isset($style['bgcolor'])) {
10341                 $style['bgcolor'] = false; 
10342             }
10343             if (!isset($style['border'])) {
10344                 $style['border'] = false;
10345             }
10346             if (!isset($style['text'])) {
10347                 $style['text'] = false;
10348                 $fontsize = 0;
10349             }
10350             if ($style['text'] AND isset($style['font'])) {
10351                 if (isset($style['fontsize'])) {
10352                     $fontsize = $style['fontsize'];
10353                 } else {
10354                     $fontsize = 0;
10355                 }
10356                 $this->SetFont($style['font'], '', $fontsize);
10357             }
10358             if (!isset($style['stretchtext'])) {
10359                 $style['stretchtext'] = 4;
10360             }
10361             
10362             $this->SetDrawColorArray($style['fgcolor']);
10363             $this->SetTextColorArray($style['fgcolor']);
10364             if ($this->empty_string($w) OR ($w <= 0)) {
10365                 if ($this->rtl) {
10366                     $w = $this->x - $this->lMargin;
10367                 } else {
10368                     $w = $this->w - $this->rMargin - $this->x;
10369                 }
10370             }
10371             if ($this->empty_string($x)) {
10372                 $x = $this->GetX();
10373             }
10374             if ($this->rtl) {
10375                 $x = $this->w - $x;
10376             }
10377             if ($this->empty_string($y)) {
10378                 $y = $this->GetY();
10379             }
10380             if ($this->empty_string($xres)) {
10381                 $xres = 0.4;
10382             }
10383             $fbw = ($arrcode['maxw'] * $xres) + (2 * $style['padding']);
10384             $extraspace = ($this->cell_height_ratio * $fontsize / $this->k) + (2 * $style['padding']);
10385             if ($this->empty_string($h) OR ($h <= 0)) {
10386                 $h = 10 + $extraspace;
10387             }
10388             if ($this->checkPageBreak($h)) {
10389                 $y = $this->y;
10390             }
10391             
10392             $barh = $h - $extraspace;
10393             switch ($style['position']) {
10394                 case 'L': { 
10395                     if ($this->rtl) {
10396                         $xpos = $x - $w;
10397                     } else {
10398                         $xpos = $x;
10399                     }
10400                     break;
10401                 }
10402                 case 'C': { 
10403                     $xdiff = (($w - $fbw) / 2);
10404                     if ($this->rtl) {
10405                         $xpos = $x - $w + $xdiff;
10406                     } else {
10407                         $xpos = $x + $xdiff;
10408                     }
10409                     break;
10410                 }
10411                 case 'R': { 
10412                     if ($this->rtl) {
10413                         $xpos = $x - $fbw;
10414                     } else {
10415                         $xpos = $x + $w - $fbw;
10416                     }
10417                     break;
10418                 }
10419                 case 'S': { 
10420                     $fbw = $w;
10421                     $xres = ($w - (2 * $style['padding'])) / $arrcode['maxw'];
10422                     if ($this->rtl) {
10423                         $xpos = $x - $w;
10424                     } else {
10425                         $xpos = $x;
10426                     }
10427                     break;
10428                 }
10429             }
10430             $xpos_rect = $xpos;
10431             $xpos = $xpos_rect + $style['padding'];
10432             $xpos_text = $xpos;
10433             
10434             $tempRTL = $this->rtl;
10435             $this->rtl = false;
10436             
10437             if ($style['bgcolor']) {
10438                 $this->Rect($xpos_rect, $y, $fbw, $h, 'DF', '', $style['bgcolor']);
10439             } elseif ($style['border']) {
10440                 $this->Rect($xpos_rect, $y, $fbw, $h, 'D');
10441             }
10442             
10443             if ($arrcode !== false) {
10444                 foreach ($arrcode['bcode'] as $k => $v) {
10445                     $bw = ($v['w'] * $xres);
10446                     if ($v['t']) {
10447                         
10448                         $ypos = $y + $style['padding'] + ($v['p'] * $barh / $arrcode['maxh']);
10449                         $this->Rect($xpos, $ypos, $bw, ($v['h'] * $barh  / $arrcode['maxh']), 'F', array(), $style['fgcolor']);
10450                     }
10451                     $xpos += $bw;
10452                 }
10453             }
10454             
10455             if ($style['text']) {
10456                 
10457                 $this->x = $xpos_text;
10458                 $this->y = $y + $style['padding'] + $barh; 
10459                 $this->Cell(($arrcode['maxw'] * $xres), ($this->cell_height_ratio * $fontsize / $this->k), $code, 0, 0, 'C', 0, '', $style['stretchtext']);
10460             }
10461             
10462             $this->rtl = $tempRTL;
10463             
10464             $this->setGraphicVars($gvars);
10465             
10466             $this->img_rb_y = $y + $h;
10467             if ($this->rtl) {
10468                 
10469                 $this->img_rb_x = ($this->w - $x - $w);
10470             } else {
10471                 
10472                 $this->img_rb_x = $x + $w;
10473             }
10474             
10475             switch($align) {
10476                 case 'T':{
10477                     $this->y = $y;
10478                     $this->x = $this->img_rb_x;
10479                     break;
10480                 }
10481                 case 'M':{
10482                     $this->y = $y + round($h/2);
10483                     $this->x = $this->img_rb_x;
10484                     break;
10485                 }
10486                 case 'B':{
10487                     $this->y = $this->img_rb_y;
10488                     $this->x = $this->img_rb_x;
10489                     break;
10490                 }
10491                 case 'N':{
10492                     $this->SetY($this->img_rb_y);
10493                     break;
10494                 }
10495                 default:{
10496                     break;
10497                 }
10498             }
10499         }
10500         
10516         public function writeBarcode($x, $y, $w, $h, $type, $style, $font, $xres, $code) {
10517             
10518             $xres = 1 / $xres;
10519             $newstyle = array(
10520                 'position' => 'L',
10521                 'border' => false,
10522                 'padding' => 0,
10523                 'fgcolor' => array(0,0,0),
10524                 'bgcolor' => false,
10525                 'text' => true,
10526                 'font' => $font,
10527                 'fontsize' => 8,
10528                 'stretchtext' => 4
10529             );
10530             if ($style & 1) {
10531                 $newstyle['border'] = true;
10532             }
10533             if ($style & 2) {
10534                 $newstyle['bgcolor'] = false;
10535             }
10536             if ($style & 4) {
10537                 $newstyle['position'] = 'C';
10538             } elseif ($style & 8) {
10539                 $newstyle['position'] = 'L';
10540             } elseif ($style & 16) {
10541                 $newstyle['position'] = 'R';
10542             }
10543             if ($style & 128) {
10544                 $newstyle['text'] = true;
10545             }
10546             if ($style & 256) {
10547                 $newstyle['stretchtext'] = 4;
10548             }
10549             $this->write1DBarcode($code, $type, $x, $y, $w, $h, $xres, $newstyle, '');
10550         }
10551         
10566         public function write2DBarcode($code, $type, $x='', $y='', $w='', $h='', $style='', $align='') {
10567             if ($this->empty_string($code)) {
10568                 return;
10569             }
10570             require_once(dirname(__FILE__).'/2dbarcodes.php');
10571             
10572             $gvars = $this->getGraphicVars();
10573             
10574             $barcodeobj = new TCPDF2DBarcode($code, $type);
10575             $arrcode = $barcodeobj->getBarcodeArray();
10576             if ($arrcode === false) {
10577                 $this->Error('Error in 2D barcode string');
10578             }
10579             
10580             if (!isset($style['padding'])) {
10581                 $style['padding'] = 0;
10582             }
10583             if (!isset($style['fgcolor'])) {
10584                 $style['fgcolor'] = array(0,0,0); 
10585             }
10586             if (!isset($style['bgcolor'])) {
10587                 $style['bgcolor'] = false; 
10588             }
10589             if (!isset($style['border'])) {
10590                 $style['border'] = false;
10591             }
10592             
10593             $this->SetDrawColorArray($style['fgcolor']);
10594             if ($this->empty_string($x)) {
10595                 $x = $this->GetX();
10596             }
10597             if ($this->rtl) {
10598                 $x = $this->w - $x;
10599             }
10600             if ($this->empty_string($y)) {
10601                 $y = $this->GetY();
10602             }
10603             if ($this->empty_string($w) OR ($w <= 0)) {
10604                 if ($this->rtl) {
10605                     $w = $x - $this->lMargin;
10606                 } else {
10607                     $w = $this->w - $this->rMargin - $x;
10608                 }
10609             }
10610             if ($this->empty_string($h) OR ($h <= 0)) {
10611                 
10612                 $h = $w;
10613             }
10614             if ($this->checkPageBreak($h)) {
10615                 $y = $this->y;
10616             }
10617             
10618             $bw = $w - (2 * $style['padding']);
10619             $bh = $h - (2 * $style['padding']);
10620             
10621             if ($this->rtl) {
10622                 $xpos = $x - $w;
10623             } else {
10624                 $xpos = $x;
10625             }
10626             $xpos += $style['padding'];
10627             $ypos = $y + $style['padding'];
10628             
10629             $tempRTL = $this->rtl;
10630             $this->rtl = false;
10631             
10632             if ($style['bgcolor']) {
10633                 $this->Rect($x, $y, $w, $h, 'DF', '', $style['bgcolor']);
10634             } elseif ($style['border']) {
10635                 $this->Rect($x, $y, $w, $h, 'D');
10636             }
10637             
10638             if ($arrcode !== false) {
10639                 $rows = $arrcode['num_rows'];
10640                 $cols = $arrcode['num_cols'];
10641                 
10642                 $cw = $bw / $cols;
10643                 $ch = $bh / $rows;
10644                 
10645                 for ($r = 0; $r < $rows; ++$r) {
10646                     $xr = $xpos;
10647                     
10648                     for ($c = 0; $c < $cols; ++$c) {
10649                         if ($arrcode['bcode'][$r][$c] == 1) {
10650                             
10651                             $this->Rect($xr, $ypos, $cw, $ch, 'F', array(), $style['fgcolor']);
10652                         }
10653                         $xr += $cw;
10654                     }
10655                     $ypos += $ch;
10656                 }
10657             }
10658             
10659             $this->rtl = $tempRTL;
10660             
10661             $this->setGraphicVars($gvars);
10662             
10663             $this->img_rb_y = $y + $h;
10664             if ($this->rtl) {
10665                 
10666                 $this->img_rb_x = ($this->w - $x - $w);
10667             } else {
10668                 
10669                 $this->img_rb_x = $x + $w;
10670             }
10671             
10672             switch($align) {
10673                 case 'T':{
10674                     $this->y = $y;
10675                     $this->x = $this->img_rb_x;
10676                     break;
10677                 }
10678                 case 'M':{
10679                     $this->y = $y + round($h/2);
10680                     $this->x = $this->img_rb_x;
10681                     break;
10682                 }
10683                 case 'B':{
10684                     $this->y = $this->img_rb_y;
10685                     $this->x = $this->img_rb_x;
10686                     break;
10687                 }
10688                 case 'N':{
10689                     $this->SetY($this->img_rb_y);
10690                     break;
10691                 }
10692                 default:{
10693                     break;
10694                 }
10695             }
10696         }
10697         
10713         public function getMargins() {
10714             $ret = array(
10715                 'left' => $this->lMargin,
10716                 'right' => $this->rMargin,
10717                 'top' => $this->tMargin,
10718                 'bottom' => $this->bMargin,
10719                 'header' => $this->header_margin,
10720                 'footer' => $this->footer_margin,
10721                 'cell' => $this->cMargin,
10722             );
10723             return $ret;
10724         }
10725         
10736         public function getOriginalMargins() {
10737             $ret = array(
10738                 'left' => $this->original_lMargin,
10739                 'right' => $this->original_rMargin
10740             );
10741             return $ret;
10742         }
10743         
10750         public function getFontSize() {
10751             return $this->FontSize;
10752         }
10753         
10760         public function getFontSizePt() {
10761             return $this->FontSizePt;
10762         }
10763 
10770         public function getFontFamily() {
10771             return $this->FontFamily;
10772         }
10773 
10780         public function getFontStyle() {
10781             return $this->FontStyle;
10782         }
10783         
10804         public function writeHTMLCell($w, $h, $x, $y, $html='', $border=0, $ln=0, $fill=0, $reseth=true, $align='', $autopadding=true) {
10805             return $this->MultiCell($w, $h, $html, $border, $align, $fill, $ln, $x, $y, $reseth, 0, true, $autopadding, 0);
10806         }
10807         
10816         protected function getHtmlDomArray($html) {
10817             
10818             $html = strip_tags($html, '<marker/><a><b><blockquote><br><br/><dd><del><div><dl><dt><em><font><h1><h2><h3><h4><h5><h6><hr><i><img><li><ol><p><pre><small><span><strong><sub><sup><table><tcpdf><td><th><thead><tr><tt><u><ul>');
10819             
10820             $html = preg_replace('/<pre/', '<xre', $html); 
10821             $html = preg_replace('/<(table|tr|td|th|blockquote|dd|div|dt|h1|h2|h3|h4|h5|h6|br|hr|li|ol|ul|p)([^>]*)>[\n\r\t]+/', '<\\1\\2>', $html);
10822             $html = preg_replace('@(\r\n|\r)@', "\n", $html);
10823             $repTable = array("\t" => ' ', "\0" => ' ', "\x0B" => ' ', "\\" => "\\\\");
10824             $html = strtr($html, $repTable);
10825             while (preg_match("'<xre([^>]*)>(.*?)\n(.*?)</pre>'si", $html)) {
10826                 
10827                 $html = preg_replace("'<xre([^>]*)>(.*?)\n(.*?)</pre>'si", "<xre\\1>\\2<br />\\3</pre>", $html);
10828             }
10829             $html = str_replace("\n", ' ', $html);
10830             
10831             $html = preg_replace('/[\s]+<\/(table|tr|td|th|ul|ol|li)>/', '</\\1>', $html);
10832             $html = preg_replace('/[\s]+<(tr|td|th|ul|ol|li|br)/', '<\\1', $html);
10833             $html = preg_replace('/<\/(table|tr|td|th|blockquote|dd|div|dt|h1|h2|h3|h4|h5|h6|hr|li|ol|ul|p)>[\s]+</', '</\\1><', $html);
10834             $html = preg_replace('/<\/(td|th)>/', '<marker style="font-size:0"/></\\1>', $html);
10835             $html = preg_replace('/<\/table>([\s]*)<marker style="font-size:0"\/>/', '</table>', $html);
10836             $html = preg_replace('/<img/', ' <img', $html);
10837             $html = preg_replace('/<img([^>]*)>/xi', '<img\\1><span></span>', $html);
10838             $html = preg_replace('/<xre/', '<pre', $html); 
10839             
10840             $html = preg_replace('/^[\s]+/', '', $html);
10841             $html = preg_replace('/[\s]+$/', '', $html);
10842             
10843             $tagpattern = '/(<[^>]+>)/';
10844             
10845             $a = preg_split($tagpattern, $html, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
10846             
10847             $maxel = count($a);
10848             $elkey = 0;
10849             $key = 0;
10850             
10851             $dom = array();
10852             $dom[$key] = array();
10853             
10854             $dom[$key]['tag'] = false;
10855             $dom[$key]['value'] = '';
10856             $dom[$key]['parent'] = 0;
10857             $dom[$key]['fontname'] = $this->FontFamily;
10858             $dom[$key]['fontstyle'] = $this->FontStyle;
10859             $dom[$key]['fontsize'] = $this->FontSizePt;
10860             $dom[$key]['bgcolor'] = false;
10861             $dom[$key]['fgcolor'] = $this->fgcolor;
10862             $dom[$key]['align'] = '';
10863             $dom[$key]['listtype'] = '';
10864             $thead = false; 
10865             ++$key;
10866             $level = array();
10867             array_push($level, 0); 
10868             while ($elkey < $maxel) {
10869                 $dom[$key] = array();
10870                 $element = $a[$elkey];
10871                 $dom[$key]['elkey'] = $elkey;
10872                 if (preg_match($tagpattern, $element)) {
10873                     
10874                     $element = substr($element, 1, -1);
10875                     
10876                     preg_match('/[\/]?([a-zA-Z0-9]*)/', $element, $tag);
10877                     $tagname = strtolower($tag[1]);
10878                     
10879                     if ($tagname == 'thead') {
10880                         if ($element{0} == '/') {
10881                             $thead = false;
10882                         } else {
10883                             $thead = true;
10884                         }
10885                         ++$elkey;
10886                         continue;
10887                     }
10888                     $dom[$key]['tag'] = true;
10889                     $dom[$key]['value'] = $tagname;
10890                     if ($element{0} == '/') {
10891                         
10892                         $dom[$key]['opening'] = false;
10893                         $dom[$key]['parent'] = end($level);
10894                         array_pop($level);
10895                         $dom[$key]['fontname'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontname'];
10896                         $dom[$key]['fontstyle'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontstyle'];
10897                         $dom[$key]['fontsize'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontsize'];
10898                         $dom[$key]['bgcolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['bgcolor'];
10899                         $dom[$key]['fgcolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fgcolor'];
10900                         $dom[$key]['align'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['align'];
10901                         if (isset($dom[($dom[($dom[$key]['parent'])]['parent'])]['listtype'])) {
10902                             $dom[$key]['listtype'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['listtype'];
10903                         }
10904                         
10905                         if (($dom[$key]['value'] == 'tr') AND (!isset($dom[($dom[($dom[$key]['parent'])]['parent'])]['cols']))) {
10906                             $dom[($dom[($dom[$key]['parent'])]['parent'])]['cols'] = $dom[($dom[$key]['parent'])]['cols'];
10907                         }
10908                         if (($dom[$key]['value'] == 'td') OR ($dom[$key]['value'] == 'th')) {
10909                             $dom[($dom[$key]['parent'])]['content'] = '';
10910                             for ($i = ($dom[$key]['parent'] + 1); $i < $key; ++$i) {
10911                                 $dom[($dom[$key]['parent'])]['content'] .= $a[$dom[$i]['elkey']];
10912                             }
10913                             $key = $i;
10914                         }
10915                         
10916                         if (($dom[$key]['value'] == 'tr') AND ($dom[($dom[$key]['parent'])]['thead'] == true)) {
10917                             if ($this->empty_string($dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'])) {
10918                                 $dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'] = $a[$dom[($dom[($dom[$key]['parent'])]['parent'])]['elkey']];
10919                             }
10920                             for ($i = $dom[$key]['parent']; $i <= $key; ++$i) {
10921                                 $dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'] .= $a[$dom[$i]['elkey']];
10922                             }
10923                         }
10924                         if (($dom[$key]['value'] == 'table') AND (!$this->empty_string($dom[($dom[$key]['parent'])]['thead']))) {
10925                             $dom[($dom[$key]['parent'])]['thead'] .= '</table>';
10926                         }
10927                     } else {
10928                         
10929                         $dom[$key]['opening'] = true;
10930                         $dom[$key]['parent'] = end($level);
10931                         if (substr($element, -1, 1) != '/') {
10932                             
10933                             array_push($level, $key);
10934                             $dom[$key]['self'] = false;
10935                         } else {
10936                             $dom[$key]['self'] = true;
10937                         }
10938                         
10939                         $parentkey = 0;
10940                         if ($key > 0) {
10941                             $parentkey = $dom[$key]['parent'];
10942                             $dom[$key]['fontname'] = $dom[$parentkey]['fontname'];
10943                             $dom[$key]['fontstyle'] = $dom[$parentkey]['fontstyle'];
10944                             $dom[$key]['fontsize'] = $dom[$parentkey]['fontsize'];
10945                             $dom[$key]['bgcolor'] = $dom[$parentkey]['bgcolor'];
10946                             $dom[$key]['fgcolor'] = $dom[$parentkey]['fgcolor'];
10947                             $dom[$key]['align'] = $dom[$parentkey]['align'];
10948                             $dom[$key]['listtype'] = $dom[$parentkey]['listtype'];
10949                         }
10950                         
10951                         preg_match_all('/([^=\s]*)=["]?([^"]*)["]?/', $element, $attr_array, PREG_PATTERN_ORDER);
10952                         $dom[$key]['attribute'] = array(); 
10953                         while (list($id, $name) = each($attr_array[1])) {
10954                             $dom[$key]['attribute'][strtolower($name)] = $attr_array[2][$id];
10955                         }
10956                         
10957                         if (isset($dom[$key]['attribute']['style'])) {
10958                             
10959                             preg_match_all('/([^;:\s]*):([^;]*)/', $dom[$key]['attribute']['style'], $style_array, PREG_PATTERN_ORDER);
10960                             $dom[$key]['style'] = array(); 
10961                             while (list($id, $name) = each($style_array[1])) {
10962                                 $dom[$key]['style'][strtolower($name)] = trim($style_array[2][$id]);
10963                             }
10964                             
10965                             if (isset($dom[$key]['style']['font-family'])) {
10966                                 
10967                                 if (isset($dom[$key]['style']['font-family'])) {
10968                                     $fontslist = split(',', strtolower($dom[$key]['style']['font-family']));
10969                                     foreach ($fontslist as $font) {
10970                                         $font = trim(strtolower($font));
10971                                         if (in_array($font, $this->fontlist) OR in_array($font, $this->fontkeys)) {
10972                                             $dom[$key]['fontname'] = $font;
10973                                             break;
10974                                         }
10975                                     }
10976                                 }
10977                             }
10978                             
10979                             if (isset($dom[$key]['style']['list-style-type'])) {
10980                                 $dom[$key]['listtype'] = trim(strtolower($dom[$key]['style']['list-style-type']));
10981                                 if ($dom[$key]['listtype'] == 'inherit') {
10982                                     $dom[$key]['listtype'] = $dom[$parentkey]['listtype'];
10983                                 }
10984                             }
10985                             
10986                             if (isset($dom[$key]['style']['font-size'])) {
10987                                 $fsize = trim($dom[$key]['style']['font-size']);
10988                                 switch ($fsize) {
10989                                     
10990                                     case 'xx-small': {
10991                                         $dom[$key]['fontsize'] = $dom[0]['fontsize'] - 4;
10992                                         break;
10993                                     }
10994                                     case 'x-small': {
10995                                         $dom[$key]['fontsize'] = $dom[0]['fontsize'] - 3;
10996                                         break;
10997                                     }
10998                                     case 'small': {
10999                                         $dom[$key]['fontsize'] = $dom[0]['fontsize'] - 2;
11000                                         break;
11001                                     }
11002                                     case 'medium': {
11003                                         $dom[$key]['fontsize'] = $dom[0]['fontsize'];
11004                                         break;
11005                                     }
11006                                     case 'large': {
11007                                         $dom[$key]['fontsize'] = $dom[0]['fontsize'] + 2;
11008                                         break;
11009                                     }
11010                                     case 'x-large': {
11011                                         $dom[$key]['fontsize'] = $dom[0]['fontsize'] + 4;
11012                                         break;
11013                                     }
11014                                     case 'xx-large': {
11015                                         $dom[$key]['fontsize'] = $dom[0]['fontsize'] + 6;
11016                                         break;
11017                                     }
11018                                     
11019                                     case 'smaller': {
11020                                         $dom[$key]['fontsize'] = $dom[$parentkey]['fontsize'] - 3;
11021                                         break;
11022                                     }
11023                                     case 'larger': {
11024                                         $dom[$key]['fontsize'] = $dom[$parentkey]['fontsize'] + 3;
11025                                         break;
11026                                     }
11027                                     default: {
11028                                         $dom[$key]['fontsize'] = $this->getHTMLUnitToUnits($fsize, $dom[$parentkey]['fontsize'], 'pt', true);
11029                                     }
11030                                 }
11031                             }
11032                             
11033                             if (isset($dom[$key]['style']['font-weight']) AND (strtolower($dom[$key]['style']['font-weight']{0}) == 'b')) {
11034                                 $dom[$key]['fontstyle'] .= 'B';
11035                             }
11036                             if (isset($dom[$key]['style']['font-style']) AND (strtolower($dom[$key]['style']['font-style']{0}) == 'i')) {
11037                                 $dom[$key]['fontstyle'] .= '"I';
11038                             }
11039                             
11040                             if (isset($dom[$key]['style']['color']) AND (!$this->empty_string($dom[$key]['style']['color']))) {
11041                                 $dom[$key]['fgcolor'] = $this->convertHTMLColorToDec($dom[$key]['style']['color']);
11042                             }
11043                             
11044                             if (isset($dom[$key]['style']['background-color']) AND (!$this->empty_string($dom[$key]['style']['background-color']))) {
11045                                 $dom[$key]['bgcolor'] = $this->convertHTMLColorToDec($dom[$key]['style']['background-color']);
11046                             }
11047                             
11048                             if (isset($dom[$key]['style']['text-decoration'])) {
11049                                 $decors = explode(' ', strtolower($dom[$key]['style']['text-decoration']));
11050                                 foreach ($decors as $dec) {
11051                                     $dec = trim($dec);
11052                                     if (!$this->empty_string($dec)) {
11053                                         if ($dec{0} == 'u') {
11054                                             $dom[$key]['fontstyle'] .= 'U';
11055                                         } elseif ($dec{0} == 'l') {
11056                                             $dom[$key]['fontstyle'] .= 'D';
11057                                         }
11058                                     }
11059                                 }
11060                             }
11061                             
11062                             if (isset($dom[$key]['style']['width'])) {
11063                                 $dom[$key]['width'] = $dom[$key]['style']['width'];
11064                             }
11065                             
11066                             if (isset($dom[$key]['style']['height'])) {
11067                                 $dom[$key]['height'] = $dom[$key]['style']['height'];
11068                             }
11069                             
11070                             if (isset($dom[$key]['style']['text-align'])) {
11071                                 $dom[$key]['align'] = strtoupper($dom[$key]['style']['text-align']{0});
11072                             }
11073                             
11074                             if (isset($dom[$key]['style']['border'])) {
11075                                 $dom[$key]['attribute']['border'] = $dom[$key]['style']['border'];
11076                             }
11077                         }
11078                         
11079                         if ($dom[$key]['value'] == 'font') {
11080                             
11081                             if (isset($dom[$key]['attribute']['face'])) {
11082                                 $fontslist = split(',', strtolower($dom[$key]['attribute']['face']));
11083                                 foreach ($fontslist as $font) {
11084                                     $font = trim(strtolower($font));
11085                                     if (in_array($font, $this->fontlist) OR in_array($font, $this->fontkeys)) {
11086                                         $dom[$key]['fontname'] = $font;
11087                                         break;
11088                                     }
11089                                 }
11090                             }
11091                             
11092                             if (isset($dom[$key]['attribute']['size'])) {
11093                                 if ($key > 0) {
11094                                     if ($dom[$key]['attribute']['size']{0} == '+') {
11095                                         $dom[$key]['fontsize'] = $dom[($dom[$key]['parent'])]['fontsize'] + intval(substr($dom[$key]['attribute']['size'], 1));
11096                                     } elseif ($dom[$key]['attribute']['size']{0} == '-') {
11097                                         $dom[$key]['fontsize'] = $dom[($dom[$key]['parent'])]['fontsize'] - intval(substr($dom[$key]['attribute']['size'], 1));
11098                                     } else {
11099                                         $dom[$key]['fontsize'] = intval($dom[$key]['attribute']['size']);
11100                                     }
11101                                 } else {
11102                                     $dom[$key]['fontsize'] = intval($dom[$key]['attribute']['size']);
11103                                 }
11104                             }
11105                         }
11106                         
11107                         if ((($dom[$key]['value'] == 'ul') OR ($dom[$key]['value'] == 'ol') OR ($dom[$key]['value'] == 'dl'))
11108                             AND (!isset($dom[$key]['align']) OR $this->empty_string($dom[$key]['align']) OR ($dom[$key]['align'] != 'J'))) {
11109                             if ($this->rtl) {
11110                                 $dom[$key]['align'] = 'R';
11111                             } else {
11112                                 $dom[$key]['align'] = 'L';
11113                             }
11114                         }
11115                         if (($dom[$key]['value'] == 'small') OR ($dom[$key]['value'] == 'sup') OR ($dom[$key]['value'] == 'sub')) {
11116                             $dom[$key]['fontsize'] = $dom[$key]['fontsize'] * K_SMALL_RATIO;
11117                         }
11118                         if (($dom[$key]['value'] == 'strong') OR ($dom[$key]['value'] == 'b')) {
11119                             $dom[$key]['fontstyle'] .= 'B';
11120                         }
11121                         if (($dom[$key]['value'] == 'em') OR ($dom[$key]['value'] == 'i')) {
11122                             $dom[$key]['fontstyle'] .= 'I';
11123                         }
11124                         if ($dom[$key]['value'] == 'u') {
11125                             $dom[$key]['fontstyle'] .= 'U';
11126                         }
11127                         if ($dom[$key]['value'] == 'del') {
11128                             $dom[$key]['fontstyle'] .= 'D';
11129                         }
11130                         if (($dom[$key]['value'] == 'pre') OR ($dom[$key]['value'] == 'tt')) {
11131                             $dom[$key]['fontname'] = $this->default_monospaced_font;
11132                         }
11133                         if (($dom[$key]['value']{0} == 'h') AND (intval($dom[$key]['value']{1}) > 0) AND (intval($dom[$key]['value']{1}) < 7)) {
11134                             $headsize = (4 - intval($dom[$key]['value']{1})) * 2;
11135                             $dom[$key]['fontsize'] = $dom[0]['fontsize'] + $headsize;
11136                             $dom[$key]['fontstyle'] .= 'B';
11137                         }
11138                         if (($dom[$key]['value'] == 'table')) {
11139                             $dom[$key]['rows'] = 0; 
11140                             $dom[$key]['trids'] = array(); 
11141                             $dom[$key]['thead'] = ''; 
11142                         }
11143                         if (($dom[$key]['value'] == 'tr')) {
11144                             $dom[$key]['cols'] = 0;
11145                             
11146                             ++$dom[($dom[$key]['parent'])]['rows'];
11147                             
11148                             array_push($dom[($dom[$key]['parent'])]['trids'], $key);
11149                             if ($thead) {
11150                                 $dom[$key]['thead'] = true;
11151                             } else {
11152                                 $dom[$key]['thead'] = false;
11153                             }
11154                         }
11155                         if (($dom[$key]['value'] == 'th') OR ($dom[$key]['value'] == 'td')) {
11156                             if (isset($dom[$key]['attribute']['colspan'])) {
11157                                 $colspan = intval($dom[$key]['attribute']['colspan']);
11158                             } else {
11159                                 $colspan = 1;
11160                             }
11161                             $dom[$key]['attribute']['colspan'] = $colspan;
11162                             $dom[($dom[$key]['parent'])]['cols'] += $colspan;
11163                         }
11164                         
11165                         if (isset($dom[$key]['attribute']['color']) AND (!$this->empty_string($dom[$key]['attribute']['color']))) {
11166                             $dom[$key]['fgcolor'] = $this->convertHTMLColorToDec($dom[$key]['attribute']['color']);
11167                         }
11168                         
11169                         if (isset($dom[$key]['attribute']['bgcolor']) AND (!$this->empty_string($dom[$key]['attribute']['bgcolor']))) {
11170                             $dom[$key]['bgcolor'] = $this->convertHTMLColorToDec($dom[$key]['attribute']['bgcolor']);
11171                         }
11172                         
11173                         if (isset($dom[$key]['attribute']['width'])) {
11174                             $dom[$key]['width'] = $dom[$key]['attribute']['width'];
11175                         }
11176                         
11177                         if (isset($dom[$key]['attribute']['height'])) {
11178                             $dom[$key]['height'] = $dom[$key]['attribute']['height'];
11179                         }
11180                         
11181                         if (isset($dom[$key]['attribute']['align']) AND (!$this->empty_string($dom[$key]['attribute']['align'])) AND ($dom[$key]['value'] !== 'img')) {
11182                             $dom[$key]['align'] = strtoupper($dom[$key]['attribute']['align']{0});
11183                         }
11184                     } 
11185                 } else {
11186                     
11187                     $dom[$key]['tag'] = false;
11188                     $dom[$key]['value'] = stripslashes($this->unhtmlentities($element));
11189                     $dom[$key]['parent'] = end($level);
11190                 }
11191                 ++$elkey;
11192                 ++$key;
11193             }
11194             return $dom;
11195         }
11196         
11209         public function writeHTML($html, $ln=true, $fill=false, $reseth=false, $cell=false, $align='') {
11210             $gvars = $this->getGraphicVars();
11211             
11212             $prevPage = $this->page;
11213             $prevlMargin = $this->lMargin;
11214             $prevrMargin = $this->rMargin;
11215             $curfontname = $this->FontFamily;
11216             $curfontstyle = $this->FontStyle;
11217             $curfontsize = $this->FontSizePt;   
11218             $this->newline = true;
11219             $minstartliney = $this->y;
11220             $yshift = 0;
11221             $startlinepage = $this->page;
11222             $newline = true;
11223             $loop = 0;
11224             $curpos = 0;
11225             $blocktags = array('blockquote','br','dd','div','dt','h1','h2','h3','h4','h5','h6','hr','li','ol','p','ul');
11226             $this->premode = false;
11227             if (isset($this->PageAnnots[$this->page])) {
11228                 $pask = count($this->PageAnnots[$this->page]);
11229             } else {
11230                 $pask = 0;
11231             }
11232             if (isset($this->footerlen[$this->page])) {
11233                 $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page];
11234             } else {
11235                 $this->footerpos[$this->page] = $this->pagelen[$this->page];
11236             }
11237             $startlinepos = $this->footerpos[$this->page];
11238             $lalign = $align;
11239             $plalign = $align;
11240             if ($this->rtl) {
11241                 $w = $this->x - $this->lMargin;
11242             } else {
11243                 $w = $this->w - $this->rMargin - $this->x;
11244             }
11245             $w -= (2 * $this->cMargin);
11246             if ($cell) {
11247                 if ($this->rtl) {
11248                     $this->x -= $this->cMargin;
11249                 } else {
11250                     $this->x += $this->cMargin;
11251                 }
11252             }
11253             if ($this->customlistindent >= 0) {
11254                 $this->listindent = $this->customlistindent;
11255             } else {
11256                 $this->listindent = $this->GetStringWidth('0000');
11257             }
11258             $this->listnum = 0;
11259             if (($this->empty_string($this->lasth)) OR ($reseth)) {
11260                 
11261                 $this->lasth = $this->FontSize * $this->cell_height_ratio; 
11262             }
11263             $dom = $this->getHtmlDomArray($html);
11264             $maxel = count($dom);
11265             $key = 0;
11266             while ($key < $maxel) {
11267                 if ($dom[$key]['tag'] OR ($key == 0)) {
11268                     if ((($dom[$key]['value'] == 'table') OR ($dom[$key]['value'] == 'tr')) AND (isset($dom[$key]['align']))) {
11269                         $dom[$key]['align'] = ($this->rtl) ? 'R' : 'L';
11270                     }
11271                     
11272                     if ((!$this->newline)
11273                         AND ($dom[$key]['value'] == 'img')
11274                         AND (isset($dom[$key]['attribute']['height']))
11275                         AND ($dom[$key]['attribute']['height'] > 0)
11276                         AND (!((($this->y + $this->getHTMLUnitToUnits($dom[$key]['attribute']['height'], $this->lasth, 'px')) > $this->PageBreakTrigger)
11277                             AND (!$this->InFooter)
11278                             AND $this->AcceptPageBreak()))
11279                         ) {
11280                         if ($this->page > $startlinepage) {
11281                             
11282                             if (isset($this->footerlen[$startlinepage])) {
11283                                 $curpos = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
11284                             }
11285                             
11286                             $pagebuff = $this->getPageBuffer($startlinepage);
11287                             $linebeg = substr($pagebuff, $startlinepos, ($curpos - $startlinepos));
11288                             $tstart = substr($pagebuff, 0, $startlinepos);
11289                             $tend = substr($this->getPageBuffer($startlinepage), $curpos);
11290                             
11291                             $this->setPageBuffer($startlinepage, $tstart.''.$tend);
11292                             $pagebuff = $this->getPageBuffer($this->page);
11293                             $tstart = substr($pagebuff, 0, $this->intmrk[$this->page]);
11294                             $tend = substr($pagebuff, $this->intmrk[$this->page]);
11295                             
11296                             $yshift = $minstartliney - $this->y;
11297                             $try = sprintf('1 0 0 1 0 %.3F cm', ($yshift * $this->k));
11298                             $this->setPageBuffer($this->page, $tstart."\nq\n".$try."\n".$linebeg."\nQ\n".$tend);
11299                             
11300                             if (isset($this->PageAnnots[$startlinepage])) {
11301                                 foreach ($this->PageAnnots[$startlinepage] as $pak => $pac) {
11302                                     if ($pak >= $pask) {
11303                                         $this->PageAnnots[$this->page][] = $pac;
11304                                         unset($this->PageAnnots[$startlinepage][$pak]);
11305                                         $npak = count($this->PageAnnots[$this->page]) - 1;
11306                                         $this->PageAnnots[$this->page][$npak]['y'] -= $yshift;
11307                                     }
11308                                 }
11309                             }
11310                         }
11311                         $this->y += (($curfontsize / $this->k) - $this->getHTMLUnitToUnits($dom[$key]['attribute']['height'], $this->lasth, 'px'));
11312                         $minstartliney = min($this->y, $minstartliney);
11313                     } elseif (isset($dom[$key]['fontname']) OR isset($dom[$key]['fontstyle']) OR isset($dom[$key]['fontsize'])) {
11314                         
11315                         $pfontname = $curfontname;
11316                         $pfontstyle = $curfontstyle;
11317                         $pfontsize = $curfontsize;
11318                         $fontname = isset($dom[$key]['fontname']) ? $dom[$key]['fontname'] : $curfontname;
11319                         $fontstyle = isset($dom[$key]['fontstyle']) ? $dom[$key]['fontstyle'] : $curfontstyle;
11320                         $fontsize = isset($dom[$key]['fontsize']) ? $dom[$key]['fontsize'] : $curfontsize;
11321                         if (($fontname != $curfontname) OR ($fontstyle != $curfontstyle) OR ($fontsize != $curfontsize)) {
11322                             $this->SetFont($fontname, $fontstyle, $fontsize);
11323                             $this->lasth = $this->FontSize * $this->cell_height_ratio;
11324                             if (is_numeric($fontsize) AND ($fontsize > 0)
11325                                 AND is_numeric($curfontsize) AND ($curfontsize > 0)
11326                                 AND ($fontsize != $curfontsize) AND (!$this->newline)
11327                                 AND ($key < ($maxel - 1))
11328                                 ) {
11329                                 if ((!$this->newline) AND ($this->page > $startlinepage)) {
11330                                     
11331                                     if (isset($this->footerlen[$startlinepage])) {
11332                                         $curpos = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
11333                                     }
11334                                     
11335                                     $pagebuff = $this->getPageBuffer($startlinepage);
11336                                     $linebeg = substr($pagebuff, $startlinepos, ($curpos - $startlinepos));
11337                                     $tstart = substr($pagebuff, 0, $startlinepos);
11338                                     $tend = substr($this->getPageBuffer($startlinepage), $curpos);
11339                                     
11340                                     $this->setPageBuffer($startlinepage, $tstart.''.$tend);
11341                                     $pagebuff = $this->getPageBuffer($this->page);
11342                                     $tstart = substr($pagebuff, 0, $this->intmrk[$this->page]);
11343                                     $tend = substr($pagebuff, $this->intmrk[$this->page]);
11344                                     
11345                                     $yshift = $minstartliney - $this->y;
11346                                     $try = sprintf('1 0 0 1 0 %.3F cm', ($yshift * $this->k));
11347                                     $this->setPageBuffer($this->page, $tstart."\nq\n".$try."\n".$linebeg."\nQ\n".$tend);
11348                                     
11349                                     if (isset($this->PageAnnots[$startlinepage])) {
11350                                         foreach ($this->PageAnnots[$startlinepage] as $pak => $pac) {
11351                                             if ($pak >= $pask) {
11352                                                 $this->PageAnnots[$this->page][] = $pac;
11353                                                 unset($this->PageAnnots[$startlinepage][$pak]);
11354                                                 $npak = count($this->PageAnnots[$this->page]) - 1;
11355                                                 $this->PageAnnots[$this->page][$npak]['y'] -= $yshift;
11356                                             }
11357                                         }
11358                                     }
11359                                 }
11360                                 $this->y += (($curfontsize - $fontsize) / $this->k);
11361                                 $minstartliney = min($this->y, $minstartliney);
11362                             }
11363                             $curfontname = $fontname;
11364                             $curfontstyle = $fontstyle;
11365                             $curfontsize = $fontsize;
11366                         }
11367                     }
11368                     if (($plalign == 'J') AND (in_array($dom[$key]['value'], $blocktags))) {
11369                         $plalign = '';
11370                     }
11371                     
11372                     $curpos = $this->pagelen[$startlinepage];
11373                     if (isset($dom[$key]['bgcolor']) AND ($dom[$key]['bgcolor'] !== false)) {
11374                         $this->SetFillColorArray($dom[$key]['bgcolor']);
11375                         $wfill = true;
11376                     } else {
11377                         $wfill = $fill | false;
11378                     }
11379                     if (isset($dom[$key]['fgcolor']) AND ($dom[$key]['fgcolor'] !== false)) {
11380                         $this->SetTextColorArray($dom[$key]['fgcolor']);
11381                     }
11382                     if (isset($dom[$key]['align'])) {
11383                         $lalign = $dom[$key]['align'];
11384                     }
11385                     if ($this->empty_string($lalign)) {
11386                         $lalign = $align;
11387                     }
11388                 }
11389                 
11390                 if ($this->newline AND (strlen($dom[$key]['value']) > 0) AND ($dom[$key]['value'] != 'td') AND ($dom[$key]['value'] != 'th')) {
11391                     $newline = true;
11392                     
11393                     if (isset($startlinex)) {
11394                         $yshift = $minstartliney - $startliney;
11395                         if (($yshift > 0) OR ($this->page > $startlinepage)) {
11396                             $yshift = 0;
11397                         }
11398                         if ((isset($plalign) AND ((($plalign == 'C') OR ($plalign == 'J') OR (($plalign == 'R') AND (!$this->rtl)) OR (($plalign == 'L') AND ($this->rtl))))) OR ($yshift < 0)) {
11399                             
11400                             $linew = abs($this->endlinex - $startlinex);
11401                             $pstart = substr($this->getPageBuffer($startlinepage), 0, $startlinepos);
11402                             if (isset($opentagpos) AND isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
11403                                 $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
11404                                 $midpos = min($opentagpos, $this->footerpos[$startlinepage]);
11405                             } elseif (isset($opentagpos)) {
11406                                 $midpos = $opentagpos;
11407                             } elseif (isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
11408                                 $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
11409                                 $midpos = $this->footerpos[$startlinepage];
11410                             } else {
11411                                 $midpos = 0;
11412                             }
11413                             if ($midpos > 0) {
11414                                 $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos, ($midpos - $startlinepos));
11415                                 $pend = substr($this->getPageBuffer($startlinepage), $midpos);
11416                             } else {
11417                                 $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos);
11418                                 $pend = '';
11419                             }
11420                             
11421                             $tw = $w;
11422                             if ($this->lMargin != $prevlMargin) {
11423                                 $tw += ($prevlMargin - $this->lMargin);
11424                             }
11425                             if ($this->rMargin != $prevrMargin) {
11426                                 $tw += ($prevrMargin - $this->rMargin);
11427                             }
11428                             $mdiff = abs($tw - $linew);
11429                             $t_x = 0;
11430                             if ($plalign == 'C') {
11431                                 if ($this->rtl) {
11432                                     $t_x = -($mdiff / 2);
11433                                 } else {
11434                                     $t_x = ($mdiff / 2);
11435                                 }
11436                             } elseif (($plalign == 'R') AND (!$this->rtl)) {
11437                                 
11438                                 $t_x = $mdiff;  
11439                             } elseif (($plalign == 'L') AND ($this->rtl)) {
11440                                 
11441                                 $t_x = -$mdiff;
11442                             } elseif (($plalign == 'J') AND ($plalign == $lalign)) {
11443                                 
11444                                 if ($this->rtl OR $this->tmprtl) {
11445                                     $t_x = $this->lMargin - $this->endlinex;
11446                                 }
11447                                 $no = 0;
11448                                 $ns = 0;
11449                                 $pmidtemp = $pmid;
11450                                 
11451                                 $pmidtemp = preg_replace('/[\\\][\(]/x', '\\#!#OP#!#', $pmidtemp);
11452                                 $pmidtemp = preg_replace('/[\\\][\)]/x', '\\#!#CP#!#', $pmidtemp);
11453                                 
11454                                 if (preg_match_all('/\[\(([^\)]*)\)\]/x', $pmidtemp, $lnstring, PREG_PATTERN_ORDER)) {
11455                                     $maxkk = count($lnstring[1]) - 1;
11456                                     for ($kk=0; $kk <= $maxkk; ++$kk) {
11457                                         
11458                                         $lnstring[1][$kk] = str_replace('#!#OP#!#', '(', $lnstring[1][$kk]);
11459                                         $lnstring[1][$kk] = str_replace('#!#CP#!#', ')', $lnstring[1][$kk]);
11460                                         if ($kk == $maxkk) {
11461                                             if ($this->rtl OR $this->tmprtl) {
11462                                                 $tvalue = ltrim($lnstring[1][$kk]);
11463                                             } else {
11464                                                 $tvalue = rtrim($lnstring[1][$kk]);
11465                                             }
11466                                         } else {
11467                                             $tvalue = $lnstring[1][$kk];
11468                                         }
11469                                         
11470                                         $no += substr_count($lnstring[1][$kk], chr(32));
11471                                         $ns += substr_count($tvalue, chr(32));
11472                                     }
11473                                     if ($this->rtl OR $this->tmprtl) {
11474                                         $t_x = $this->lMargin - $this->endlinex - (($no - $ns - 1) * $this->GetStringWidth(chr(32)));
11475                                     }
11476                                     
11477                                     $spacewidth = (($tw - $linew + (($no - $ns) * $this->GetStringWidth(chr(32)))) / ($ns?$ns:1)) * $this->k;
11478                                     $spacewidthu = ($tw - $linew + ($no * $this->GetStringWidth(chr(32)))) / ($ns?$ns:1) / $this->FontSize / $this->k;
11479                                     $nsmax = $ns;
11480                                     $ns = 0;
11481                                     reset($lnstring);
11482                                     $offset = 0;
11483                                     $strcount = 0;
11484                                     $prev_epsposbeg = 0;
11485                                     global $spacew;
11486                                     while (preg_match('/([0-9\.\+\-]*)[\s](Td|cm|m|l|c|re)[\s]/x', $pmid, $strpiece, PREG_OFFSET_CAPTURE, $offset) == 1) {
11487                                         if ($this->rtl OR $this->tmprtl) {
11488                                             $spacew = ($spacewidth * ($nsmax - $ns));
11489                                         } else {
11490                                             $spacew = ($spacewidth * $ns);
11491                                         }
11492                                         $offset = $strpiece[2][1] + strlen($strpiece[2][0]);
11493                                         $epsposbeg = strpos($pmid, 'q'.$this->epsmarker, $offset);
11494                                         $epsposend = strpos($pmid, $this->epsmarker.'Q', $offset) + strlen($this->epsmarker.'Q');
11495                                         if ((($epsposbeg > 0) AND ($epsposend > 0) AND ($offset > $epsposbeg) AND ($offset < $epsposend))
11496                                             OR (($epsposbeg === false) AND ($epsposend > 0) AND ($offset < $epsposend))) {
11497                                             
11498                                             $trx = sprintf('1 0 0 1 %.3F 0 cm', $spacew);
11499                                             $epsposbeg = strpos($pmid, 'q'.$this->epsmarker, ($prev_epsposbeg - 6));
11500                                             $pmid_b = substr($pmid, 0, $epsposbeg);
11501                                             $pmid_m = substr($pmid, $epsposbeg, ($epsposend - $epsposbeg));
11502                                             $pmid_e = substr($pmid, $epsposend);
11503                                             $pmid = $pmid_b."\nq\n".$trx."\n".$pmid_m."\nQ\n".$pmid_e;
11504                                             $offset = $epsposend;
11505                                             continue;
11506                                         }
11507                                         $prev_epsposbeg = $epsposbeg;
11508                                         $currentxpos = 0;
11509                                         
11510                                         switch ($strpiece[2][0]) {
11511                                             case 'Td':
11512                                             case 'cm':
11513                                             case 'm':
11514                                             case 'l': {
11515                                                 
11516                                                 preg_match('/([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', $pmid, $xmatches);
11517                                                 $currentxpos = $xmatches[1];
11518                                                 if (($strcount <= $maxkk) AND ($strpiece[2][0] == 'Td')) {
11519                                                     if ($strcount == $maxkk) {
11520                                                         if ($this->rtl OR $this->tmprtl) {
11521                                                             $tvalue = $lnstring[1][$strcount];
11522                                                         } else {
11523                                                             $tvalue = rtrim($lnstring[1][$strcount]);
11524                                                         }
11525                                                     } else {
11526                                                         $tvalue = $lnstring[1][$strcount];
11527                                                     }
11528                                                     $ns += substr_count($tvalue, chr(32));
11529                                                     ++$strcount;
11530                                                 }
11531                                                 if ($this->rtl OR $this->tmprtl) {
11532                                                     $spacew = ($spacewidth * ($nsmax - $ns));
11533                                                 }
11534                                                 
11535                                                 $pmid = preg_replace_callback('/([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x',
11536                                                     create_function('$matches', 'global $spacew;
11537                                                     $newx = sprintf("%.2F",(floatval($matches[1]) + $spacew));
11538                                                     return "".$newx." ".$matches[2]." x*#!#*x".$matches[3].$matches[4];'), $pmid, 1);
11539                                                 break;
11540                                             }
11541                                             case 're': {
11542                                                 
11543                                                 preg_match('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', $pmid, $xmatches);
11544                                                 $currentxpos = $xmatches[1];
11545                                                 
11546                                                 $pmid = preg_replace_callback('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x',
11547                                                     create_function('$matches', 'global $spacew;
11548                                                     $newx = sprintf("%.2F",(floatval($matches[1]) + $spacew));
11549                                                     return "".$newx." ".$matches[2]." ".$matches[3]." ".$matches[4]." x*#!#*x".$matches[5].$matches[6];'), $pmid, 1);
11550                                                 break;
11551                                             }
11552                                             case 'c': {
11553                                                 
11554                                                 preg_match('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', $pmid, $xmatches);
11555                                                 $currentxpos = $xmatches[1];
11556                                                 
11557                                                 $pmid = preg_replace_callback('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x',
11558                                                     create_function('$matches', 'global $spacew;
11559                                                     $newx1 = sprintf("%.3F",(floatval($matches[1]) + $spacew));
11560                                                     $newx2 = sprintf("%.3F",(floatval($matches[3]) + $spacew));
11561                                                     $newx3 = sprintf("%.3F",(floatval($matches[5]) + $spacew));
11562                                                     return "".$newx1." ".$matches[2]." ".$newx2." ".$matches[4]." ".$newx3." ".$matches[6]." x*#!#*x".$matches[7].$matches[8];'), $pmid, 1);
11563                                                 break;
11564                                             }
11565                                         }
11566                                         
11567                                         if (isset($this->PageAnnots[$this->page])) {
11568                                             foreach ($this->PageAnnots[$this->page] as $pak => $pac) {
11569                                                 if (($pac['y'] >= $minstartliney) AND (($pac['x'] * $this->k) >= ($currentxpos - $this->feps)) AND (($pac['x'] * $this->k) <= ($currentxpos + $this->feps))) {
11570                                                     $this->PageAnnots[$this->page][$pak]['x'] += ($spacew / $this->k);
11571                                                     $this->PageAnnots[$this->page][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k);
11572                                                     break;
11573                                                 }
11574                                             }
11575                                         }
11576                                     } 
11577                                     
11578                                     $pmid = str_replace('x*#!#*x', '', $pmid);
11579                                     if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
11580                                         
11581                                         $spacew = $spacewidthu;
11582                                         $pmidtemp = $pmid;
11583                                         
11584                                         $pmidtemp = preg_replace('/[\\\][\(]/x', '\\#!#OP#!#', $pmidtemp);
11585                                         $pmidtemp = preg_replace('/[\\\][\)]/x', '\\#!#CP#!#', $pmidtemp);
11586                                         $pmid = preg_replace_callback("/\[\(([^\)]*)\)\]/x",
11587                                                     create_function('$matches', 'global $spacew;
11588                                                     $matches[1] = str_replace("#!#OP#!#", "(", $matches[1]);
11589                                                     $matches[1] = str_replace("#!#CP#!#", ")", $matches[1]);
11590                                                     return "[(".str_replace(chr(0).chr(32), ") ".(-2830 * $spacew)." (", $matches[1]).")]";'), $pmidtemp);
11591                                         $this->setPageBuffer($startlinepage, $pstart."\n".$pmid."\n".$pend);
11592                                         $endlinepos = strlen($pstart."\n".$pmid."\n");
11593                                     } else {
11594                                         
11595                                         $rs = sprintf("%.3F Tw", $spacewidth);
11596                                         $pmid = preg_replace("/\[\(/x", $rs.' [(', $pmid);
11597                                         $this->setPageBuffer($startlinepage, $pstart."\n".$pmid."\nBT 0 Tw ET\n".$pend);
11598                                         $endlinepos = strlen($pstart."\n".$pmid."\nBT 0 Tw ET\n");
11599                                     }
11600                                 }
11601                             } 
11602                             if (($t_x != 0) OR ($yshift < 0)) {
11603                                 
11604                                 $trx = sprintf('1 0 0 1 %.3F %.3F cm', ($t_x * $this->k), ($yshift * $this->k));
11605                                 $this->setPageBuffer($startlinepage, $pstart."\nq\n".$trx."\n".$pmid."\nQ\n".$pend);
11606                                 $endlinepos = strlen($pstart."\nq\n".$trx."\n".$pmid."\nQ\n");
11607                                 
11608                                 if (isset($this->PageAnnots[$this->page])) {
11609                                     foreach ($this->PageAnnots[$this->page] as $pak => $pac) {
11610                                         if ($pak >= $pask) {
11611                                             $this->PageAnnots[$this->page][$pak]['x'] += $t_x;
11612                                             $this->PageAnnots[$this->page][$pak]['y'] -= $yshift;
11613                                         }
11614                                     }
11615                                 }
11616                                 $this->y -= $yshift;
11617                             }
11618                         }
11619                     }
11620                     $this->newline = false;
11621                     $pbrk = $this->checkPageBreak($this->lasth);
11622                     $this->SetFont($fontname, $fontstyle, $fontsize);
11623                     if ($wfill) {
11624                         $this->SetFillColorArray($this->bgcolor);
11625                     }
11626                     $startlinex = $this->x;
11627                     $startliney = $this->y;
11628                     $minstartliney = $this->y;
11629                     $startlinepage = $this->page;
11630                     if (isset($endlinepos) AND (!$pbrk)) {
11631                         $startlinepos = $endlinepos;
11632                         unset($endlinepos);
11633                     } else {
11634                         if (isset($this->footerlen[$this->page])) {
11635                             $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page];
11636                         } else {
11637                             $this->footerpos[$this->page] = $this->pagelen[$this->page];
11638                         }
11639                         $startlinepos = $this->footerpos[$this->page];
11640                     }
11641                     $plalign = $lalign;
11642                     if (isset($this->PageAnnots[$this->page])) {
11643                         $pask = count($this->PageAnnots[$this->page]);
11644                     } else {
11645                         $pask = 0;
11646                     }
11647                 }
11648                 if (isset($opentagpos)) {
11649                     unset($opentagpos);
11650                 }
11651                 if ($dom[$key]['tag']) {
11652                     if ($dom[$key]['opening']) {
11653                         if ($dom[$key]['value'] == 'table') {
11654                             if ($this->rtl) {
11655                                 $wtmp = $this->x - $this->lMargin;
11656                             } else {
11657                                 $wtmp = $this->w - $this->rMargin - $this->x;
11658                             }
11659                             $wtmp -= (2 * $this->cMargin);
11660                             
11661                             if (isset($dom[$key]['width'])) {
11662                                 $table_width = $this->getHTMLUnitToUnits($dom[$key]['width'], $wtmp, 'px');
11663                             } else {
11664                                 $table_width = $wtmp;
11665                             }
11666                         }
11667                         
11668                         if (($dom[$key]['value'] == 'td') OR ($dom[$key]['value'] == 'th')) {
11669                             $trid = $dom[$key]['parent'];
11670                             $table_el = $dom[$trid]['parent'];
11671                             if (!isset($dom[$table_el]['cols'])) {
11672                                 $dom[$table_el]['cols'] = $trid['cols'];
11673                             }
11674                             $oldmargin = $this->cMargin;
11675                             if (isset($dom[($dom[$trid]['parent'])]['attribute']['cellpadding'])) {
11676                                 $currentcmargin = $this->getHTMLUnitToUnits($dom[($dom[$trid]['parent'])]['attribute']['cellpadding'], 1, 'px');
11677                             } else {
11678                                 $currentcmargin = 0;        
11679                             }
11680                             $this->cMargin = $currentcmargin;
11681                             if (isset($dom[($dom[$trid]['parent'])]['attribute']['cellspacing'])) {
11682                                 $cellspacing = $this->getHTMLUnitToUnits($dom[($dom[$trid]['parent'])]['attribute']['cellspacing'], 1, 'px');
11683                             } else {
11684                                 $cellspacing = 0;
11685                             }
11686                             if ($this->rtl) {
11687                                 $cellspacingx = -$cellspacing;
11688                             } else {
11689                                 $cellspacingx = $cellspacing;
11690                             }
11691                             $colspan = $dom[$key]['attribute']['colspan'];
11692                             $wtmp = ($colspan * ($table_width / $dom[$table_el]['cols']));
11693                             if (isset($dom[$key]['width'])) {
11694                                 $cellw = $this->getHTMLUnitToUnits($dom[$key]['width'], $wtmp, 'px');
11695                             } else {
11696                                 $cellw = $wtmp;
11697                             }
11698                             if (isset($dom[$key]['height'])) {
11699                                 
11700                                 $cellh = $this->getHTMLUnitToUnits($dom[$key]['height'], 0, 'px');
11701                             } else {
11702                                 $cellh = 0;
11703                             }
11704                             $cellw -= $cellspacing;
11705                             if (isset($dom[$key]['content'])) {
11706                                 $cell_content = $dom[$key]['content'];
11707                             } else {
11708                                 $cell_content = ' ';
11709                             }
11710                             $tagtype = $dom[$key]['value'];
11711                             $parentid = $key;
11712                             while (($key < $maxel) AND (!(($dom[$key]['tag']) AND (!$dom[$key]['opening']) AND ($dom[$key]['value'] == $tagtype) AND ($dom[$key]['parent'] == $parentid)))) {
11713                                 
11714                                 ++$key;
11715                             }
11716                             if (!isset($dom[$trid]['startpage'])) {
11717                                 $dom[$trid]['startpage'] = $this->page;
11718                             } else {
11719                                 $this->setPage($dom[$trid]['startpage']);
11720                             }
11721                             if (!isset($dom[$trid]['starty'])) {
11722                                 $dom[$trid]['starty'] = $this->y;
11723                             } else {
11724                                 $this->y = $dom[$trid]['starty'];
11725                             }
11726                             if (!isset($dom[$trid]['startx'])) {
11727                                 $dom[$trid]['startx'] = $this->x;
11728                             }
11729                             $this->x += ($cellspacingx / 2);                        
11730                             if (isset($dom[$parentid]['attribute']['rowspan'])) {
11731                                 $rowspan = intval($dom[$parentid]['attribute']['rowspan']);
11732                             } else {
11733                                 $rowspan = 1;
11734                             }
11735                             
11736                             if (isset($dom[$table_el]['rowspans'])) {
11737                                 $rsk = 0;
11738                                 $rskmax = count($dom[$table_el]['rowspans']);
11739                                 while ($rsk < $rskmax) {
11740                                     $trwsp = $dom[$table_el]['rowspans'][$rsk];
11741                                     $rsstartx = $trwsp['startx'];
11742                                     $rsendx = $trwsp['endx'];
11743                                     
11744                                     if ($trwsp['startpage'] < $this->page) {
11745                                         if (($this->rtl) AND ($this->pagedim[$this->page]['orm'] != $this->pagedim[$trwsp['startpage']]['orm'])) {
11746                                             $dl = ($this->pagedim[$this->page]['orm'] - $this->pagedim[$trwsp['startpage']]['orm']);
11747                                             $rsstartx -= $dl;
11748                                             $rsendx -= $dl;
11749                                         } elseif ((!$this->rtl) AND ($this->pagedim[$this->page]['olm'] != $this->pagedim[$trwsp['startpage']]['olm'])) {
11750                                             $dl = ($this->pagedim[$this->page]['olm'] - $this->pagedim[$trwsp['startpage']]['olm']);
11751                                             $rsstartx += $dl;
11752                                             $rsendx += $dl;
11753                                         }
11754                                     }
11755                                     if  (($trwsp['rowspan'] > 0)
11756                                         AND ($rsstartx > ($this->x - $cellspacing - $currentcmargin - $this->feps))
11757                                         AND ($rsstartx < ($this->x + $cellspacing + $currentcmargin + $this->feps))
11758                                         AND (($trwsp['starty'] < ($this->y - $this->feps)) OR ($trwsp['startpage'] < $this->page))) {
11759                                         
11760                                         $this->x = $rsendx + $cellspacingx;
11761                                         if (($trwsp['rowspan'] == 1)
11762                                             AND (isset($dom[$trid]['endy']))
11763                                             AND (isset($dom[$trid]['endpage']))
11764                                             AND ($trwsp['endpage'] == $dom[$trid]['endpage'])) {
11765                                             
11766                                             $dom[$table_el]['rowspans'][$rsk]['endy'] = max($dom[$trid]['endy'], $trwsp['endy']);
11767                                             $dom[$trid]['endy'] = $dom[$table_el]['rowspans'][$rsk]['endy'];
11768                                         }
11769                                         $rsk = 0;
11770                                     } else {
11771                                         ++$rsk;
11772                                     }
11773                                 }
11774                             }
11775                             
11776                             if ($rowspan > 1) {
11777                                 if (isset($this->footerlen[$this->page])) {
11778                                     $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page];
11779                                 } else {
11780                                     $this->footerpos[$this->page] = $this->pagelen[$this->page];
11781                                 }
11782                                 $trintmrkpos = $this->footerpos[$this->page];
11783                                 $trsid = array_push($dom[$table_el]['rowspans'], array('trid' => $trid, 'rowspan' => $rowspan, 'mrowspan' => $rowspan, 'colspan' => $colspan, 'startpage' => $this->page, 'startx' => $this->x, 'starty' => $this->y, 'intmrkpos' => $trintmrkpos));
11784                             }
11785                             $cellid = array_push($dom[$trid]['cellpos'], array('startx' => $this->x));
11786                             if ($rowspan > 1) {
11787                                 $dom[$trid]['cellpos'][($cellid - 1)]['rowspanid'] = ($trsid - 1);
11788                             }
11789                             
11790                             if (isset($dom[$parentid]['bgcolor']) AND ($dom[$parentid]['bgcolor'] !== false)) {
11791                                 $dom[$trid]['cellpos'][($cellid - 1)]['bgcolor'] = $dom[$parentid]['bgcolor'];
11792                             }
11793                             $prevLastH = $this->lasth;
11794                             
11795                             $this->MultiCell($cellw, $cellh, $cell_content, false, $lalign, false, 2, '', '', true, 0, true);
11796                             $this->lasth = $prevLastH;
11797                             $this->cMargin = $oldmargin;
11798                             $dom[$trid]['cellpos'][($cellid - 1)]['endx'] = $this->x;
11799                             
11800                             if ($rowspan <= 1) {
11801                                 if (isset($dom[$trid]['endy'])) {
11802                                     if ($this->page == $dom[$trid]['endpage']) {
11803                                         $dom[$trid]['endy'] = max($this->y, $dom[$trid]['endy']);
11804                                     } elseif ($this->page > $dom[$trid]['endpage']) {
11805                                         $dom[$trid]['endy'] = $this->y;
11806                                     }
11807                                 } else {
11808                                     $dom[$trid]['endy'] = $this->y;
11809                                 }
11810                                 if (isset($dom[$trid]['endpage'])) {
11811                                     $dom[$trid]['endpage'] = max($this->page, $dom[$trid]['endpage']);
11812                                 } else {
11813                                     $dom[$trid]['endpage'] = $this->page;
11814                                 }                               
11815                             } else {
11816                                 
11817                                 $dom[$table_el]['rowspans'][($trsid - 1)]['endx'] = $this->x;
11818                                 $dom[$table_el]['rowspans'][($trsid - 1)]['endy'] = $this->y;
11819                                 $dom[$table_el]['rowspans'][($trsid - 1)]['endpage'] = $this->page;
11820                             }
11821                             if (isset($dom[$table_el]['rowspans'])) {
11822                                 
11823                                 foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
11824                                     if ($trwsp['rowspan'] > 0) {
11825                                         if (isset($dom[$trid]['endpage'])) {
11826                                             if ($trwsp['endpage'] == $dom[$trid]['endpage']) {
11827                                                 $dom[$table_el]['rowspans'][$k]['endy'] = max($dom[$trid]['endy'], $trwsp['endy']);
11828                                             } elseif ($trwsp['endpage'] < $dom[$trid]['endpage']) {
11829                                                 $dom[$table_el]['rowspans'][$k]['endy'] = $dom[$trid]['endy'];
11830                                                 $dom[$table_el]['rowspans'][$k]['endpage'] = $dom[$trid]['endpage'];
11831                                             } else {
11832                                                 $dom[$trid]['endy'] = $this->pagedim[$dom[$trid]['endpage']]['hk'] - $this->pagedim[$dom[$trid]['endpage']]['bm'];
11833                                             }
11834                                         }
11835                                     }
11836                                 }
11837                             }
11838                             $this->x += ($cellspacingx / 2);                            
11839                         } else {
11840                             
11841                             if (!isset($opentagpos)) {
11842                                 if (!$this->InFooter) {
11843                                     if (isset($this->footerlen[$this->page])) {
11844                                         $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page];
11845                                     } else {
11846                                         $this->footerpos[$this->page] = $this->pagelen[$this->page];
11847                                     }
11848                                     $opentagpos = $this->footerpos[$this->page];
11849                                 }
11850                             }
11851                             $this->openHTMLTagHandler($dom, $key, $cell);
11852                         }
11853                     } else {
11854                         
11855                         $this->closeHTMLTagHandler($dom, $key, $cell);
11856                     }
11857                 } elseif (strlen($dom[$key]['value']) > 0) {
11858                     
11859                     if (!$this->empty_string($this->lispacer)) {
11860                         $this->SetFont($pfontname, $pfontstyle, $pfontsize);
11861                         $this->lasth = $this->FontSize * $this->cell_height_ratio;
11862                         $minstartliney = $this->y;
11863                         $this->putHtmlListBullet($this->listnum, $this->lispacer, $pfontsize);
11864                         $this->SetFont($curfontname, $curfontstyle, $curfontsize);
11865                         $this->lasth = $this->FontSize * $this->cell_height_ratio;
11866                         if (is_numeric($pfontsize) AND ($pfontsize > 0) AND is_numeric($curfontsize) AND ($curfontsize > 0) AND ($pfontsize != $curfontsize)) {
11867                             $this->y += (($pfontsize - $curfontsize) / $this->k);
11868                             $minstartliney = min($this->y, $minstartliney);
11869                         }
11870                     }
11871                     
11872                     $this->htmlvspace = 0;
11873                     if ((!$this->premode) AND ($this->rtl OR $this->tmprtl)) {
11874                         
11875                         $len1 = strlen($dom[$key]['value']);
11876                         $lsp = $len1 - strlen(ltrim($dom[$key]['value']));
11877                         $rsp = $len1 - strlen(rtrim($dom[$key]['value']));
11878                         $tmpstr = '';
11879                         if ($rsp > 0) {
11880                             $tmpstr .= substr($dom[$key]['value'], -$rsp);
11881                         }
11882                         $tmpstr .= trim($dom[$key]['value']);
11883                         if ($lsp > 0) {
11884                             $tmpstr .= substr($dom[$key]['value'], 0, $lsp);
11885                         }
11886                         $dom[$key]['value'] = $tmpstr;
11887                     }
11888                     if ($newline) {
11889                         if (!$this->premode) {
11890                             if (($this->rtl OR $this->tmprtl)) {
11891                                 $dom[$key]['value'] = rtrim($dom[$key]['value']);
11892                             } else {
11893                                 $dom[$key]['value'] = ltrim($dom[$key]['value']);
11894                             }
11895                         }
11896                         $newline = false;
11897                         $firstblock = true;
11898                     } else {
11899                         $firstblock = false;
11900                     }
11901                     $strrest = '';
11902                     if (!empty($this->HREF) AND (isset($this->HREF['url']))) {
11903                         
11904                         $strrest = $this->addHtmlLink($this->HREF['url'], $dom[$key]['value'], $wfill, true, $this->HREF['color'], $this->HREF['style']);
11905                     } else {
11906                         $ctmpmargin = $this->cMargin;
11907                         $this->cMargin = 0;
11908                         
11909                         $strrest = $this->Write($this->lasth, $dom[$key]['value'], '', $wfill, '', false, 0, true, $firstblock);
11910                         $this->cMargin = $ctmpmargin;
11911                     }
11912                     if (strlen($strrest) > 0) {
11913                         
11914                         $this->newline = true;
11915                         if ($cell) {
11916                             if ($this->rtl) {
11917                                 $this->x -= $this->cMargin;
11918                             } else {
11919                                 $this->x += $this->cMargin;
11920                             }
11921                         }
11922                         if ($strrest == $dom[$key]['value']) {
11923                             
11924                             ++$loop;
11925                         } else {
11926                             $loop = 0;
11927                         }
11928                         $dom[$key]['value'] = ltrim($strrest);
11929                         if ($loop < 3) {
11930                             --$key;
11931                         }
11932                     } else {
11933                         $loop = 0;
11934                     }
11935                 }
11936                 ++$key;
11937             } 
11938             
11939             if (isset($startlinex)) {
11940                 $yshift = $minstartliney - $startliney;
11941                 if (($yshift > 0) OR ($this->page > $startlinepage)) {
11942                     $yshift = 0;
11943                 }
11944                 if ((isset($plalign) AND ((($plalign == 'C') OR ($plalign == 'J') OR (($plalign == 'R') AND (!$this->rtl)) OR (($plalign == 'L') AND ($this->rtl))))) OR ($yshift < 0)) {
11945                     
11946                     $linew = abs($this->endlinex - $startlinex);
11947                     $pstart = substr($this->getPageBuffer($startlinepage), 0, $startlinepos);
11948                     if (isset($opentagpos) AND isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
11949                         $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
11950                         $midpos = min($opentagpos, $this->footerpos[$startlinepage]);
11951                     } elseif (isset($opentagpos)) {
11952                         $midpos = $opentagpos;
11953                     } elseif (isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
11954                         $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
11955                         $midpos = $this->footerpos[$startlinepage];
11956                     } else {
11957                         $midpos = 0;
11958                     }
11959                     if ($midpos > 0) {
11960                         $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos, ($midpos - $startlinepos));
11961                         $pend = substr($this->getPageBuffer($startlinepage), $midpos);
11962                     } else {
11963                         $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos);
11964                         $pend = '';
11965                     }   
11966                     
11967                     $tw = $w;
11968                     if ($this->lMargin != $prevlMargin) {
11969                         $tw += ($prevlMargin - $this->lMargin);
11970                     }
11971                     if ($this->rMargin != $prevrMargin) {
11972                         $tw += ($prevrMargin - $this->rMargin);
11973                     }
11974                     $mdiff = abs($tw - $linew);
11975                     if ($plalign == 'C') {
11976                         if ($this->rtl) {
11977                             $t_x = -($mdiff / 2);
11978                         } else {
11979                             $t_x = ($mdiff / 2);
11980                         }
11981                     } elseif (($plalign == 'R') AND (!$this->rtl)) {
11982                         
11983                         $t_x = $mdiff;
11984                     } elseif (($plalign == 'L') AND ($this->rtl)) {
11985                         
11986                         $t_x = -$mdiff;
11987                     } else {
11988                         $t_x = 0;
11989                     }
11990                     if (($t_x != 0) OR ($yshift < 0)) {
11991                         
11992                         $trx = sprintf('1 0 0 1 %.3F %.3F cm', ($t_x * $this->k), ($yshift * $this->k));
11993                         $this->setPageBuffer($startlinepage, $pstart."\nq\n".$trx."\n".$pmid."\nQ\n".$pend);
11994                         $endlinepos = strlen($pstart."\nq\n".$trx."\n".$pmid."\nQ\n");
11995                         
11996                         if (isset($this->PageAnnots[$this->page])) {
11997                             foreach ($this->PageAnnots[$this->page] as $pak => $pac) {
11998                                 if ($pak >= $pask) {
11999                                     $this->PageAnnots[$this->page][$pak]['x'] += $t_x;
12000                                     $this->PageAnnots[$this->page][$pak]['y'] -= $yshift;
12001                                 }
12002                             }
12003                         }
12004                         $this->y -= $yshift;
12005                     }
12006                 }
12007             }
12008             if ($ln AND (!($cell AND ($dom[$key-1]['value'] == 'table')))) {
12009                 $this->Ln($this->lasth);
12010             }
12011             
12012             $this->setGraphicVars($gvars);
12013             if ($this->page > $prevPage) {
12014                 $this->lMargin = $this->pagedim[$this->page]['olm'];
12015                 $this->rMargin = $this->pagedim[$this->page]['orm'];
12016             }
12017             unset($dom);
12018         }
12019         
12027         protected function openHTMLTagHandler(&$dom, $key, $cell=false) {
12028             $tag = $dom[$key];
12029             $parent = $dom[($dom[$key]['parent'])];
12030             $firstorlast = ($key == 1);
12031             
12032             if (isset($tag['attribute']['dir'])) {
12033                 $this->tmprtl = $tag['attribute']['dir'] == 'rtl' ? 'R' : 'L';
12034             } else {
12035                 $this->tmprtl = false;
12036             }
12037             
12038             switch($tag['value']) {
12039                 case 'table': {
12040                     $cp = 0;
12041                     $cs = 0;
12042                     $dom[$key]['rowspans'] = array();
12043                     if (!$this->empty_string($dom[$key]['thead'])) {
12044                         
12045                         $this->thead = $dom[$key]['thead'];
12046                     }
12047                     if (isset($tag['attribute']['cellpadding'])) {
12048                         $cp = $this->getHTMLUnitToUnits($tag['attribute']['cellpadding'], 1, 'px');
12049                         $this->oldcMargin = $this->cMargin;
12050                         $this->cMargin = $cp;
12051                     }
12052                     if (isset($tag['attribute']['cellspacing'])) {
12053                         $cs = $this->getHTMLUnitToUnits($tag['attribute']['cellspacing'], 1, 'px');
12054                     }
12055                     $this->checkPageBreak((2 * $cp) + (2 * $cs) + $this->lasth);
12056                     break;
12057                 }
12058                 case 'tr': {
12059                     
12060                     $dom[$key]['cellpos'] = array();
12061                     break;
12062                 }
12063                 case 'hr': {
12064                     $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
12065                     $this->htmlvspace = 0;
12066                     $wtmp = $this->w - $this->lMargin - $this->rMargin;
12067                     if ((isset($tag['attribute']['width'])) AND ($tag['attribute']['width'] != '')) {
12068                         $hrWidth = $this->getHTMLUnitToUnits($tag['attribute']['width'], $wtmp, 'px');
12069                     } else {
12070                         $hrWidth = $wtmp;
12071                     }
12072                     $x = $this->GetX();
12073                     $y = $this->GetY();
12074                     $prevlinewidth = $this->GetLineWidth();
12075                     $this->Line($x, $y, $x + $hrWidth, $y);
12076                     $this->SetLineWidth($prevlinewidth);
12077                     $this->addHTMLVertSpace(1, $cell, '', !isset($dom[($key + 1)]), $tag['value'], false);
12078                     break;
12079                 }
12080                 case 'a': {
12081                     if (array_key_exists('href', $tag['attribute'])) {
12082                         $this->HREF['url'] = $tag['attribute']['href'];
12083                     }
12084                     $this->HREF['color'] = $this->htmlLinkColorArray;
12085                     $this->HREF['style'] = $this->htmlLinkFontStyle;
12086                     if (array_key_exists('style', $tag['attribute'])) {
12087                         
12088                         preg_match_all('/([^;:\s]*):([^;]*)/', $tag['attribute']['style'], $style_array, PREG_PATTERN_ORDER);
12089                         $astyle = array();
12090                         while (list($id, $name) = each($style_array[1])) {
12091                             $name = strtolower($name);
12092                             $astyle[$name] = trim($style_array[2][$id]);
12093                         }
12094                         if (isset($astyle['color'])) {
12095                             $this->HREF['color'] = $this->convertHTMLColorToDec($astyle['color']);
12096                         }
12097                         if (isset($astyle['text-decoration'])) {
12098                             $this->HREF['style'] = '';
12099                             $decors = explode(' ', strtolower($astyle['text-decoration']));
12100                             foreach ($decors as $dec) {
12101                                 $dec = trim($dec);
12102                                 if (!$this->empty_string($dec)) {
12103                                     if ($dec{0} == 'u') {
12104                                         $this->HREF['style'] .= 'U';
12105                                     } elseif ($dec{0} == 'l') {
12106                                         $this->HREF['style'] .= 'D';
12107                                     }
12108                                 }
12109                             }
12110                         }
12111                     }       
12112                     break;
12113                 }
12114                 case 'img': {
12115                     if (isset($tag['attribute']['src'])) {
12116                         
12117                         if ($tag['attribute']['src'][0] == '/') {
12118                             $tag['attribute']['src'] = $_SERVER['DOCUMENT_ROOT'].$tag['attribute']['src'];
12119                         }
12120                         $tag['attribute']['src'] = urldecode($tag['attribute']['src']);
12121                         $tag['attribute']['src'] = str_replace(K_PATH_URL, K_PATH_MAIN, $tag['attribute']['src']);
12122                         if (!isset($tag['attribute']['width'])) {
12123                             $tag['attribute']['width'] = 0;
12124                         }
12125                         if (!isset($tag['attribute']['height'])) {
12126                             $tag['attribute']['height'] = 0;
12127                         }
12128                         
12129                             
12130                             
12131                             $tag['attribute']['align'] = 'bottom';
12132                         
12133                         switch($tag['attribute']['align']) {
12134                             case 'top': {
12135                                 $align = 'T';
12136                                 break;
12137                             }
12138                             case 'middle': {
12139                                 $align = 'M';
12140                                 break;
12141                             }
12142                             case 'bottom': {
12143                                 $align = 'B';
12144                                 break;
12145                             }
12146                             default: {
12147                                 $align = 'B';
12148                                 break;
12149                             }
12150                         }
12151                         $fileinfo = pathinfo($tag['attribute']['src']);
12152                         if (isset($fileinfo['extension']) AND (!$this->empty_string($fileinfo['extension']))) {
12153                             $type = strtolower($fileinfo['extension']);
12154                         }
12155                         $prevy = $this->y;
12156                         $xpos = $this->GetX();
12157                         if (isset($dom[($key - 1)]) AND ($dom[($key - 1)]['value'] == ' ')) {
12158                             if ($this->rtl) {
12159                                 $xpos += $this->GetStringWidth(' ');
12160                             } else {
12161                                 $xpos -= $this->GetStringWidth(' ');
12162                             }
12163                         }
12164                         $imglink = '';
12165                         if (isset($this->HREF['url']) AND !$this->empty_string($this->HREF['url'])) {
12166                             $imglink = $this->HREF['url'];
12167                             if ($imglink{0} == '#') {
12168                                 
12169                                 $page = intval(substr($imglink, 1));
12170                                 $imglink = $this->AddLink();
12171                                 $this->SetLink($imglink, 0, $page);
12172                             }
12173                         }
12174                         $border = 0;
12175                         if (isset($tag['attribute']['border']) AND !empty($tag['attribute']['border'])) {
12176                             
12177                             $border = $tag['attribute']['border'];
12178                         }
12179                         if (isset($tag['attribute']['width'])) {
12180                             $iw = $this->getHTMLUnitToUnits($tag['attribute']['width'], 1, 'px', false);
12181                         }
12182                         if (isset($tag['attribute']['height'])) {
12183                             $ih = $this->getHTMLUnitToUnits($tag['attribute']['height'], 1, 'px', false);
12184                         }
12185                         if (($type == 'eps') OR ($type == 'ai')) {
12186                             $this->ImageEps($tag['attribute']['src'], $xpos, $this->GetY(), $iw, $ih, $imglink, true, $align, '', $border);
12187                         } else {
12188                             $this->Image($tag['attribute']['src'], $xpos, $this->GetY(), $iw, $ih, '', $imglink, $align, false, 300, '', false, false, $border);
12189                         }
12190                         switch($align) {
12191                             case 'T': {
12192                                 $this->y = $prevy;
12193                                 break;
12194                             }
12195                             case 'M': {
12196                                 $this->y = (($this->img_rb_y + $prevy - ($tag['fontsize'] / $this->k)) / 2) ;
12197                                 break;
12198                             }
12199                             case 'B': {
12200                                 $this->y = $this->img_rb_y - ($tag['fontsize'] / $this->k);
12201                                 break;
12202                             }
12203                         }
12204                     }
12205                     break;
12206                 }
12207                 case 'dl': {
12208                     ++$this->listnum;
12209                     $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], false);
12210                     break;
12211                 }
12212                 case 'dt': {
12213                     $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
12214                     break;
12215                 }
12216                 case 'dd': {
12217                     if ($this->rtl) {
12218                         $this->rMargin += $this->listindent;
12219                     } else {
12220                         $this->lMargin += $this->listindent;
12221                     }
12222                     $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
12223                     break;
12224                 }
12225                 case 'ul':
12226                 case 'ol': {
12227                     $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], false);
12228                     $this->htmlvspace = 0;
12229                     ++$this->listnum;
12230                     if ($tag['value'] == 'ol') {
12231                         $this->listordered[$this->listnum] = true;
12232                     } else {
12233                         $this->listordered[$this->listnum] = false;
12234                     }
12235                     if (isset($tag['attribute']['start'])) {
12236                         $this->listcount[$this->listnum] = intval($tag['attribute']['start']) - 1;
12237                     } else {
12238                         $this->listcount[$this->listnum] = 0;
12239                     }
12240                     if ($this->rtl) {
12241                         $this->rMargin += $this->listindent;
12242                     } else {
12243                         $this->lMargin += $this->listindent;
12244                     }
12245                     $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], false);
12246                     $this->htmlvspace = 0;
12247                     break;
12248                 }
12249                 case 'li': {
12250                     $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
12251                     if ($this->listordered[$this->listnum]) {
12252                         
12253                         if (isset($parent['attribute']['type']) AND !$this->empty_string($parent['attribute']['type'])) {
12254                             $this->lispacer = $parent['attribute']['type'];
12255                         } elseif (isset($parent['listtype']) AND !$this->empty_string($parent['listtype'])) {
12256                             $this->lispacer = $parent['listtype'];
12257                         } elseif (isset($this->lisymbol) AND !$this->empty_string($this->lisymbol)) {
12258                             $this->lispacer = $this->lisymbol;
12259                         } else {
12260                             $this->lispacer = '#';
12261                         }
12262                         ++$this->listcount[$this->listnum];
12263                         if (isset($tag['attribute']['value'])) {
12264                             $this->listcount[$this->listnum] = intval($tag['attribute']['value']);
12265                         }
12266                     } else {
12267                         
12268                         if (isset($parent['attribute']['type']) AND !$this->empty_string($parent['attribute']['type'])) {
12269                             $this->lispacer = $parent['attribute']['type'];
12270                         } elseif (isset($parent['listtype']) AND !$this->empty_string($parent['listtype'])) {
12271                             $this->lispacer = $parent['listtype'];
12272                         } elseif (isset($this->lisymbol) AND !$this->empty_string($this->lisymbol)) {
12273                             $this->lispacer = $this->lisymbol;
12274                         } else {
12275                             $this->lispacer = '!';
12276                         }
12277                     }
12278                     break;
12279                 }
12280                 case 'blockquote': {
12281                     if ($this->rtl) {
12282                         $this->rMargin += $this->listindent;
12283                     } else {
12284                         $this->lMargin += $this->listindent;
12285                     }
12286                     $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], false);
12287                     break;
12288                 }
12289                 case 'br': {
12290                     $this->Ln('', $cell);
12291                     break;
12292                 }
12293                 case 'div': {
12294                     $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
12295                     break;
12296                 }
12297                 case 'p': {
12298                     $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], false);
12299                     break;
12300                 }
12301                 case 'pre': {
12302                     $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
12303                     $this->premode = true;
12304                     break;
12305                 }
12306                 case 'sup': {
12307                     $this->SetXY($this->GetX(), $this->GetY() - ((0.7 * $this->FontSizePt) / $this->k));
12308                     break;
12309                 }
12310                 case 'sub': {
12311                     $this->SetXY($this->GetX(), $this->GetY() + ((0.3 * $this->FontSizePt) / $this->k));
12312                     break;
12313                 }
12314                 case 'h1': 
12315                 case 'h2': 
12316                 case 'h3': 
12317                 case 'h4': 
12318                 case 'h5': 
12319                 case 'h6': {
12320                     $this->addHTMLVertSpace(1, $cell, ($tag['fontsize'] * 1.5) / $this->k, $firstorlast, $tag['value'], false);
12321                     break;
12322                 }
12323                 case 'tcpdf': {
12324                     
12325                     if (isset($tag['attribute']['method'])) {
12326                         $tcpdf_method = $tag['attribute']['method'];
12327                         if (method_exists($this, $tcpdf_method)) {
12328                             if (isset($tag['attribute']['params']) AND (!empty($tag['attribute']['params']))) {
12329                                 eval('$params = array('.$tag['attribute']['params'].');');
12330                                 call_user_func_array(array($this, $tcpdf_method), $params);
12331                             } else {
12332                                 $this->$tcpdf_method();
12333                             }
12334                             $this->newline = true;
12335                         }
12336                     }
12337                 }
12338                 default: {
12339                     break;
12340                 }
12341             }
12342         }
12343         
12351         protected function closeHTMLTagHandler(&$dom, $key, $cell=false) {
12352             $tag = $dom[$key];
12353             $parent = $dom[($dom[$key]['parent'])];
12354             $firstorlast = ((!isset($dom[($key + 1)])) OR ((!isset($dom[($key + 2)])) AND ($dom[($key + 1)]['value'] == 'marker')));
12355             
12356             switch($tag['value']) {
12357                 case 'tr': {
12358                     $table_el = $dom[($dom[$key]['parent'])]['parent'];
12359                     if(!isset($parent['endy'])) {
12360                         $dom[($dom[$key]['parent'])]['endy'] = $this->y;
12361                         $parent['endy'] = $this->y;
12362                     }
12363                     if(!isset($parent['endpage'])) {
12364                         $dom[($dom[$key]['parent'])]['endpage'] = $this->page;
12365                         $parent['endpage'] = $this->page;
12366                     }
12367                     
12368                     if (isset($dom[$table_el]['rowspans'])) {
12369                         foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
12370                             $dom[$table_el]['rowspans'][$k]['rowspan'] -= 1;
12371                             if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) {
12372                                 if ($dom[$table_el]['rowspans'][$k]['endpage'] == $parent['endpage']) {
12373                                     $dom[($dom[$key]['parent'])]['endy'] = max($dom[$table_el]['rowspans'][$k]['endy'], $parent['endy']);
12374                                 } elseif ($dom[$table_el]['rowspans'][$k]['endpage'] > $parent['endpage']) {
12375                                     $dom[($dom[$key]['parent'])]['endy'] = $dom[$table_el]['rowspans'][$k]['endy'];
12376                                     $dom[($dom[$key]['parent'])]['endpage'] = $dom[$table_el]['rowspans'][$k]['endpage'];
12377                                 }
12378                             }
12379                         }
12380                         
12381                         foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
12382                             if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) {
12383                                 $dom[$table_el]['rowspans'][$k]['endpage'] = max($dom[$table_el]['rowspans'][$k]['endpage'], $dom[($dom[$key]['parent'])]['endpage']);
12384                                 $dom[($dom[$key]['parent'])]['endpage'] = $dom[$table_el]['rowspans'][$k]['endpage'];
12385                                 $dom[$table_el]['rowspans'][$k]['endy'] = max($dom[$table_el]['rowspans'][$k]['endy'], $dom[($dom[$key]['parent'])]['endy']);
12386                                 $dom[($dom[$key]['parent'])]['endy'] = $dom[$table_el]['rowspans'][$k]['endy'];
12387                             }
12388                         }
12389                         
12390                         foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
12391                             if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) {
12392                                 $dom[$table_el]['rowspans'][$k]['endpage'] = $dom[($dom[$key]['parent'])]['endpage'];
12393                                 $dom[$table_el]['rowspans'][$k]['endy'] = $dom[($dom[$key]['parent'])]['endy'];
12394                             }
12395                         }
12396                     }
12397                     $this->setPage($dom[($dom[$key]['parent'])]['endpage']);
12398                     $this->y = $dom[($dom[$key]['parent'])]['endy'];                    
12399                     if (isset($dom[$table_el]['attribute']['cellspacing'])) {
12400                         $cellspacing = $this->getHTMLUnitToUnits($dom[$table_el]['attribute']['cellspacing'], 1, 'px');
12401                         $this->y += $cellspacing;
12402                     }               
12403                     $this->Ln(0, $cell);
12404                     $this->x = $parent['startx'];
12405                     
12406                     if ($this->page > $parent['startpage']) {
12407                         if (($this->rtl) AND ($this->pagedim[$this->page]['orm'] != $this->pagedim[$parent['startpage']]['orm'])) {
12408                             $this->x += ($this->pagedim[$this->page]['orm'] - $this->pagedim[$parent['startpage']]['orm']);
12409                         } elseif ((!$this->rtl) AND ($this->pagedim[$this->page]['olm'] != $this->pagedim[$parent['startpage']]['olm'])) {
12410                             $this->x += ($this->pagedim[$this->page]['olm'] - $this->pagedim[$parent['startpage']]['olm']);
12411                         }
12412                     }
12413                     break;
12414                 }
12415                 case 'table': {
12416                     
12417                     $table_el = $parent;
12418                     if ((isset($table_el['attribute']['border']) AND ($table_el['attribute']['border'] > 0)) 
12419                         OR (isset($table_el['style']['border']) AND ($table_el['style']['border'] > 0))) {
12420                             $border = 1;
12421                     } else {
12422                         $border = 0;
12423                     }
12424                     
12425                     foreach ($dom[($dom[$key]['parent'])]['trids'] as $j => $trkey) {
12426                         
12427                         if (isset($dom[($dom[$key]['parent'])]['rowspans'])) {
12428                             foreach ($dom[($dom[$key]['parent'])]['rowspans'] as $k => $trwsp) {
12429                                 if ($trwsp['trid'] == $trkey) {
12430                                     $dom[($dom[$key]['parent'])]['rowspans'][$k]['mrowspan'] -= 1;
12431                                 }
12432                                 if (isset($prevtrkey) AND ($trwsp['trid'] == $prevtrkey) AND ($trwsp['mrowspan'] >= 0)) {
12433                                     $dom[($dom[$key]['parent'])]['rowspans'][$k]['trid'] = $trkey;
12434                                 }
12435                             }
12436                         }
12437                         if (isset($prevtrkey) AND ($dom[$trkey]['startpage'] > $dom[$prevtrkey]['endpage'])) {
12438                             $pgendy = $this->pagedim[$dom[$prevtrkey]['endpage']]['hk'] - $this->pagedim[$dom[$prevtrkey]['endpage']]['bm'];
12439                             $dom[$prevtrkey]['endy'] = $pgendy;
12440                             
12441                             if (isset($dom[($dom[$key]['parent'])]['rowspans'])) {
12442                                 foreach ($dom[($dom[$key]['parent'])]['rowspans'] as $k => $trwsp) {
12443                                     if (($trwsp['trid'] == $trkey) AND ($trwsp['mrowspan'] == 1) AND ($trwsp['endpage'] == $dom[$prevtrkey]['endpage'])) {
12444                                         $dom[($dom[$key]['parent'])]['rowspans'][$k]['endy'] = $pgendy;
12445                                         $dom[($dom[$key]['parent'])]['rowspans'][$k]['mrowspan'] = -1;
12446                                     }
12447                                 }
12448                             }
12449                         }
12450                         $prevtrkey = $trkey;
12451                         $table_el = $dom[($dom[$key]['parent'])];
12452                     }
12453                     
12454                     foreach ($table_el['trids'] as $j => $trkey) {
12455                         $parent = $dom[$trkey];
12456                         
12457                         foreach ($parent['cellpos'] as $k => $cellpos) {
12458                             if (isset($cellpos['rowspanid']) AND ($cellpos['rowspanid'] >= 0)) {
12459                                 $cellpos['startx'] = $table_el['rowspans'][($cellpos['rowspanid'])]['startx'];
12460                                 $cellpos['endx'] = $table_el['rowspans'][($cellpos['rowspanid'])]['endx'];
12461                                 $endy = $table_el['rowspans'][($cellpos['rowspanid'])]['endy'];
12462                                 $startpage = $table_el['rowspans'][($cellpos['rowspanid'])]['startpage'];
12463                                 $endpage = $table_el['rowspans'][($cellpos['rowspanid'])]['endpage'];
12464                             } else {
12465                                 $endy = $parent['endy'];
12466                                 $startpage = $parent['startpage'];
12467                                 $endpage = $parent['endpage'];
12468                             }
12469                             if ($endpage > $startpage) {
12470                                 
12471                                 for ($page=$startpage; $page <= $endpage; ++$page) {
12472                                     $this->setPage($page);
12473                                     if ($page == $startpage) {
12474                                         $this->y = $parent['starty']; 
12475                                         $ch = $this->getPageHeight() - $parent['starty'] - $this->getBreakMargin();
12476                                         $cborder = $this->getBorderMode($border, $position='start');
12477                                     } elseif ($page == $endpage) {
12478                                         $this->y = $this->tMargin; 
12479                                         $ch = $endy - $this->tMargin;
12480                                         $cborder = $this->getBorderMode($border, $position='end');
12481                                     } else {
12482                                         $this->y = $this->tMargin; 
12483                                         $ch = $this->getPageHeight() - $this->tMargin - $this->getBreakMargin();
12484                                         $cborder = $this->getBorderMode($border, $position='middle');
12485                                     }
12486                                     if (isset($cellpos['bgcolor']) AND ($cellpos['bgcolor']) !== false) {
12487                                         $this->SetFillColorArray($cellpos['bgcolor']);
12488                                         $fill = true;
12489                                     } else {
12490                                         $fill = false;
12491                                     }
12492                                     $cw = abs($cellpos['endx'] - $cellpos['startx']);
12493                                     $this->x = $cellpos['startx'];
12494                                     
12495                                     if ($page > $startpage) {
12496                                         if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) {
12497                                             $this->x -= ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']);
12498                                         } elseif ((!$this->rtl) AND ($this->pagedim[$page]['lm'] != $this->pagedim[$startpage]['olm'])) {
12499                                             $this->x += ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']);
12500                                         }
12501                                     }
12502                                     
12503                                     $ccode = $this->FillColor."\n".$this->getCellCode($cw, $ch, '', $cborder, 1, '', $fill, '', 0, true);
12504                                     if ($cborder OR $fill) {
12505                                         $pagebuff = $this->getPageBuffer($this->page);
12506                                         $pstart = substr($pagebuff, 0, $this->intmrk[$this->page]);
12507                                         $pend = substr($pagebuff, $this->intmrk[$this->page]);
12508                                         $this->setPageBuffer($this->page, $pstart.$ccode."\n".$pend);
12509                                         $this->intmrk[$this->page] += strlen($ccode."\n");
12510                                     }
12511                                 }
12512                             } else {
12513                                 $this->setPage($startpage);
12514                                 if (isset($cellpos['bgcolor']) AND ($cellpos['bgcolor']) !== false) {
12515                                     $this->SetFillColorArray($cellpos['bgcolor']);
12516                                     $fill = true;
12517                                 } else {
12518                                     $fill = false;
12519                                 }
12520                                 $this->x = $cellpos['startx'];
12521                                 $this->y = $parent['starty'];
12522                                 $cw = abs($cellpos['endx'] - $cellpos['startx']);
12523                                 $ch = $endy - $parent['starty'];
12524                                 
12525                                 $ccode = $this->FillColor."\n".$this->getCellCode($cw, $ch, '', $border, 1, '', $fill, '', 0, true);
12526                                 if ($border OR $fill) {
12527                                     if (end($this->transfmrk[$this->page]) !== false) {
12528                                         $pagemarkkey = key($this->transfmrk[$this->page]);
12529                                         $pagemark = &$this->transfmrk[$this->page][$pagemarkkey];
12530                                     } elseif ($this->InFooter) {
12531                                         $pagemark = &$this->footerpos[$this->page];
12532                                     } else {
12533                                         $pagemark = &$this->intmrk[$this->page];
12534                                     }
12535                                     $pagebuff = $this->getPageBuffer($this->page);
12536                                     $pstart = substr($pagebuff, 0, $pagemark);
12537                                     $pend = substr($pagebuff, $pagemark);
12538                                     $this->setPageBuffer($this->page, $pstart.$ccode."\n".$pend);
12539                                     $pagemark += strlen($ccode."\n");
12540                                 }                   
12541                             }
12542                         }                   
12543                         if (isset($table_el['attribute']['cellspacing'])) {
12544                             $cellspacing = $this->getHTMLUnitToUnits($table_el['attribute']['cellspacing'], 1, 'px');
12545                             $this->y += $cellspacing;
12546                         }               
12547                         $this->Ln(0, $cell);
12548                         $this->x = $parent['startx'];
12549                         if ($endpage > $startpage) {
12550                             if (($this->rtl) AND ($this->pagedim[$endpage]['orm'] != $this->pagedim[$startpage]['orm'])) {
12551                                 $this->x += ($this->pagedim[$endpage]['orm'] - $this->pagedim[$startpage]['orm']);
12552                             } elseif ((!$this->rtl) AND ($this->pagedim[$endpage]['olm'] != $this->pagedim[$startpage]['olm'])) {
12553                                 $this->x += ($this->pagedim[$endpage]['olm'] - $this->pagedim[$startpage]['olm']);
12554                             }
12555                         }
12556                     }
12557                     if (isset($parent['cellpadding'])) {
12558                         $this->cMargin = $this->oldcMargin;
12559                     }
12560                     $this->lasth = $this->FontSize * $this->cell_height_ratio;
12561                     if (!$this->empty_string($this->theadMargin)) {
12562                         
12563                         $this->tMargin = $this->theadMargin;
12564                         $this->pagedim[$this->page]['tm'] = $this->theadMargin;
12565                     }
12566                     
12567                     $this->thead = '';
12568                     $this->theadMargin = '';
12569                     break;
12570                 }
12571                 case 'a': {
12572                     $this->HREF = '';
12573                     break;
12574                 }
12575                 case 'sup': {
12576                     $this->SetXY($this->GetX(), $this->GetY() + ((0.7 * $parent['fontsize']) / $this->k));
12577                     break;
12578                 }
12579                 case 'sub': {
12580                     $this->SetXY($this->GetX(), $this->GetY() - ((0.3 * $parent['fontsize'])/$this->k));
12581                     break;
12582                 }
12583                 case 'div': {
12584                     $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], true);
12585                     break;
12586                 }
12587                 case 'blockquote': {
12588                     if ($this->rtl) {
12589                         $this->rMargin -= $this->listindent;
12590                     } else {
12591                         $this->lMargin -= $this->listindent;
12592                     }
12593                     $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], true);
12594                     break;
12595                 }
12596                 case 'p': {
12597                     $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], true);
12598                     break;
12599                 }
12600                 case 'pre': {
12601                     $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], true);
12602                     $this->premode = false;
12603                     break;
12604                 }
12605                 case 'dl': {
12606                     --$this->listnum;
12607                     if ($this->listnum <= 0) {
12608                         $this->listnum = 0;
12609                         $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], true);
12610                     }
12611                     break;
12612                 }
12613                 case 'dt': {
12614                     $this->lispacer = '';
12615                     $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], true);
12616                     break;
12617                 }
12618                 case 'dd': {
12619                     $this->lispacer = '';
12620                     if ($this->rtl) {
12621                         $this->rMargin -= $this->listindent;
12622                     } else {
12623                         $this->lMargin -= $this->listindent;
12624                     }
12625                     $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], true);
12626                     break;
12627                 }
12628                 case 'ul':
12629                 case 'ol': {
12630                     --$this->listnum;
12631                     $this->lispacer = '';
12632                     if ($this->rtl) {
12633                         $this->rMargin -= $this->listindent;
12634                     } else {
12635                         $this->lMargin -= $this->listindent;
12636                     }
12637                     if ($this->listnum <= 0) {
12638                         $this->listnum = 0;
12639                         $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], true);
12640                     }
12641                     $this->lasth = $this->FontSize * $this->cell_height_ratio;
12642                     break;
12643                 }
12644                 case 'li': {
12645                     $this->lispacer = '';
12646                     $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], true);
12647                     break;
12648                 }
12649                 case 'h1': 
12650                 case 'h2': 
12651                 case 'h3': 
12652                 case 'h4': 
12653                 case 'h5': 
12654                 case 'h6': {
12655                     $this->addHTMLVertSpace(1, $cell, ($parent['fontsize'] * 1.5) / $this->k, $firstorlast, $tag['value'], true);
12656                     break;
12657                 }
12658                 default : {
12659                     break;
12660                 }
12661             }
12662             $this->tmprtl = false;
12663         }
12664         
12675         protected function addHTMLVertSpace($n, $cell=false, $h='', $firstorlast=false, $tag='', $closing=false) {
12676             if ($firstorlast) {
12677                 $this->Ln(0, $cell);
12678                 $this->htmlvspace = 0;
12679                 return;
12680             }
12681             if (isset($this->tagvspaces[$tag][intval($closing)]['n'])) {
12682                 $n = $this->tagvspaces[$tag][intval($closing)]['n'];
12683             }
12684             if (isset($this->tagvspaces[$tag][intval($closing)]['h'])) {
12685                 $h = $this->tagvspaces[$tag][intval($closing)]['h'];
12686             }
12687             if (is_string($h)) {
12688                 $vsize = $n * $this->lasth;
12689             } else {
12690                 $vsize = $n * $h;
12691             }
12692             if ($vsize > $this->htmlvspace) {
12693                 $this->Ln(($vsize - $this->htmlvspace), $cell);
12694                 $this->htmlvspace = $vsize;
12695             }
12696         }
12697         
12704         public function setLIsymbol($symbol='!') {
12705             $symbol = strtolower($symbol);
12706             switch ($symbol) {
12707                 case '!' :
12708                 case '#' :
12709                 case 'disc' :
12710                 case 'disc' :
12711                 case 'circle' :
12712                 case 'square' :
12713                 case '1':
12714                 case 'decimal':
12715                 case 'decimal-leading-zero':
12716                 case 'i':
12717                 case 'lower-roman':
12718                 case 'I':
12719                 case 'upper-roman':
12720                 case 'a':
12721                 case 'lower-alpha':
12722                 case 'lower-latin':
12723                 case 'A':
12724                 case 'upper-alpha':
12725                 case 'upper-latin':
12726                 case 'lower-greek': {
12727                     $this->lisymbol = $symbol;
12728                     break;
12729                 }
12730                 default : {
12731                     $this->lisymbol = '';
12732                 }
12733             }
12734         }
12735         
12744         public function SetBooklet($booklet=true, $inner=-1, $outer=-1) {
12745             $this->booklet = $booklet;
12746             if ($inner >= 0) {
12747                 $this->lMargin = $inner;
12748             }
12749             if ($outer >= 0) {
12750                 $this->rMargin = $outer;
12751             }
12752         }
12753         
12760         protected function swapMargins($reverse=true) {
12761             if ($reverse) {
12762                 
12763                 $mtemp = $this->original_lMargin;
12764                 $this->original_lMargin = $this->original_rMargin;
12765                 $this->original_rMargin = $mtemp;
12766                 $deltam = $this->original_lMargin - $this->original_rMargin;
12767                 $this->lMargin += $deltam;
12768                 $this->rMargin -= $deltam;
12769             }
12770         }
12771 
12784         public function setHtmlVSpace($tagvs) {
12785             $this->tagvspaces = $tagvs;
12786         }
12787 
12794         public function setListIndentWidth($width) {
12795             return $this->customlistindent = floatval($width);
12796         }
12797 
12804         public function setOpenCell($isopen) {
12805             $this->opencell = $isopen;
12806         }
12807 
12815         public function setHtmlLinksStyle($color=array(0,0,255), $fontstyle='U') {
12816             $this->htmlLinkColorArray = $color;
12817             $this->htmlLinkFontStyle = $fontstyle;
12818         }
12819 
12830         public function getHTMLUnitToUnits($htmlval, $refsize=1, $defaultunit='px', $points=false) {
12831             $supportedunits = array('%', 'em', 'ex', 'px', 'in', 'cm', 'mm', 'pc', 'pt');
12832             $retval = 0;
12833             $value = 0;
12834             $unit = 'px';
12835             $k = $this->k;
12836             if ($points) {
12837                 $k = 1;
12838             }
12839             if (in_array($defaultunit, $supportedunits)) {
12840                 $unit = $defaultunit;
12841             }
12842             if (is_numeric($htmlval)) {
12843                 $value = floatval($htmlval);
12844             } elseif (preg_match('/([0-9\.]+)/', $htmlval, $mnum)) {
12845                 $value = floatval($mnum[1]);
12846                 if (preg_match('/([a-z%]+)/', $htmlval, $munit)) {
12847                     if (in_array($munit[1], $supportedunits)) {
12848                         $unit = $munit[1];
12849                     }
12850                 }
12851             }
12852             switch ($unit) {
12853                 
12854                 case '%': {
12855                     $retval = (($value * $refsize) / 100);
12856                     break;
12857                 }
12858                 
12859                 case 'em': {
12860                     $retval = ($value * $refsize);
12861                     break;
12862                 }
12863                 case 'ex': {
12864                     $retval = $value * ($refsize / 2);
12865                     break;
12866                 }
12867                 
12868                 case 'in': {
12869                     $retval = ($value * $this->dpi) / $k;
12870                     break;
12871                 }
12872                 case 'cm': {
12873                     $retval = ($value / 2.54 * $this->dpi) / $k;
12874                     break;
12875                 }
12876                 case 'mm': {
12877                     $retval = ($value / 25.4 * $this->dpi) / $k;
12878                     break;
12879                 }
12880                 case 'pc': {
12881                     
12882                     $retval = ($value * 12) / $k;
12883                     break;
12884                 }
12885                 case 'pt': {
12886                     $retval = $value / $k;
12887                     break;
12888                 }
12889                 case 'px': {
12890                     $retval = $this->pixelsToUnits($value);
12891                     break;
12892                 }
12893             }
12894             return $retval;
12895         }
12896 
12904         public function intToRoman($number) {
12905             $roman = '';
12906             while ($number >= 1000) {
12907                 $roman .= 'M';
12908                 $number -= 1000;
12909             }
12910             while ($number >= 900) {
12911                 $roman .= 'CM';
12912                 $number -= 900;
12913             }
12914             while ($number >= 500) {
12915                 $roman .= 'D';
12916                 $number -= 500;
12917             }
12918             while ($number >= 400) {
12919                 $roman .= 'CD';
12920                 $number -= 400;
12921             }
12922             while ($number >= 100) {
12923                 $roman .= 'C';
12924                 $number -= 100;
12925             }
12926             while ($number >= 90) {
12927             $roman .= 'XC';
12928             $number -= 90;
12929             }
12930             while ($number >= 50) {
12931                 $roman .= 'L';
12932                 $number -= 50;
12933             }
12934             while ($number >= 40) {
12935                 $roman .= 'XL';
12936                 $number -= 40;
12937             }
12938             while ($number >= 10) {
12939             $roman .= 'X';
12940             $number -= 10;
12941             }
12942             while ($number >= 9) {
12943                 $roman .= 'IX';
12944                 $number -= 9;
12945             }
12946             while ($number >= 5) {
12947                 $roman .= 'V';
12948                 $number -= 5;
12949             }
12950             while ($number >= 4) {
12951             $roman .= 'IV';
12952             $number -= 4;
12953             }
12954             while ($number >= 1) {
12955                 $roman .= 'I';
12956                 --$number;
12957             }
12958             return $roman;
12959         }
12960 
12969         protected function putHtmlListBullet($listdepth, $listtype='', $size=10) {
12970             $size /= $this->k;
12971             $fill = '';
12972             $color = $this->fgcolor;
12973             $width = 0;
12974             $textitem = '';
12975             $tmpx = $this->x;       
12976             $lspace = $this->GetStringWidth('  ');
12977             if ($listtype == '!') {
12978                 
12979                 $deftypes = array('disc', 'circle', 'square');
12980                 $listtype = $deftypes[($listdepth - 1) % 3];
12981             } elseif ($listtype == '#') {
12982                 
12983                 $listtype = 'decimal';
12984             }
12985             switch ($listtype) {
12986                 
12987                 case 'none': {
12988                     break;
12989                 }
12990                 case 'disc': {
12991                     $fill = 'F';
12992                 }
12993                 case 'circle': {
12994                     $fill .= 'D';
12995                     $r = $size / 6;
12996                     $lspace += (2 * $r);
12997                     if ($this->rtl) {
12998                         $this->x += $lspace;
12999                     } else {
13000                         $this->x -= $lspace;
13001                     }
13002                     $this->Circle(($this->x + $r), ($this->y + ($this->lasth / 2)), $r, 0, 360, $fill, array('color'=>$color), $color, 8);
13003                     break;
13004                 }
13005                 case 'square': {
13006                     $l = $size / 3;
13007                     $lspace += $l;
13008                     if ($this->rtl) {
13009                         $this->x += $lspace;
13010                     } else {
13011                         $this->x -= $lspace;
13012                     }
13013                     $this->Rect($this->x, ($this->y + (($this->lasth - $l)/ 2)), $l, $l, 'F', array(), $color);
13014                     break;
13015                 }
13016                 
13017 
13018                 
13019                 
13020                 case '1':
13021                 case 'decimal': {
13022                     $textitem = $this->listcount[$this->listnum];
13023                     break;
13024                 }
13025                 case 'decimal-leading-zero': {
13026                     $textitem = sprintf("%02d", $this->listcount[$this->listnum]);
13027                     break;
13028                 }
13029                 case 'i':
13030                 case 'lower-roman': {
13031                     $textitem = strtolower($this->intToRoman($this->listcount[$this->listnum]));
13032                     break;
13033                 }
13034                 case 'I':
13035                 case 'upper-roman': {
13036                     $textitem = $this->intToRoman($this->listcount[$this->listnum]);
13037                     break;
13038                 }
13039                 case 'a':
13040                 case 'lower-alpha':
13041                 case 'lower-latin': {
13042                     $textitem = chr(97 + $this->listcount[$this->listnum] - 1);
13043                     break;
13044                 }
13045                 case 'A':
13046                 case 'upper-alpha':
13047                 case 'upper-latin': {
13048                     $textitem = chr(65 + $this->listcount[$this->listnum] - 1);
13049                     break;
13050                 }
13051                 case 'lower-greek': {
13052                     $textitem = $this->unichr(945 + $this->listcount[$this->listnum] - 1);
13053                     break;
13054                 }
13055                 
13056 
13057 
13058 
13059 
13060 
13061 
13062 
13063 
13064 
13065 
13066 
13067 
13068 
13069 
13070 
13071 
13072 
13073 
13074 
13075 
13076 
13077 
13078 
13079 
13080 
13081 
13082                 default: {
13083                     $textitem = $this->listcount[$this->listnum];
13084                 }
13085             }
13086             if (!$this->empty_string($textitem)) {
13087                 
13088                 if ($this->rtl) {
13089                     $textitem = '.'.$textitem;
13090                 } else {
13091                     $textitem = $textitem.'.';
13092                 }
13093                 $lspace += $this->GetStringWidth($textitem);
13094                 if ($this->rtl) {
13095                     $this->x += $lspace;
13096                 } else {
13097                     $this->x -= $lspace;
13098                 }
13099                 $this->Write($this->lasth, $textitem, '', false, '', false, 0, false);
13100             }
13101             $this->x = $tmpx;
13102             $this->lispacer = '';
13103         }
13104 
13111         protected function getGraphicVars() {
13112             $grapvars = array(
13113                 'FontFamily' => $this->FontFamily,
13114                 'FontStyle' => $this->FontStyle,
13115                 'FontSizePt' => $this->FontSizePt,
13116                 'rMargin' => $this->rMargin,
13117                 'lMargin' => $this->lMargin,
13118                 'cMargin' => $this->cMargin,
13119                 'LineWidth' => $this->LineWidth,
13120                 'linestyleWidth' => $this->linestyleWidth,
13121                 'linestyleCap' => $this->linestyleCap,
13122                 'linestyleJoin' => $this->linestyleJoin,
13123                 'linestyleDash' => $this->linestyleDash,
13124                 'DrawColor' => $this->DrawColor,
13125                 'FillColor' => $this->FillColor,
13126                 'TextColor' => $this->TextColor,
13127                 'ColorFlag' => $this->ColorFlag,
13128                 'bgcolor' => $this->bgcolor,
13129                 'fgcolor' => $this->fgcolor,
13130                 'htmlvspace' => $this->htmlvspace,
13131                 'lasth' => $this->lasth
13132                 );
13133             return $grapvars;
13134         }
13135 
13142         protected function setGraphicVars($gvars) {
13143             $this->FontFamily = $gvars['FontFamily'];
13144             $this->FontStyle = $gvars['FontStyle'];
13145             $this->FontSizePt = $gvars['FontSizePt'];
13146             $this->rMargin = $gvars['rMargin'];
13147             $this->lMargin = $gvars['lMargin'];
13148             $this->cMargin = $gvars['cMargin'];
13149             $this->LineWidth = $gvars['LineWidth'];
13150             $this->linestyleWidth = $gvars['linestyleWidth'];
13151             $this->linestyleCap = $gvars['linestyleCap'];
13152             $this->linestyleJoin = $gvars['linestyleJoin'];
13153             $this->linestyleDash = $gvars['linestyleDash'];
13154             $this->DrawColor = $gvars['DrawColor'];
13155             $this->FillColor = $gvars['FillColor'];
13156             $this->TextColor = $gvars['TextColor'];
13157             $this->ColorFlag = $gvars['ColorFlag'];
13158             $this->bgcolor = $gvars['bgcolor'];
13159             $this->fgcolor = $gvars['fgcolor'];
13160             $this->htmlvspace = $gvars['htmlvspace'];
13161             
13162             $this->_out(''.$this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor.' '.$this->FillColor.'');
13163             if (!$this->empty_string($this->FontFamily)) {
13164                 $this->SetFont($this->FontFamily, $this->FontStyle, $this->FontSizePt);
13165             }
13166         }
13167 
13175         protected function getObjFilename($name) {
13176             return tempnam(K_PATH_CACHE, $name.'_');
13177         }
13178 
13187         protected function writeDiskCache($filename, $data, $append=false) {
13188             if ($append) {
13189                 $fmode = 'ab+';
13190             } else {
13191                 $fmode = 'wb+';
13192             }
13193             $f = @fopen($filename, $fmode);
13194             if (!$f) {
13195                 $this->Error('Unable to write cache file: '.$filename);
13196             } else {
13197                 fwrite($f, $data);
13198                 fclose($f);
13199             }
13200             
13201             if (!isset($this->cache_file_lenght['_'.$filename])) {
13202                 $this->cache_file_lenght['_'.$filename] = strlen($data);
13203             } else {
13204                 $this->cache_file_lenght['_'.$filename] += strlen($data);
13205             }
13206         }
13207 
13215         protected function readDiskCache($filename) {
13216             return file_get_contents($filename);
13217         }
13218 
13225         protected function setBuffer($data) {
13226             $this->bufferlen += strlen($data);
13227             if ($this->diskcache) {
13228                 if (!isset($this->buffer) OR $this->empty_string($this->buffer)) {
13229                     $this->buffer = $this->getObjFilename('buffer');
13230                 }
13231                 $this->writeDiskCache($this->buffer, $data, true);
13232             } else {
13233                 $this->buffer .= $data;
13234             }
13235         }
13236 
13243         protected function getBuffer() {
13244             if ($this->diskcache) {
13245                 return $this->readDiskCache($this->buffer);
13246             } else {
13247                 return $this->buffer;
13248             }
13249         }
13250 
13259         protected function setPageBuffer($page, $data, $append=false) {
13260             if ($this->diskcache) {
13261                 if (!isset($this->pages[$page])) {
13262                     $this->pages[$page] = $this->getObjFilename('page'.$page);
13263                 }
13264                 $this->writeDiskCache($this->pages[$page], $data, $append);
13265             } else {
13266                 if ($append) {
13267                     $this->pages[$page] .= $data;
13268                 } else {
13269                     $this->pages[$page] = $data;
13270                 }
13271             }
13272             if ($append AND isset($this->pagelen[$page])) {
13273                 $this->pagelen[$page] += strlen($data);
13274             } else {
13275                 $this->pagelen[$page] = strlen($data);
13276             }
13277         }
13278 
13286         protected function getPageBuffer($page) {
13287             if ($this->diskcache) {
13288                 return $this->readDiskCache($this->pages[$page]);
13289             } elseif (isset($this->pages[$page])) {
13290                 return $this->pages[$page];
13291             }
13292             return false;
13293         }
13294 
13302         protected function setImageBuffer($image, $data) {
13303             if ($this->diskcache) {
13304                 if (!isset($this->images[$image])) {
13305                     $this->images[$image] = $this->getObjFilename('image'.$image);
13306                 }
13307                 $this->writeDiskCache($this->images[$image], serialize($data));
13308             } else {
13309                 $this->images[$image] = $data;
13310             }
13311             if (!in_array($image, $this->imagekeys)) {
13312                 $this->imagekeys[] = $image;
13313             }
13314             ++$this->numimages;
13315         }
13316 
13325         protected function setImageSubBuffer($image, $key, $data) {
13326             if (!isset($this->images[$image])) {
13327                 $this->setImageBuffer($image, array());
13328             }
13329             if ($this->diskcache) {
13330                 $tmpimg = $this->getImageBuffer($image);
13331                 $tmpimg[$key] = $data;
13332                 $this->writeDiskCache($this->images[$image], serialize($tmpimg));
13333             } else {
13334                 $this->images[$image][$key] = $data;
13335             }
13336         }
13337 
13345         protected function getImageBuffer($image) {
13346             if ($this->diskcache AND isset($this->images[$image])) {
13347                 return unserialize($this->readDiskCache($this->images[$image]));
13348             } elseif (isset($this->images[$image])) {
13349                 return $this->images[$image];
13350             }
13351             return false;
13352         }
13353 
13361         protected function setFontBuffer($font, $data) {
13362             if ($this->diskcache) {
13363                 if (!isset($this->fonts[$font])) {
13364                     $this->fonts[$font] = $this->getObjFilename('font');
13365                 }
13366                 $this->writeDiskCache($this->fonts[$font], serialize($data));
13367             } else {
13368                 $this->fonts[$font] = $data;
13369             }
13370             if (!in_array($font, $this->fontkeys)) {
13371                 $this->fontkeys[] = $font;
13372             }
13373         }
13374 
13383         protected function setFontSubBuffer($font, $key, $data) {
13384             if (!isset($this->fonts[$font])) {
13385                 $this->setFontBuffer($font, array());
13386             }
13387             if ($this->diskcache) {
13388                 $tmpfont = $this->getFontBuffer($font);
13389                 $tmpfont[$key] = $data;
13390                 $this->writeDiskCache($this->fonts[$font], serialize($tmpfont));
13391             } else {
13392                 $this->fonts[$font][$key] = $data;
13393             }
13394         }
13395 
13403         protected function getFontBuffer($font) {
13404             if ($this->diskcache AND isset($this->fonts[$font])) {
13405                 return unserialize($this->readDiskCache($this->fonts[$font]));
13406             } elseif (isset($this->fonts[$font])) {
13407                 return $this->fonts[$font];
13408             }
13409             return false;
13410         }
13411 
13420         public function movePage($frompage, $topage) {
13421             if (($frompage > $this->numpages) OR ($frompage <= $topage)) {
13422                 return false;
13423             }
13424             if ($frompage == $this->page) {
13425                 
13426                 $this->endPage();
13427             }
13428             
13429             $tmppage = $this->pages[$frompage];
13430             $tmppagedim = $this->pagedim[$frompage];
13431             $tmppagelen = $this->pagelen[$frompage];
13432             $tmpintmrk = $this->intmrk[$frompage];
13433             if (isset($this->footerpos[$frompage])) {
13434                 $tmpfooterpos = $this->footerpos[$frompage];
13435             }
13436             if (isset($this->footerlen[$frompage])) {
13437                 $tmpfooterlen = $this->footerlen[$frompage];
13438             }
13439             if (isset($this->transfmrk[$frompage])) {
13440                 $tmptransfmrk = $this->transfmrk[$frompage];
13441             }
13442             if (isset($this->PageAnnots[$frompage])) {
13443                 $tmpannots = $this->PageAnnots[$frompage];
13444             }
13445             if (isset($this->newpagegroup[$frompage])) {
13446                 $tmpnewpagegroup = $this->newpagegroup[$frompage];
13447             }
13448             for ($i = $frompage; $i > $topage; --$i) {
13449                 $j = $i - 1;
13450                 
13451                 $this->pages[$i] = $this->pages[$j];
13452                 $this->pagedim[$i] = $this->pagedim[$j];
13453                 $this->pagelen[$i] = $this->pagelen[$j];
13454                 $this->intmrk[$i] = $this->intmrk[$j];
13455                 if (isset($this->footerpos[$j])) {
13456                     $this->footerpos[$i] = $this->footerpos[$j];
13457                 } elseif (isset($this->footerpos[$i])) {
13458                     unset($this->footerpos[$i]);
13459                 }
13460                 if (isset($this->footerlen[$j])) {
13461                     $this->footerlen[$i] = $this->footerlen[$j];
13462                 } elseif (isset($this->footerlen[$i])) {
13463                     unset($this->footerlen[$i]);
13464                 }
13465                 if (isset($this->transfmrk[$j])) {
13466                     $this->transfmrk[$i] = $this->transfmrk[$j];
13467                 } elseif (isset($this->transfmrk[$i])) {
13468                     unset($this->transfmrk[$i]);
13469                 }
13470                 if (isset($this->PageAnnots[$j])) {
13471                     $this->PageAnnots[$i] = $this->PageAnnots[$j];
13472                 } elseif (isset($this->PageAnnots[$i])) {
13473                     unset($this->PageAnnots[$i]);
13474                 }
13475                 if (isset($this->newpagegroup[$j])) {
13476                     $this->newpagegroup[$i] = $this->newpagegroup[$j];
13477                 } elseif (isset($this->newpagegroup[$i])) {
13478                     unset($this->newpagegroup[$i]);
13479                 }
13480             }
13481             $this->pages[$topage] = $tmppage;
13482             $this->pagedim[$topage] = $tmppagedim;
13483             $this->pagelen[$topage] = $tmppagelen;
13484             $this->intmrk[$topage] = $tmpintmrk;
13485             if (isset($tmpfooterpos)) {
13486                 $this->footerpos[$topage] = $tmpfooterpos;
13487             } elseif (isset($this->footerpos[$topage])) {
13488                 unset($this->footerpos[$topage]);
13489             }
13490             if (isset($tmpfooterlen)) {
13491                 $this->footerlen[$topage] = $tmpfooterlen;
13492             } elseif (isset($this->footerlen[$topage])) {
13493                 unset($this->footerlen[$topage]);
13494             }
13495             if (isset($tmptransfmrk)) {
13496                 $this->transfmrk[$topage] = $tmptransfmrk;
13497             } elseif (isset($this->transfmrk[$topage])) {
13498                 unset($this->transfmrk[$topage]);
13499             }
13500             if (isset($tmpannots)) {
13501                 $this->PageAnnots[$topage] = $tmpannots;
13502             } elseif (isset($this->PageAnnots[$topage])) {
13503                 unset($this->PageAnnots[$topage]);
13504             }
13505             if (isset($tmpnewpagegroup)) {
13506                 $this->newpagegroup[$topage] = $tmpnewpagegroup;
13507             } elseif (isset($this->newpagegroup[$topage])) {
13508                 unset($this->newpagegroup[$topage]);
13509             }
13510             
13511             $tmpoutlines = $this->outlines;
13512             foreach ($tmpoutlines as $key => $outline) {
13513                 if (($outline['p'] >= $topage) AND ($outline['p'] < $frompage)) {
13514                     $this->outlines[$key]['p'] = $outline['p'] + 1;
13515                 } elseif ($outline['p'] == $frompage) {
13516                     $this->outlines[$key]['p'] = $topage;
13517                 }
13518             }
13519             
13520             $tmplinks = $this->links;
13521             foreach ($tmplinks as $key => $link) {
13522                 if (($link[0] >= $topage) AND ($link[0] < $frompage)) {
13523                     $this->links[$key][0] = $link[0] + 1;
13524                 } elseif ($link[0] == $frompage) {
13525                     $this->links[$key][0] = $topage;
13526                 }
13527             }
13528             
13529             $tmpjavascript = $this->javascript;
13530             global $jfrompage, $jtopage;
13531             $jfrompage = $frompage;
13532             $jtopage = $topage;
13533             $this->javascript = preg_replace_callback('/this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/',
13534                 create_function('$matches', 'global $jfrompage, $jtopage;
13535                 $pagenum = intval($matches[3]) + 1;
13536                 if (($pagenum >= $jtopage) AND ($pagenum < $jfrompage)) {
13537                     $newpage = ($pagenum + 1);
13538                 } elseif ($pagenum == $jfrompage) {
13539                     $newpage = $jtopage;
13540                 } else {
13541                     $newpage = $pagenum;
13542                 }
13543                 --$newpage;
13544                 return "this.addField(\'".$matches[1]."\',\'".$matches[2]."\',".$newpage."";'), $tmpjavascript);
13545             
13546             $this->lastPage(true);
13547             return true;
13548         }
13549 
13557         public function deletePage($page) {
13558             if ($page > $this->numpages) {
13559                 return false;
13560             }
13561             
13562             unset($this->pages[$page]);
13563             unset($this->pagedim[$page]);
13564             unset($this->pagelen[$page]);
13565             unset($this->intmrk[$page]);
13566             if (isset($this->footerpos[$page])) {
13567                 unset($this->footerpos[$page]);
13568             }
13569             if (isset($this->footerlen[$page])) {
13570                 unset($this->footerlen[$page]);
13571             }
13572             if (isset($this->transfmrk[$page])) {
13573                 unset($this->transfmrk[$page]);
13574             }
13575             if (isset($this->PageAnnots[$page])) {
13576                 unset($this->PageAnnots[$page]);
13577             }
13578             if (isset($this->newpagegroup[$page])) {
13579                 unset($this->newpagegroup[$page]);
13580             }
13581             if (isset($this->pageopen[$page])) {
13582                 unset($this->pageopen[$page]);
13583             }
13584             
13585             for ($i = $page; $i < $this->numpages; ++$i) {
13586                 $j = $i + 1;
13587                 
13588                 $this->pages[$i] = $this->pages[$j];
13589                 $this->pagedim[$i] = $this->pagedim[$j];
13590                 $this->pagelen[$i] = $this->pagelen[$j];
13591                 $this->intmrk[$i] = $this->intmrk[$j];
13592                 if (isset($this->footerpos[$j])) {
13593                     $this->footerpos[$i] = $this->footerpos[$j];
13594                 } elseif (isset($this->footerpos[$i])) {
13595                     unset($this->footerpos[$i]);
13596                 }
13597                 if (isset($this->footerlen[$j])) {
13598                     $this->footerlen[$i] = $this->footerlen[$j];
13599                 } elseif (isset($this->footerlen[$i])) {
13600                     unset($this->footerlen[$i]);
13601                 }
13602                 if (isset($this->transfmrk[$j])) {
13603                     $this->transfmrk[$i] = $this->transfmrk[$j];
13604                 } elseif (isset($this->transfmrk[$i])) {
13605                     unset($this->transfmrk[$i]);
13606                 }
13607                 if (isset($this->PageAnnots[$j])) {
13608                     $this->PageAnnots[$i] = $this->PageAnnots[$j];
13609                 } elseif (isset($this->PageAnnots[$i])) {
13610                     unset($this->PageAnnots[$i]);
13611                 }
13612                 if (isset($this->newpagegroup[$j])) {
13613                     $this->newpagegroup[$i] = $this->newpagegroup[$j];
13614                 } elseif (isset($this->newpagegroup[$i])) {
13615                     unset($this->newpagegroup[$i]);
13616                 }
13617                 if (isset($this->pageopen[$j])) {
13618                     $this->pageopen[$i] = $this->pageopen[$j];
13619                 } elseif (isset($this->pageopen[$i])) {
13620                     unset($this->pageopen[$i]);
13621                 }
13622             }
13623             
13624             unset($this->pages[$this->numpages]);
13625             unset($this->pagedim[$this->numpages]);
13626             unset($this->pagelen[$this->numpages]);
13627             unset($this->intmrk[$this->numpages]);
13628             if (isset($this->footerpos[$this->numpages])) {
13629                 unset($this->footerpos[$this->numpages]);
13630             }
13631             if (isset($this->footerlen[$this->numpages])) {
13632                 unset($this->footerlen[$this->numpages]);
13633             }
13634             if (isset($this->transfmrk[$this->numpages])) {
13635                 unset($this->transfmrk[$this->numpages]);
13636             }
13637             if (isset($this->PageAnnots[$this->numpages])) {
13638                 unset($this->PageAnnots[$this->numpages]);
13639             }
13640             if (isset($this->newpagegroup[$this->numpages])) {
13641                 unset($this->newpagegroup[$this->numpages]);
13642             }
13643             if (isset($this->pageopen[$this->numpages])) {
13644                 unset($this->pageopen[$this->numpages]);
13645             }
13646             --$this->numpages;
13647             $this->page = $this->numpages;
13648             
13649             $tmpoutlines = $this->outlines;
13650             foreach ($tmpoutlines as $key => $outline) {
13651                 if ($outline['p'] > $page) {
13652                     $this->outlines[$key]['p'] = $outline['p'] - 1;
13653                 } elseif ($outline['p'] == $page) {
13654                     unset($this->outlines[$key]);
13655                 }
13656             }
13657             
13658             $tmplinks = $this->links;
13659             foreach ($tmplinks as $key => $link) {
13660                 if ($link[0] > $page) {
13661                     $this->links[$key][0] = $link[0] - 1;
13662                 } elseif ($link[0] == $page) {
13663                     unset($this->links[$key]);
13664                 }
13665             }
13666             
13667             $tmpjavascript = $this->javascript;
13668             global $jpage;
13669             $jpage = $page;
13670             $this->javascript = preg_replace_callback('/this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/',
13671                 create_function('$matches', 'global $jpage;
13672                 $pagenum = intval($matches[3]) + 1;
13673                 if ($pagenum >= $jpage) {
13674                     $newpage = ($pagenum - 1);
13675                 } elseif ($pagenum == $jpage) {
13676                     $newpage = 1;
13677                 } else {
13678                     $newpage = $pagenum;
13679                 }
13680                 --$newpage;
13681                 return "this.addField(\'".$matches[1]."\',\'".$matches[2]."\',".$newpage."";'), $tmpjavascript);
13682             
13683             $this->lastPage(true);
13684             return true;
13685         }
13686 
13697         public function addTOC($page='', $numbersfont='', $filler='.') {
13698             $fontsize = $this->FontSizePt;
13699             $fontfamily = $this->FontFamily;
13700             $fontstyle = $this->FontStyle;
13701             $w = $this->w - $this->lMargin - $this->rMargin;
13702             $spacer = $this->GetStringWidth(' ') * 4;
13703             $page_first = $this->getPage();
13704             $lmargin = $this->lMargin;
13705             $rmargin = $this->rMargin;
13706             $x_start = $this->GetX();
13707             if ($this->empty_string($numbersfont)) {
13708                 $numbersfont = $this->default_monospaced_font;
13709             }
13710             if ($this->empty_string($filler)) {
13711                 $filler = ' ';
13712             }
13713             if ($this->empty_string($page)) {
13714                 $gap = ' ';
13715             } else {
13716                 $gap = '';
13717             }
13718             foreach ($this->outlines as $key => $outline) {
13719                 if ($this->rtl) {
13720                     $aligntext = 'R';
13721                     $alignnum = 'L';
13722                 } else {
13723                     $aligntext = 'L';
13724                     $alignnum = 'R';
13725                 }
13726                 if ($outline['l'] == 0) {
13727                     $this->SetFont($fontfamily, $fontstyle.'B', $fontsize);
13728                 } else {
13729                     $this->SetFont($fontfamily, $fontstyle, $fontsize - $outline['l']);
13730                 }
13731                 $indent = ($spacer * $outline['l']);
13732                 if ($this->rtl) {
13733                     $this->rMargin += $indent;
13734                     $this->x -= $indent;
13735                 } else {
13736                     $this->lMargin += $indent;
13737                     $this->x += $indent;
13738                 }
13739                 $link = $this->AddLink();
13740                 $this->SetLink($link, 0, $outline['p']);
13741                 
13742                 $this->Write(0, $outline['t'], $link, 0, $aligntext, false, 0, false, false, 0);
13743                 $this->SetFont($numbersfont, $fontstyle, $fontsize);
13744                 if ($this->empty_string($page)) {
13745                     $pagenum = $outline['p'];
13746                 } else {
13747                     
13748                     $pagenum = '{#'.($outline['p']).'}';
13749                     if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
13750                         $pagenum = '{'.$pagenum.'}';
13751                     }
13752                 }
13753                 $numwidth = $this->GetStringWidth($pagenum);
13754                 if ($this->rtl) {
13755                     $tw = $this->x - $this->lMargin;
13756                 } else {
13757                     $tw = $this->w - $this->rMargin - $this->x;
13758                 }
13759                 $fw = $tw - $numwidth - $this->GetStringWidth(' ');
13760                 $numfills = floor($fw / $this->GetStringWidth($filler));
13761                 if ($numfills > 0) {
13762                     $rowfill = str_repeat($filler, $numfills);
13763                 } else {
13764                     $rowfill = '';
13765                 }
13766                 if ($this->rtl) {
13767                     $pagenum = $pagenum.$gap.$rowfill.' ';
13768                 } else {
13769                     $pagenum = ' '.$rowfill.$gap.$pagenum;
13770                 }
13771                 
13772                 
13773                 $this->Cell($tw, 0, $pagenum, 0, 1, $alignnum, 0, $link, 0);
13774                 $this->SetX($x_start);
13775                 $this->lMargin = $lmargin;
13776                 $this->rMargin = $rmargin;
13777             }
13778             $page_last = $this->getPage();
13779             $numpages = $page_last - $page_first + 1;
13780             if (!$this->empty_string($page)) {
13781                 for($p = $page_first; $p <= $page_last; ++$p) {
13782                     
13783                     $temppage = $this->getPageBuffer($p);
13784                     for($n = 1; $n <= $this->numpages; ++$n) {
13785                         
13786                         $k = '{#'.$n.'}';
13787                         $ku = '{'.$k.'}';
13788                         $alias_a = $this->_escape($k);
13789                         $alias_au = $this->_escape('{'.$k.'}');
13790                         if ($this->isunicode) {
13791                             $alias_b = $this->_escape($this->UTF8ToLatin1($k));
13792                             $alias_bu = $this->_escape($this->UTF8ToLatin1($ku));
13793                             $alias_c = $this->_escape($this->utf8StrRev($k, false, $this->tmprtl));
13794                             $alias_cu = $this->_escape($this->utf8StrRev($ku, false, $this->tmprtl));
13795                         }
13796                         if ($n >= $page) {
13797                             $np = $n + $numpages;
13798                         } else {
13799                             $np = $n;
13800                         }
13801                         $ns = $this->formatTOCPageNumber($np);
13802                         $nu = $ns;
13803                         $sdiff = strlen($k) - strlen($ns) - 1;
13804                         $sdiffu = strlen($ku) - strlen($ns) - 1;
13805                         $sfill = str_repeat($filler, $sdiff);
13806                         $sfillu = str_repeat($filler, $sdiffu);
13807                         if ($this->rtl) {
13808                             $ns = $ns.' '.$sfill;
13809                             $nu = $nu.' '.$sfillu;
13810                         } else {
13811                             $ns = $sfill.' '.$ns;
13812                             $nu = $sfillu.' '.$nu;
13813                         }
13814                         $nu = $this->UTF8ToUTF16BE($nu, false);
13815                         $temppage = str_replace($alias_au, $nu, $temppage);
13816                         if ($this->isunicode) {
13817                             $temppage = str_replace($alias_bu, $nu, $temppage);
13818                             $temppage = str_replace($alias_cu, $nu, $temppage);
13819                             $temppage = str_replace($alias_b, $ns, $temppage);
13820                             $temppage = str_replace($alias_c, $ns, $temppage);
13821                         }
13822                         $temppage = str_replace($alias_a, $ns, $temppage);
13823                     }
13824                     
13825                     $this->setPageBuffer($p, $temppage);
13826                 }
13827                 
13828                 for ($i = 0; $i < $numpages; ++$i) {
13829                     $this->movePage($page_last, $page);
13830                 }
13831             }
13832             $this->SetFont($fontfamily, $fontstyle, $fontsize);
13833         }
13834 
13840         public function startTransaction() {
13841             if (isset($this->objcopy)) {
13842                 
13843                 $this->commitTransaction();
13844             }
13845             
13846             $this->objcopy = $this->objclone($this);
13847         }
13848 
13854         public function commitTransaction() {
13855             if (isset($this->objcopy)) {
13856                 $this->objcopy->_destroy(true, true);
13857                 unset($this->objcopy);
13858             }
13859         }
13860 
13867         public function rollbackTransaction() {
13868             if (isset($this->objcopy)) {
13869                 if (isset($this->objcopy->diskcache) AND $this->objcopy->diskcache) {
13870                     
13871                     foreach ($this->objcopy->cache_file_lenght as $file => $lenght) {
13872                         $file = substr($file, 1);
13873                         $handle = fopen($file, 'r+');
13874                         ftruncate($handle, $lenght);
13875                     }
13876                 }
13877                 $this->_destroy(true, true);
13878                 return $this->objcopy;
13879             }
13880             return $this;
13881         }
13882 
13890         public function objclone($object) {
13891             return @clone($object);
13892         }
13893 
13901         public function empty_string($str) {
13902             return (is_null($str) OR (is_string($str) AND (strlen($str) == 0)));
13903         }
13904         
13905     } 
13906 }
13907 
13908 
13909 
13910 ?>