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
00092
00136 require_once(dirname(__FILE__).'/config/tcpdf_config.php');
00137
00138
00139
00143 require_once(dirname(__FILE__).'/unicode_data.php');
00144
00148 require_once(dirname(__FILE__).'/htmlcolors.php');
00149
00150 if (!class_exists('TCPDF', false)) {
00154 define('PDF_PRODUCER', 'TCPDF 4.8.007 (http://www.tcpdf.org)');
00155
00165 class TCPDF {
00166
00167
00168
00173 protected $page;
00174
00179 protected $n;
00180
00185 protected $offsets;
00186
00191 protected $buffer;
00192
00197 protected $pages = array();
00198
00203 protected $state;
00204
00209 protected $compress;
00210
00215 protected $CurOrientation;
00216
00221 protected $pagedim = array();
00222
00227 protected $k;
00228
00233 protected $fwPt;
00234
00239 protected $fhPt;
00240
00245 protected $wPt;
00246
00251 protected $hPt;
00252
00257 protected $w;
00258
00263 protected $h;
00264
00269 protected $lMargin;
00270
00275 protected $tMargin;
00276
00281 protected $rMargin;
00282
00287 protected $bMargin;
00288
00293
00294 public $cMargin;
00295
00300 protected $oldcMargin;
00301
00306 protected $x;
00307
00312 protected $y;
00313
00318 protected $lasth;
00319
00324 protected $LineWidth;
00325
00330 protected $CoreFonts;
00331
00336 protected $fonts = array();
00337
00342 protected $FontFiles = array();
00343
00348 protected $diffs = array();
00349
00354 protected $images = array();
00355
00360 protected $PageAnnots = array();
00361
00366 protected $links = array();
00367
00372 protected $FontFamily;
00373
00378 protected $FontStyle;
00379
00385 protected $FontAscent;
00386
00392 protected $FontDescent;
00393
00398 protected $underline;
00399
00404 protected $CurrentFont;
00405
00410 protected $FontSizePt;
00411
00416 protected $FontSize;
00417
00422 protected $DrawColor;
00423
00428 protected $FillColor;
00429
00434 protected $TextColor;
00435
00440 protected $ColorFlag;
00441
00446 protected $AutoPageBreak;
00447
00452 protected $PageBreakTrigger;
00453
00458 protected $InFooter = false;
00459
00464 protected $ZoomMode;
00465
00470 protected $LayoutMode;
00471
00476 protected $title = '';
00477
00482 protected $subject = '';
00483
00488 protected $author = '';
00489
00494 protected $keywords = '';
00495
00500 protected $creator = '';
00501
00506 protected $AliasNbPages = '{nb}';
00507
00512 protected $AliasNumPage = '{pnb}';
00513
00520 protected $img_rb_x;
00521
00528 protected $img_rb_y;
00529
00536 protected $imgscale = 1;
00537
00544 protected $isunicode = false;
00545
00551 protected $PDFVersion = '1.7';
00552
00553
00554
00555
00560 protected $header_margin;
00561
00566 protected $footer_margin;
00567
00573 protected $original_lMargin;
00574
00580 protected $original_rMargin;
00581
00586 protected $header_font;
00587
00592 protected $footer_font;
00593
00598 protected $l;
00599
00604 protected $barcode = false;
00605
00610 protected $print_header = true;
00611
00616 protected $print_footer = true;
00617
00622 protected $header_logo = '';
00623
00628 protected $header_logo_width = 30;
00629
00634 protected $header_title = '';
00635
00640 protected $header_string = '';
00641
00646 protected $default_table_columns = 4;
00647
00648
00649
00650
00655 protected $HREF = array();
00656
00661 protected $fontlist = array();
00662
00667 protected $fgcolor;
00668
00673 protected $listordered = array();
00674
00679 protected $listcount = array();
00680
00685 protected $listnum = 0;
00686
00691 protected $listindent;
00692
00697 protected $bgcolor;
00698
00703 protected $tempfontsize = 10;
00704
00709 protected $lispacer = '';
00710
00716 protected $encoding = 'UTF-8';
00717
00723 protected $internal_encoding;
00724
00730 protected $rtl = false;
00731
00737 protected $tmprtl = false;
00738
00739
00740
00746 protected $encrypted;
00747
00753 protected $Uvalue;
00754
00760 protected $Ovalue;
00761
00767 protected $Pvalue;
00768
00774 protected $enc_obj_id;
00775
00781 protected $last_rc4_key;
00782
00788 protected $last_rc4_key_c;
00789
00794 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";
00795
00800 protected $encryption_key;
00801
00802
00803
00809 protected $outlines = array();
00810
00816 protected $OutlineRoot;
00817
00818
00819
00820
00826 protected $javascript = '';
00827
00833 protected $n_js;
00834
00840 protected $linethrough;
00841
00842
00843
00844
00850 protected $ur;
00851
00857 protected $ur_document;
00858
00864 protected $ur_annots;
00865
00871 protected $ur_form;
00872
00878 protected $ur_signature;
00879
00885 protected $dpi = 72;
00886
00892 protected $newpagegroup = array();
00893
00899 protected $pagegroups;
00900
00906 protected $currpagegroup;
00907
00913 protected $visibility = 'all';
00914
00920 protected $n_ocg_print;
00921
00927 protected $n_ocg_view;
00928
00934 protected $extgstates;
00935
00941 protected $jpeg_quality;
00942
00948 protected $cell_height_ratio = K_CELL_HEIGHT_RATIO;
00949
00955 protected $viewer_preferences;
00956
00962 protected $PageMode;
00963
00969 protected $gradients = array();
00970
00977 protected $intmrk = array();
00978
00985 protected $cntmrk = array();
00986
00992 protected $footerpos = array();
00993
00994
01000 protected $footerlen = array();
01001
01007 protected $newline = true;
01008
01014 protected $endlinex = 0;
01015
01021 protected $linestyleWidth = '';
01022
01028 protected $linestyleCap = '0 J';
01029
01035 protected $linestyleJoin = '0 j';
01036
01042 protected $linestyleDash = '[] 0 d';
01043
01049 protected $openMarkedContent = false;
01050
01056 protected $htmlvspace = 0;
01057
01063 protected $spot_colors = array();
01064
01070 protected $lisymbol = '';
01071
01077 protected $epsmarker = 'x#!#EPS#!#x';
01078
01084 protected $transfmatrix = array();
01085
01091 protected $transfmatrix_key = 0;
01092
01098 protected $booklet = false;
01099
01105 protected $feps = 0.005;
01106
01112 protected $tagvspaces = array();
01113
01120 protected $customlistindent = -1;
01121
01127 protected $opencell = true;
01128
01134 protected $embeddedfiles = array();
01135
01141 protected $premode = false;
01142
01149 protected $transfmrk = array();
01150
01156 protected $htmlLinkColorArray = array(0, 0, 255);
01157
01163 protected $htmlLinkFontStyle = 'U';
01164
01170 protected $numpages = 0;
01171
01177 protected $pagelen = array();
01178
01184 protected $numimages = 0;
01185
01191 protected $imagekeys = array();
01192
01198 protected $bufferlen = 0;
01199
01205 protected $diskcache = false;
01206
01212 protected $numfonts = 0;
01213
01219 protected $fontkeys = array();
01220
01226 protected $font_obj_ids = array();
01227
01233 protected $pageopen = array();
01234
01240 protected $default_monospaced_font = 'courier';
01241
01247 protected $objcopy;
01248
01254 protected $cache_file_lenght = array();
01255
01261 protected $thead = '';
01262
01268 protected $theadMargins = array();
01269
01275 protected $cache_UTF8StringToArray = array();
01276
01282 protected $cache_maxsize_UTF8StringToArray = 8;
01283
01289 protected $cache_size_UTF8StringToArray = 0;
01290
01296 protected $sign = false;
01297
01303 protected $signature_data = array();
01304
01310 protected $signature_max_lenght = 11742;
01311
01317 protected $re_spaces = '/[\s]/';
01318
01324 protected $sig_obj_id = 0;
01325
01331 protected $byterange_string = '/ByteRange[0 ********** ********** **********]';
01332
01338 protected $sig_annot_ref = '***SIGANNREF*** 0 R';
01339
01345 protected $page_obj_id = array();
01346
01352 protected $embedded_start_obj_id = 100000;
01353
01359 protected $annots_start_obj_id = 200000;
01360
01366 protected $annot_obj_id = 200000;
01367
01373 protected $curr_annot_obj_id = 200000;
01374
01380 protected $form_obj_id = array();
01381
01382
01383
01384
01385
01386
01387 protected $default_form_prop = array('lineWidth'=>1, 'borderStyle'=>'solid', 'fillColor'=>array(255, 255, 255), 'strokeColor'=>array(128, 128, 128));
01388
01394 protected $js_objects = array();
01395
01401 protected $js_start_obj_id = 300000;
01402
01408 protected $js_obj_id = 300000;
01409
01415 protected $form_action = '';
01416
01422 protected $form_enctype = 'application/x-www-form-urlencoded';
01423
01429 protected $form_mode = 'post';
01430
01436 protected $apxo_start_obj_id = 400000;
01437
01443 protected $apxo_obj_id = 400000;
01444
01450 protected $annotation_fonts = array();
01451
01457 protected $radiobutton_groups = array();
01458
01464 protected $radio_groups = array();
01465
01471 protected $textindent = 0;
01472
01478 protected $start_transaction_page = 0;
01479
01480
01481
01482
01483
01497 public function __construct($orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding='UTF-8', $diskcache=false) {
01498
01499 if (function_exists('mb_internal_encoding') AND mb_internal_encoding()) {
01500 $this->internal_encoding = mb_internal_encoding();
01501 mb_internal_encoding('ASCII');
01502 }
01503
01504 $this->diskcache = $diskcache ? true : false;
01505
01506 $this->rtl = false;
01507 $this->tmprtl = false;
01508
01509 $this->_dochecks();
01510
01511 $this->isunicode = $unicode;
01512 $this->page = 0;
01513 $this->transfmrk[0] = array();
01514 $this->pagedim = array();
01515 $this->n = 2;
01516 $this->buffer = '';
01517 $this->pages = array();
01518 $this->state = 0;
01519 $this->fonts = array();
01520 $this->FontFiles = array();
01521 $this->diffs = array();
01522 $this->images = array();
01523 $this->links = array();
01524 $this->gradients = array();
01525 $this->InFooter = false;
01526 $this->lasth = 0;
01527 $this->FontFamily = 'helvetica';
01528 $this->FontStyle = '';
01529 $this->FontSizePt = 12;
01530 $this->underline = false;
01531 $this->linethrough = false;
01532 $this->DrawColor = '0 G';
01533 $this->FillColor = '0 g';
01534 $this->TextColor = '0 g';
01535 $this->ColorFlag = false;
01536
01537 $this->encrypted = false;
01538 $this->last_rc4_key = '';
01539 $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";
01540
01541 $this->CoreFonts = array(
01542 'courier'=>'Courier',
01543 'courierB'=>'Courier-Bold',
01544 'courierI'=>'Courier-Oblique',
01545 'courierBI'=>'Courier-BoldOblique',
01546 'helvetica'=>'Helvetica',
01547 'helveticaB'=>'Helvetica-Bold',
01548 'helveticaI'=>'Helvetica-Oblique',
01549 'helveticaBI'=>'Helvetica-BoldOblique',
01550 'times'=>'Times-Roman',
01551 'timesB'=>'Times-Bold',
01552 'timesI'=>'Times-Italic',
01553 'timesBI'=>'Times-BoldItalic',
01554 'symbol'=>'Symbol',
01555 'zapfdingbats'=>'ZapfDingbats'
01556 );
01557
01558 $this->setPageUnit($unit);
01559
01560 $this->setPageFormat($format, $orientation);
01561
01562 $margin = 28.35 / $this->k;
01563 $this->SetMargins($margin, $margin);
01564
01565 $this->cMargin = $margin / 10;
01566
01567 $this->LineWidth = 0.57 / $this->k;
01568 $this->linestyleWidth = sprintf('%.2F w', ($this->LineWidth * $this->k));
01569 $this->linestyleCap = '0 J';
01570 $this->linestyleJoin = '0 j';
01571 $this->linestyleDash = '[] 0 d';
01572
01573 $this->SetAutoPageBreak(true, (2 * $margin));
01574
01575 $this->SetDisplayMode('fullwidth');
01576
01577 $this->SetCompression(true);
01578
01579 $this->PDFVersion = '1.7';
01580 $this->encoding = $encoding;
01581 $this->HREF = array();
01582 $this->getFontsList();
01583 $this->fgcolor = array('R' => 0, 'G' => 0, 'B' => 0);
01584 $this->bgcolor = array('R' => 255, 'G' => 255, 'B' => 255);
01585 $this->extgstates = array();
01586
01587 $this->sign = false;
01588 $this->ur = false;
01589 $this->ur_document = '/FullSave';
01590 $this->ur_annots = '/Create/Delete/Modify/Copy/Import/Export';
01591 $this->ur_form = '/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate';
01592 $this->ur_signature = '/Modify';
01593
01594 $this->jpeg_quality = 75;
01595
01596 $this->utf8Bidi(array(''), '');
01597
01598 $this->SetFont($this->FontFamily, $this->FontStyle, $this->FontSizePt);
01599
01600 if ($this->isunicode AND (@preg_match('/\pL/u', 'a') == 1)) {
01601
01602
01603
01604
01605
01606 $this->re_spaces = '/[\s\p{Z}]/u';
01607 } else {
01608
01609 $this->re_spaces = '/[\s]/';
01610 }
01611 $this->annot_obj_id = $this->annots_start_obj_id;
01612 $this->curr_annot_obj_id = $this->annots_start_obj_id;
01613 $this->apxo_obj_id = $this->apxo_start_obj_id;
01614 $this->js_obj_id = $this->js_start_obj_id;
01615 $this->default_form_prop = array('lineWidth'=>1, 'borderStyle'=>'solid', 'fillColor'=>array(255, 255, 255), 'strokeColor'=>array(128, 128, 128));
01616 }
01617
01623 public function __destruct() {
01624
01625 if (isset($this->internal_encoding) AND !empty($this->internal_encoding)) {
01626 mb_internal_encoding($this->internal_encoding);
01627 }
01628
01629 $this->_destroy(true);
01630 }
01631
01638 public function setPageUnit($unit) {
01639
01640 switch (strtolower($unit)) {
01641
01642 case 'px':
01643 case 'pt': {
01644 $this->k = 1;
01645 break;
01646 }
01647
01648 case 'mm': {
01649 $this->k = $this->dpi / 25.4;
01650 break;
01651 }
01652
01653 case 'cm': {
01654 $this->k = $this->dpi / 2.54;
01655 break;
01656 }
01657
01658 case 'in': {
01659 $this->k = $this->dpi;
01660 break;
01661 }
01662
01663 default : {
01664 $this->Error('Incorrect unit: '.$unit);
01665 break;
01666 }
01667 }
01668 if (isset($this->CurOrientation)) {
01669 $this->setPageOrientation($this->CurOrientation);
01670 }
01671 }
01672
01680 public function setPageFormat($format, $orientation='P') {
01681
01682 if (is_string($format)) {
01683
01684
01685 switch (strtoupper($format)) {
01686 case '4A0': {$format = array(4767.87,6740.79); break;}
01687 case '2A0': {$format = array(3370.39,4767.87); break;}
01688 case 'A0': {$format = array(2383.94,3370.39); break;}
01689 case 'A1': {$format = array(1683.78,2383.94); break;}
01690 case 'A2': {$format = array(1190.55,1683.78); break;}
01691 case 'A3': {$format = array(841.89,1190.55); break;}
01692 case 'A4': default: {$format = array(595.28,841.89); break;}
01693 case 'A5': {$format = array(419.53,595.28); break;}
01694 case 'A6': {$format = array(297.64,419.53); break;}
01695 case 'A7': {$format = array(209.76,297.64); break;}
01696 case 'A8': {$format = array(147.40,209.76); break;}
01697 case 'A9': {$format = array(104.88,147.40); break;}
01698 case 'A10': {$format = array(73.70,104.88); break;}
01699 case 'B0': {$format = array(2834.65,4008.19); break;}
01700 case 'B1': {$format = array(2004.09,2834.65); break;}
01701 case 'B2': {$format = array(1417.32,2004.09); break;}
01702 case 'B3': {$format = array(1000.63,1417.32); break;}
01703 case 'B4': {$format = array(708.66,1000.63); break;}
01704 case 'B5': {$format = array(498.90,708.66); break;}
01705 case 'B6': {$format = array(354.33,498.90); break;}
01706 case 'B7': {$format = array(249.45,354.33); break;}
01707 case 'B8': {$format = array(175.75,249.45); break;}
01708 case 'B9': {$format = array(124.72,175.75); break;}
01709 case 'B10': {$format = array(87.87,124.72); break;}
01710 case 'C0': {$format = array(2599.37,3676.54); break;}
01711 case 'C1': {$format = array(1836.85,2599.37); break;}
01712 case 'C2': {$format = array(1298.27,1836.85); break;}
01713 case 'C3': {$format = array(918.43,1298.27); break;}
01714 case 'C4': {$format = array(649.13,918.43); break;}
01715 case 'C5': {$format = array(459.21,649.13); break;}
01716 case 'C6': {$format = array(323.15,459.21); break;}
01717 case 'C7': {$format = array(229.61,323.15); break;}
01718 case 'C8': {$format = array(161.57,229.61); break;}
01719 case 'C9': {$format = array(113.39,161.57); break;}
01720 case 'C10': {$format = array(79.37,113.39); break;}
01721 case 'RA0': {$format = array(2437.80,3458.27); break;}
01722 case 'RA1': {$format = array(1729.13,2437.80); break;}
01723 case 'RA2': {$format = array(1218.90,1729.13); break;}
01724 case 'RA3': {$format = array(864.57,1218.90); break;}
01725 case 'RA4': {$format = array(609.45,864.57); break;}
01726 case 'SRA0': {$format = array(2551.18,3628.35); break;}
01727 case 'SRA1': {$format = array(1814.17,2551.18); break;}
01728 case 'SRA2': {$format = array(1275.59,1814.17); break;}
01729 case 'SRA3': {$format = array(907.09,1275.59); break;}
01730 case 'SRA4': {$format = array(637.80,907.09); break;}
01731 case 'LETTER': {$format = array(612.00,792.00); break;}
01732 case 'LEGAL': {$format = array(612.00,1008.00); break;}
01733 case 'EXECUTIVE': {$format = array(521.86,756.00); break;}
01734 case 'FOLIO': {$format = array(612.00,936.00); break;}
01735 }
01736 $this->fwPt = $format[0];
01737 $this->fhPt = $format[1];
01738 } else {
01739 $this->fwPt = $format[0] * $this->k;
01740 $this->fhPt = $format[1] * $this->k;
01741 }
01742 $this->setPageOrientation($orientation);
01743 }
01744
01753 public function setPageOrientation($orientation, $autopagebreak='', $bottommargin='') {
01754 $orientation = strtoupper($orientation);
01755 if (($orientation == 'P') OR ($orientation == 'PORTRAIT')) {
01756 $this->CurOrientation = 'P';
01757 $this->wPt = $this->fwPt;
01758 $this->hPt = $this->fhPt;
01759 } elseif (($orientation == 'L') OR ($orientation == 'LANDSCAPE')) {
01760 $this->CurOrientation = 'L';
01761 $this->wPt = $this->fhPt;
01762 $this->hPt = $this->fwPt;
01763 } else {
01764 $this->Error('Incorrect orientation: '.$orientation);
01765 }
01766 $this->w = $this->wPt / $this->k;
01767 $this->h = $this->hPt / $this->k;
01768 if ($this->empty_string($autopagebreak)) {
01769 if (isset($this->AutoPageBreak)) {
01770 $autopagebreak = $this->AutoPageBreak;
01771 } else {
01772 $autopagebreak = true;
01773 }
01774 }
01775 if ($this->empty_string($bottommargin)) {
01776 if (isset($this->bMargin)) {
01777 $bottommargin = $this->bMargin;
01778 } else {
01779
01780 $bottommargin = 2 * 28.35 / $this->k;
01781 }
01782 }
01783 $this->SetAutoPageBreak($autopagebreak, $bottommargin);
01784
01785 $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);
01786 }
01787
01794 public function setSpacesRE($re='/[\s]/') {
01795
01796
01797
01798
01799 $this->re_spaces = $re;
01800 }
01801
01809 public function setRTL($enable, $resetx=true) {
01810 $enable = $enable ? true : false;
01811 $resetx = ($resetx AND ($enable != $this->rtl));
01812 $this->rtl = $enable;
01813 $this->tmprtl = false;
01814 if ($resetx) {
01815 $this->Ln(0);
01816 }
01817 }
01818
01825 public function getRTL() {
01826 return $this->rtl;
01827 }
01828
01835 public function setTempRTL($mode) {
01836 switch ($mode) {
01837 case false:
01838 case 'L':
01839 case 'R': {
01840 $this->tmprtl = $mode;
01841 }
01842 }
01843 }
01844
01852 public function setLastH($h) {
01853 $this->lasth = $h;
01854 }
01855
01862 public function getLastH() {
01863 return $this->lasth;
01864 }
01865
01873 public function setImageScale($scale) {
01874 $this->imgscale = $scale;
01875 }
01876
01884 public function getImageScale() {
01885 return $this->imgscale;
01886 }
01887
01897 public function getPageDimensions($pagenum='') {
01898 if (empty($pagenum)) {
01899 $pagenum = $this->page;
01900 }
01901 return $this->pagedim[$pagenum];
01902 }
01903
01913 public function getPageWidth($pagenum='') {
01914 if (empty($pagenum)) {
01915 return $this->w;
01916 }
01917 return $this->pagedim[$pagenum]['w'];
01918 }
01919
01929 public function getPageHeight($pagenum='') {
01930 if (empty($pagenum)) {
01931 return $this->h;
01932 }
01933 return $this->pagedim[$pagenum]['h'];
01934 }
01935
01945 public function getBreakMargin($pagenum='') {
01946 if (empty($pagenum)) {
01947 return $this->bMargin;
01948 }
01949 return $this->pagedim[$pagenum]['bm'];
01950 }
01951
01959 public function getScaleFactor() {
01960 return $this->k;
01961 }
01962
01972 public function SetMargins($left, $top, $right=-1) {
01973
01974 $this->lMargin = $left;
01975 $this->tMargin = $top;
01976 if ($right == -1) {
01977 $right = $left;
01978 }
01979 $this->rMargin = $right;
01980 }
01981
01989 public function SetLeftMargin($margin) {
01990
01991 $this->lMargin=$margin;
01992 if (($this->page > 0) AND ($this->x < $margin)) {
01993 $this->x = $margin;
01994 }
01995 }
01996
02004 public function SetTopMargin($margin) {
02005
02006 $this->tMargin=$margin;
02007 if (($this->page > 0) AND ($this->y < $margin)) {
02008 $this->y = $margin;
02009 }
02010 }
02011
02019 public function SetRightMargin($margin) {
02020 $this->rMargin=$margin;
02021 if (($this->page > 0) AND ($this->x > ($this->w - $margin))) {
02022 $this->x = $this->w - $margin;
02023 }
02024 }
02025
02033 public function SetCellPadding($pad) {
02034 $this->cMargin = $pad;
02035 }
02036
02045 public function SetAutoPageBreak($auto, $margin=0) {
02046
02047 $this->AutoPageBreak = $auto;
02048 $this->bMargin = $margin;
02049 $this->PageBreakTrigger = $this->h - $margin;
02050 }
02051
02060 public function SetDisplayMode($zoom, $layout='SinglePage', $mode='UseNone') {
02061
02062 if (($zoom == 'fullpage') OR ($zoom == 'fullwidth') OR ($zoom == 'real') OR ($zoom == 'default') OR (!is_string($zoom))) {
02063 $this->ZoomMode = $zoom;
02064 } else {
02065 $this->Error('Incorrect zoom display mode: '.$zoom);
02066 }
02067 switch ($layout) {
02068 case 'default':
02069 case 'single':
02070 case 'SinglePage': {
02071 $this->LayoutMode = 'SinglePage';
02072 break;
02073 }
02074 case 'continuous':
02075 case 'OneColumn': {
02076 $this->LayoutMode = 'OneColumn';
02077 break;
02078 }
02079 case 'two':
02080 case 'TwoColumnLeft': {
02081 $this->LayoutMode = 'TwoColumnLeft';
02082 break;
02083 }
02084 case 'TwoColumnRight': {
02085 $this->LayoutMode = 'TwoColumnRight';
02086 break;
02087 }
02088 case 'TwoPageLeft': {
02089 $this->LayoutMode = 'TwoPageLeft';
02090 break;
02091 }
02092 case 'TwoPageRight': {
02093 $this->LayoutMode = 'TwoPageRight';
02094 break;
02095 }
02096 default: {
02097 $this->LayoutMode = 'SinglePage';
02098 }
02099 }
02100 switch ($mode) {
02101 case 'UseNone': {
02102 $this->PageMode = 'UseNone';
02103 break;
02104 }
02105 case 'UseOutlines': {
02106 $this->PageMode = 'UseOutlines';
02107 break;
02108 }
02109 case 'UseThumbs': {
02110 $this->PageMode = 'UseThumbs';
02111 break;
02112 }
02113 case 'FullScreen': {
02114 $this->PageMode = 'FullScreen';
02115 break;
02116 }
02117 case 'UseOC': {
02118 $this->PageMode = 'UseOC';
02119 break;
02120 }
02121 case '': {
02122 $this->PageMode = 'UseAttachments';
02123 break;
02124 }
02125 default: {
02126 $this->PageMode = 'UseNone';
02127 }
02128 }
02129 }
02130
02138 public function SetCompression($compress) {
02139
02140 if (function_exists('gzcompress')) {
02141 $this->compress = $compress;
02142 } else {
02143 $this->compress = false;
02144 }
02145 }
02146
02154 public function SetTitle($title) {
02155
02156 $this->title = $title;
02157 }
02158
02166 public function SetSubject($subject) {
02167
02168 $this->subject = $subject;
02169 }
02170
02178 public function SetAuthor($author) {
02179
02180 $this->author = $author;
02181 }
02182
02190 public function SetKeywords($keywords) {
02191
02192 $this->keywords = $keywords;
02193 }
02194
02202 public function SetCreator($creator) {
02203
02204 $this->creator = $creator;
02205 }
02206
02214 public function Error($msg) {
02215
02216 $this->_destroy(true);
02217
02218 die('<strong>TCPDF ERROR: </strong>'.$msg);
02219 }
02220
02229 public function Open() {
02230
02231 $this->state = 1;
02232 }
02233
02242 public function Close() {
02243 if ($this->state == 3) {
02244 return;
02245 }
02246 if ($this->page == 0) {
02247 $this->AddPage();
02248 }
02249
02250 $this->endPage();
02251
02252 $this->_enddoc();
02253
02254 $this->_destroy(false);
02255 }
02256
02265 public function setPage($pnum, $resetmargins=false) {
02266 if ($pnum == $this->page) {
02267 return;
02268 }
02269 if (($pnum > 0) AND ($pnum <= $this->numpages)) {
02270 $this->state = 2;
02271
02272
02273 $oldpage = $this->page;
02274 $this->page = $pnum;
02275 $this->wPt = $this->pagedim[$this->page]['w'];
02276 $this->hPt = $this->pagedim[$this->page]['h'];
02277 $this->w = $this->wPt / $this->k;
02278 $this->h = $this->hPt / $this->k;
02279 $this->tMargin = $this->pagedim[$this->page]['tm'];
02280 $this->bMargin = $this->pagedim[$this->page]['bm'];
02281 $this->original_lMargin = $this->pagedim[$this->page]['olm'];
02282 $this->original_rMargin = $this->pagedim[$this->page]['orm'];
02283 $this->AutoPageBreak = $this->pagedim[$this->page]['pb'];
02284 $this->CurOrientation = $this->pagedim[$this->page]['or'];
02285 $this->SetAutoPageBreak($this->AutoPageBreak, $this->bMargin);
02286
02287
02288 if ($resetmargins) {
02289 $this->lMargin = $this->pagedim[$this->page]['olm'];
02290 $this->rMargin = $this->pagedim[$this->page]['orm'];
02291 $this->SetY($this->tMargin);
02292 } else {
02293
02294 if ($this->pagedim[$this->page]['olm'] != $this->pagedim[$oldpage]['olm']) {
02295 $deltam = $this->pagedim[$this->page]['olm'] - $this->pagedim[$this->page]['orm'];
02296 $this->lMargin += $deltam;
02297 $this->rMargin -= $deltam;
02298 }
02299 }
02300 } else {
02301 $this->Error('Wrong page number on setPage() function.');
02302 }
02303 }
02304
02312 public function lastPage($resetmargins=false) {
02313 $this->setPage($this->getNumPages(), $resetmargins);
02314 }
02315
02323 public function getPage() {
02324 return $this->page;
02325 }
02326
02327
02335 public function getNumPages() {
02336 return $this->numpages;
02337 }
02338
02348 public function AddPage($orientation='', $format='') {
02349 if (!isset($this->original_lMargin)) {
02350 $this->original_lMargin = $this->lMargin;
02351 }
02352 if (!isset($this->original_rMargin)) {
02353 $this->original_rMargin = $this->rMargin;
02354 }
02355
02356 $this->endPage();
02357
02358 $this->startPage($orientation, $format);
02359 }
02360
02367 protected function endPage() {
02368
02369 if (($this->page == 0) OR ($this->numpages > $this->page) OR (!$this->pageopen[$this->page])) {
02370 return;
02371 }
02372 $this->InFooter = true;
02373
02374 $this->setFooter();
02375
02376 $this->_endpage();
02377
02378 $this->pageopen[$this->page] = false;
02379 $this->InFooter = false;
02380 }
02381
02391 protected function startPage($orientation='', $format='') {
02392 if ($this->numpages > $this->page) {
02393
02394 $this->setPage($this->page + 1);
02395 $this->SetY($this->tMargin);
02396 return;
02397 }
02398
02399 if ($this->state == 0) {
02400 $this->Open();
02401 }
02402 ++$this->numpages;
02403 $this->swapMargins($this->booklet);
02404
02405 $gvars = $this->getGraphicVars();
02406
02407 $this->_beginpage($orientation, $format);
02408
02409 $this->pageopen[$this->page] = true;
02410
02411 $this->setGraphicVars($gvars);
02412
02413 $this->setPageMark();
02414
02415 $this->setHeader();
02416
02417 $this->setGraphicVars($gvars);
02418
02419 $this->setPageMark();
02420
02421 $this->setTableHeader();
02422 }
02423
02431 public function setPageMark() {
02432 $this->intmrk[$this->page] = $this->pagelen[$this->page];
02433 $this->setContentMark();
02434 }
02435
02442 protected function setContentMark($page=0) {
02443 if ($page <= 0) {
02444 $page = $this->page;
02445 }
02446 if (isset($this->footerlen[$page])) {
02447 $this->cntmrk[$page] = $this->pagelen[$page] - $this->footerlen[$page];
02448 } else {
02449 $this->cntmrk[$page] = $this->pagelen[$page];
02450 }
02451 }
02452
02461 public function setHeaderData($ln='', $lw=0, $ht='', $hs='') {
02462 $this->header_logo = $ln;
02463 $this->header_logo_width = $lw;
02464 $this->header_title = $ht;
02465 $this->header_string = $hs;
02466 }
02467
02475 public function getHeaderData() {
02476 $ret = array();
02477 $ret['logo'] = $this->header_logo;
02478 $ret['logo_width'] = $this->header_logo_width;
02479 $ret['title'] = $this->header_title;
02480 $ret['string'] = $this->header_string;
02481 return $ret;
02482 }
02483
02490 public function setHeaderMargin($hm=10) {
02491 $this->header_margin = $hm;
02492 }
02493
02500 public function getHeaderMargin() {
02501 return $this->header_margin;
02502 }
02503
02510 public function setFooterMargin($fm=10) {
02511 $this->footer_margin = $fm;
02512 }
02513
02520 public function getFooterMargin() {
02521 return $this->footer_margin;
02522 }
02528 public function setPrintHeader($val=true) {
02529 $this->print_header = $val;
02530 }
02531
02537 public function setPrintFooter($val=true) {
02538 $this->print_footer = $val;
02539 }
02540
02546 public function getImageRBX() {
02547 return $this->img_rb_x;
02548 }
02549
02555 public function getImageRBY() {
02556 return $this->img_rb_y;
02557 }
02558
02564 public function Header() {
02565 $ormargins = $this->getOriginalMargins();
02566 $headerfont = $this->getHeaderFont();
02567 $headerdata = $this->getHeaderData();
02568 if (($headerdata['logo']) AND ($headerdata['logo'] != K_BLANK_IMAGE)) {
02569 $this->Image(K_PATH_IMAGES.$headerdata['logo'], $this->GetX(), $this->getHeaderMargin(), $headerdata['logo_width']);
02570 $imgy = $this->getImageRBY();
02571 } else {
02572 $imgy = $this->GetY();
02573 }
02574 $cell_height = round(($this->getCellHeightRatio() * $headerfont[2]) / $this->getScaleFactor(), 2);
02575
02576 if ($this->getRTL()) {
02577 $header_x = $ormargins['right'] + ($headerdata['logo_width'] * 1.1);
02578 } else {
02579 $header_x = $ormargins['left'] + ($headerdata['logo_width'] * 1.1);
02580 }
02581 $this->SetTextColor(0, 0, 0);
02582
02583 $this->SetFont($headerfont[0], 'B', $headerfont[2] + 1);
02584 $this->SetX($header_x);
02585 $this->Cell(0, $cell_height, $headerdata['title'], 0, 1, '', 0, '', 0);
02586
02587 $this->SetFont($headerfont[0], $headerfont[1], $headerfont[2]);
02588 $this->SetX($header_x);
02589 $this->MultiCell(0, $cell_height, $headerdata['string'], 0, '', 0, 1, '', '', true, 0, false);
02590
02591 $this->SetLineStyle(array('width' => 0.85 / $this->getScaleFactor(), 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)));
02592 $this->SetY((2.835 / $this->getScaleFactor()) + max($imgy, $this->GetY()));
02593 if ($this->getRTL()) {
02594 $this->SetX($ormargins['right']);
02595 } else {
02596 $this->SetX($ormargins['left']);
02597 }
02598 $this->Cell(0, 0, '', 'T', 0, 'C');
02599 }
02600
02606 public function Footer() {
02607 $cur_y = $this->GetY();
02608 $ormargins = $this->getOriginalMargins();
02609 $this->SetTextColor(0, 0, 0);
02610
02611 $line_width = 0.85 / $this->getScaleFactor();
02612 $this->SetLineStyle(array('width' => $line_width, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)));
02613
02614 $barcode = $this->getBarcode();
02615 if (!empty($barcode)) {
02616 $this->Ln($line_width);
02617 $barcode_width = round(($this->getPageWidth() - $ormargins['left'] - $ormargins['right'])/3);
02618 $this->write1DBarcode($barcode, 'C128B', $this->GetX(), $cur_y + $line_width, $barcode_width, (($this->getFooterMargin() / 3) - $line_width), 0.3, '', '');
02619 }
02620 if (empty($this->pagegroups)) {
02621 $pagenumtxt = $this->l['w_page'].' '.$this->getAliasNumPage().' / '.$this->getAliasNbPages();
02622 } else {
02623 $pagenumtxt = $this->l['w_page'].' '.$this->getPageNumGroupAlias().' / '.$this->getPageGroupAlias();
02624 }
02625 $this->SetY($cur_y);
02626
02627 if ($this->getRTL()) {
02628 $this->SetX($ormargins['right']);
02629 $this->Cell(0, 0, $pagenumtxt, 'T', 0, 'L');
02630 } else {
02631 $this->SetX($ormargins['left']);
02632 $this->Cell(0, 0, $pagenumtxt, 'T', 0, 'R');
02633 }
02634 }
02635
02641 protected function setHeader() {
02642 if ($this->print_header) {
02643 $lasth = $this->lasth;
02644 $this->_out('q');
02645 $this->rMargin = $this->original_rMargin;
02646 $this->lMargin = $this->original_lMargin;
02647 $this->cMargin = 0;
02648
02649 if ($this->rtl) {
02650 $this->SetXY($this->original_rMargin, $this->header_margin);
02651 } else {
02652 $this->SetXY($this->original_lMargin, $this->header_margin);
02653 }
02654 $this->SetFont($this->header_font[0], $this->header_font[1], $this->header_font[2]);
02655 $this->Header();
02656
02657 if ($this->rtl) {
02658 $this->SetXY($this->original_rMargin, $this->tMargin);
02659 } else {
02660 $this->SetXY($this->original_lMargin, $this->tMargin);
02661 }
02662 $this->_out('Q');
02663 $this->lasth = $lasth;
02664 }
02665 }
02666
02672 protected function setFooter() {
02673
02674
02675 $gvars = $this->getGraphicVars();
02676
02677 $this->footerpos[$this->page] = $this->pagelen[$this->page];
02678 $this->_out("\n");
02679 if ($this->print_footer) {
02680 $lasth = $this->lasth;
02681 $this->_out('q');
02682 $this->rMargin = $this->original_rMargin;
02683 $this->lMargin = $this->original_lMargin;
02684 $this->cMargin = 0;
02685
02686 $footer_y = $this->h - $this->footer_margin;
02687 if ($this->rtl) {
02688 $this->SetXY($this->original_rMargin, $footer_y);
02689 } else {
02690 $this->SetXY($this->original_lMargin, $footer_y);
02691 }
02692 $this->SetFont($this->footer_font[0], $this->footer_font[1], $this->footer_font[2]);
02693 $this->Footer();
02694
02695 if ($this->rtl) {
02696 $this->SetXY($this->original_rMargin, $this->tMargin);
02697 } else {
02698 $this->SetXY($this->original_lMargin, $this->tMargin);
02699 }
02700 $this->_out('Q');
02701 $this->lasth = $lasth;
02702 }
02703
02704 $this->setGraphicVars($gvars);
02705
02706 $this->footerlen[$this->page] = $this->pagelen[$this->page] - $this->footerpos[$this->page] + 1;
02707 }
02708
02714 protected function setTableHeader() {
02715 if (isset($this->theadMargins['top'])) {
02716
02717 $this->tMargin = $this->theadMargins['top'];
02718 $this->pagedim[$this->page]['tm'] = $this->tMargin;
02719 $this->y = $this->tMargin;
02720 }
02721 if (!$this->empty_string($this->thead)) {
02722
02723 $prev_lMargin = $this->lMargin;
02724 $prev_rMargin = $this->rMargin;
02725 $this->lMargin = $this->pagedim[$this->page]['olm'];
02726 $this->rMargin = $this->pagedim[$this->page]['orm'];
02727 $this->cMargin = $this->theadMargins['cmargin'];
02728
02729 $this->writeHTML($this->thead, false, false, false, false, '');
02730
02731 if (!isset($this->theadMargins['top'])) {
02732 $this->theadMargins['top'] = $this->tMargin;
02733 }
02734 $this->tMargin = $this->y;
02735 $this->pagedim[$this->page]['tm'] = $this->tMargin;
02736 $this->lasth = 0;
02737 $this->lMargin = $prev_lMargin;
02738 $this->rMargin = $prev_rMargin;
02739 }
02740 }
02741
02749 public function PageNo() {
02750 return $this->page;
02751 }
02752
02765 public function AddSpotColor($name, $c, $m, $y, $k) {
02766 if (!isset($this->spot_colors[$name])) {
02767 $i = 1 + count($this->spot_colors);
02768 $this->spot_colors[$name] = array('i' => $i, 'c' => $c, 'm' => $m, 'y' => $y, 'k' => $k);
02769 }
02770 }
02771
02781 public function SetDrawColorArray($color) {
02782 if (isset($color)) {
02783 $color = array_values($color);
02784 $r = isset($color[0]) ? $color[0] : -1;
02785 $g = isset($color[1]) ? $color[1] : -1;
02786 $b = isset($color[2]) ? $color[2] : -1;
02787 $k = isset($color[3]) ? $color[3] : -1;
02788 if ($r >= 0) {
02789 $this->SetDrawColor($r, $g, $b, $k);
02790 }
02791 }
02792 }
02793
02804 public function SetDrawColor($col1=0, $col2=-1, $col3=-1, $col4=-1) {
02805
02806 if (!is_numeric($col1)) {
02807 $col1 = 0;
02808 }
02809 if (!is_numeric($col2)) {
02810 $col2 = -1;
02811 }
02812 if (!is_numeric($col3)) {
02813 $col3 = -1;
02814 }
02815 if (!is_numeric($col4)) {
02816 $col4 = -1;
02817 }
02818
02819 if (($col2 == -1) AND ($col3 == -1) AND ($col4 == -1)) {
02820
02821 $this->DrawColor = sprintf('%.3F G', $col1/255);
02822 } elseif ($col4 == -1) {
02823
02824 $this->DrawColor = sprintf('%.3F %.3F %.3F RG', $col1/255, $col2/255, $col3/255);
02825 } else {
02826
02827 $this->DrawColor = sprintf('%.3F %.3F %.3F %.3F K', $col1/100, $col2/100, $col3/100, $col4/100);
02828 }
02829 if ($this->page > 0) {
02830 $this->_out($this->DrawColor);
02831 }
02832 }
02833
02842 public function SetDrawSpotColor($name, $tint=100) {
02843 if (!isset($this->spot_colors[$name])) {
02844 $this->Error('Undefined spot color: '.$name);
02845 }
02846 $this->DrawColor = sprintf('/CS%d CS %.3F SCN', $this->spot_colors[$name]['i'], $tint/100);
02847 if ($this->page > 0) {
02848 $this->_out($this->DrawColor);
02849 }
02850 }
02851
02861 public function SetFillColorArray($color) {
02862 if (isset($color)) {
02863 $color = array_values($color);
02864 $r = isset($color[0]) ? $color[0] : -1;
02865 $g = isset($color[1]) ? $color[1] : -1;
02866 $b = isset($color[2]) ? $color[2] : -1;
02867 $k = isset($color[3]) ? $color[3] : -1;
02868 if ($r >= 0) {
02869 $this->SetFillColor($r, $g, $b, $k);
02870 }
02871 }
02872 }
02873
02884 public function SetFillColor($col1=0, $col2=-1, $col3=-1, $col4=-1) {
02885
02886 if (!is_numeric($col1)) {
02887 $col1 = 0;
02888 }
02889 if (!is_numeric($col2)) {
02890 $col2 = -1;
02891 }
02892 if (!is_numeric($col3)) {
02893 $col3 = -1;
02894 }
02895 if (!is_numeric($col4)) {
02896 $col4 = -1;
02897 }
02898
02899 if (($col2 == -1) AND ($col3 == -1) AND ($col4 == -1)) {
02900
02901 $this->FillColor = sprintf('%.3F g', $col1/255);
02902 $this->bgcolor = array('G' => $col1);
02903 } elseif ($col4 == -1) {
02904
02905 $this->FillColor = sprintf('%.3F %.3F %.3F rg', $col1/255, $col2/255, $col3/255);
02906 $this->bgcolor = array('R' => $col1, 'G' => $col2, 'B' => $col3);
02907 } else {
02908
02909 $this->FillColor = sprintf('%.3F %.3F %.3F %.3F k', $col1/100, $col2/100, $col3/100, $col4/100);
02910 $this->bgcolor = array('C' => $col1, 'M' => $col2, 'Y' => $col3, 'K' => $col4);
02911 }
02912 $this->ColorFlag = ($this->FillColor != $this->TextColor);
02913 if ($this->page > 0) {
02914 $this->_out($this->FillColor);
02915 }
02916 }
02917
02926 public function SetFillSpotColor($name, $tint=100) {
02927 if (!isset($this->spot_colors[$name])) {
02928 $this->Error('Undefined spot color: '.$name);
02929 }
02930 $this->FillColor = sprintf('/CS%d cs %.3F scn', $this->spot_colors[$name]['i'], $tint/100);
02931 $this->ColorFlag = ($this->FillColor != $this->TextColor);
02932 if ($this->page > 0) {
02933 $this->_out($this->FillColor);
02934 }
02935 }
02936
02945 public function SetTextColorArray($color) {
02946 if (isset($color)) {
02947 $color = array_values($color);
02948 $r = isset($color[0]) ? $color[0] : -1;
02949 $g = isset($color[1]) ? $color[1] : -1;
02950 $b = isset($color[2]) ? $color[2] : -1;
02951 $k = isset($color[3]) ? $color[3] : -1;
02952 if ($r >= 0) {
02953 $this->SetTextColor($r, $g, $b, $k);
02954 }
02955 }
02956 }
02957
02968 public function SetTextColor($col1=0, $col2=-1, $col3=-1, $col4=-1) {
02969
02970 if (!is_numeric($col1)) {
02971 $col1 = 0;
02972 }
02973 if (!is_numeric($col2)) {
02974 $col2 = -1;
02975 }
02976 if (!is_numeric($col3)) {
02977 $col3 = -1;
02978 }
02979 if (!is_numeric($col4)) {
02980 $col4 = -1;
02981 }
02982
02983 if (($col2 == -1) AND ($col3 == -1) AND ($col4 == -1)) {
02984
02985 $this->TextColor = sprintf('%.3F g', $col1/255);
02986 $this->fgcolor = array('G' => $col1);
02987 } elseif ($col4 == -1) {
02988
02989 $this->TextColor = sprintf('%.3F %.3F %.3F rg', $col1/255, $col2/255, $col3/255);
02990 $this->fgcolor = array('R' => $col1, 'G' => $col2, 'B' => $col3);
02991 } else {
02992
02993 $this->TextColor = sprintf('%.3F %.3F %.3F %.3F k', $col1/100, $col2/100, $col3/100, $col4/100);
02994 $this->fgcolor = array('C' => $col1, 'M' => $col2, 'Y' => $col3, 'K' => $col4);
02995 }
02996 $this->ColorFlag = ($this->FillColor != $this->TextColor);
02997 }
02998
03007 public function SetTextSpotColor($name, $tint=100) {
03008 if (!isset($this->spot_colors[$name])) {
03009 $this->Error('Undefined spot color: '.$name);
03010 }
03011 $this->TextColor = sprintf('/CS%d cs %.3F scn', $this->spot_colors[$name]['i'], $tint/100);
03012 $this->ColorFlag = ($this->FillColor != $this->TextColor);
03013 if ($this->page > 0) {
03014 $this->_out($this->TextColor);
03015 }
03016 }
03017
03029 public function GetStringWidth($s, $fontname='', $fontstyle='', $fontsize=0) {
03030 return $this->GetArrStringWidth($this->utf8Bidi($this->UTF8StringToArray($s), $s, $this->tmprtl), $fontname, $fontstyle, $fontsize);
03031 }
03032
03044 public function GetArrStringWidth($sa, $fontname='', $fontstyle='', $fontsize=0) {
03045
03046 if (!$this->empty_string($fontname)) {
03047 $prev_FontFamily = $this->FontFamily;
03048 $prev_FontStyle = $this->FontStyle;
03049 $prev_FontSizePt = $this->FontSizePt;
03050 $this->SetFont($fontname, $fontstyle, $fontsize);
03051 }
03052 $w = 0;
03053 foreach ($sa as $char) {
03054 $w += $this->GetCharWidth($char);
03055 }
03056
03057 if (!$this->empty_string($fontname)) {
03058 $this->SetFont($prev_FontFamily, $prev_FontStyle, $prev_FontSizePt);
03059 }
03060 return $w;
03061 }
03062
03071 public function GetCharWidth($char) {
03072 if ($char == 173) {
03073
03074 return (0);
03075 }
03076 $cw = &$this->CurrentFont['cw'];
03077 if (isset($cw[$char])) {
03078 $w = $cw[$char];
03079 } elseif (isset($this->CurrentFont['dw'])) {
03080
03081 $w = $this->CurrentFont['dw'];
03082 } elseif (isset($cw[32])) {
03083
03084 $dw = $cw[32];
03085 } else {
03086 $w = 600;
03087 }
03088 return ($w * $this->FontSize / 1000);
03089 }
03090
03098 public function GetNumChars($s) {
03099 if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
03100 return count($this->UTF8StringToArray($s));
03101 }
03102 return strlen($s);
03103 }
03104
03110 protected function getFontsList() {
03111 $fontsdir = opendir($this->_getfontpath());
03112 while (($file = readdir($fontsdir)) !== false) {
03113 if (substr($file, -4) == '.php') {
03114 array_push($this->fontlist, strtolower(basename($file, '.php')));
03115 }
03116 }
03117 closedir($fontsdir);
03118 }
03119
03132 public function AddFont($family, $style='', $fontfile='') {
03133 if ($this->empty_string($family)) {
03134 if (!$this->empty_string($this->FontFamily)) {
03135 $family = $this->FontFamily;
03136 } else {
03137 $this->Error('Empty font family');
03138 }
03139 }
03140 $family = strtolower($family);
03141 if ((!$this->isunicode) AND ($family == 'arial')) {
03142 $family = 'helvetica';
03143 }
03144 if (($family == 'symbol') OR ($family == 'zapfdingbats')) {
03145 $style = '';
03146 }
03147 $tempstyle = strtoupper($style);
03148 $style = '';
03149
03150 if (strpos($tempstyle, 'U') !== false) {
03151 $this->underline = true;
03152 } else {
03153 $this->underline = false;
03154 }
03155
03156 if (strpos($tempstyle, 'D') !== false) {
03157 $this->linethrough = true;
03158 } else {
03159 $this->linethrough = false;
03160 }
03161
03162 if (strpos($tempstyle, 'B') !== false) {
03163 $style .= 'B';
03164 }
03165
03166 if (strpos($tempstyle, 'I') !== false) {
03167 $style .= 'I';
03168 }
03169 $bistyle = $style;
03170 $fontkey = $family.$style;
03171 $font_style = $style.($this->underline ? 'U' : '').($this->linethrough ? 'D' : '');
03172 $fontdata = array('fontkey' => $fontkey, 'family' => $family, 'style' => $font_style);
03173
03174 if ($this->getFontBuffer($fontkey) !== false) {
03175 return $fontdata;
03176 }
03177 if (isset($type)) {
03178 unset($type);
03179 }
03180 if (isset($cw)) {
03181 unset($cw);
03182 }
03183
03184 $fontdir = '';
03185 if (!$this->empty_string($fontfile)) {
03186 $fontdir = dirname($fontfile);
03187 if ($this->empty_string($fontdir) OR ($fontdir == '.')) {
03188 $fontdir = '';
03189 } else {
03190 $fontdir .= '/';
03191 }
03192 }
03193
03194 if ($this->empty_string($fontfile) OR (!file_exists($fontfile))) {
03195
03196 $fontfile1 = str_replace(' ', '', $family).strtolower($style).'.php';
03197 $fontfile2 = str_replace(' ', '', $family).'.php';
03198
03199 if (file_exists($fontdir.$fontfile1)) {
03200 $fontfile = $fontdir.$fontfile1;
03201 } elseif (file_exists($this->_getfontpath().$fontfile1)) {
03202 $fontfile = $this->_getfontpath().$fontfile1;
03203 } elseif (file_exists($fontfile1)) {
03204 $fontfile = $fontfile1;
03205 } elseif (file_exists($fontdir.$fontfile2)) {
03206 $fontfile = $fontdir.$fontfile2;
03207 } elseif (file_exists($this->_getfontpath().$fontfile2)) {
03208 $fontfile = $this->_getfontpath().$fontfile2;
03209 } else {
03210 $fontfile = $fontfile2;
03211 }
03212 }
03213
03214 if (file_exists($fontfile)) {
03215 include($fontfile);
03216 } else {
03217 $this->Error('Could not include font definition file: '.$family.'');
03218 }
03219
03220 if ((!isset($type)) OR (!isset($cw))) {
03221 $this->Error('The font definition file has a bad format: '.$fontfile.'');
03222 }
03223
03224 if (!isset($file) OR $this->empty_string($file)) {
03225 $file = '';
03226 }
03227 if (!isset($enc) OR $this->empty_string($enc)) {
03228 $enc = '';
03229 }
03230 if (!isset($cidinfo) OR $this->empty_string($cidinfo)) {
03231 $cidinfo = array('Registry'=>'Adobe','Ordering'=>'Identity','Supplement'=>0);
03232 $cidinfo['uni2cid'] = array();
03233 }
03234 if (!isset($ctg) OR $this->empty_string($ctg)) {
03235 $ctg = '';
03236 }
03237 if (!isset($desc) OR $this->empty_string($desc)) {
03238 $desc = array();
03239 }
03240 if (!isset($up) OR $this->empty_string($up)) {
03241 $up = -100;
03242 }
03243 if (!isset($ut) OR $this->empty_string($ut)) {
03244 $ut = 50;
03245 }
03246 if (!isset($cw) OR $this->empty_string($cw)) {
03247 $cw = array();
03248 }
03249 if (!isset($dw) OR $this->empty_string($dw)) {
03250
03251 if (isset($desc['MissingWidth']) AND ($desc['MissingWidth'] > 0)) {
03252 $dw = $desc['MissingWidth'];
03253 } elseif (isset($cw[32])) {
03254 $dw = $cw[32];
03255 } else {
03256 $dw = 600;
03257 }
03258 }
03259 ++$this->numfonts;
03260 if ($type == 'cidfont0') {
03261
03262 $styles = array('' => '', 'B' => ',Bold', 'I' => ',Italic', 'BI' => ',BoldItalic');
03263 $sname = $name.$styles[$bistyle];
03264 if ((strpos($bistyle, 'B') !== false) AND (isset($desc['StemV'])) AND ($desc['StemV'] == 70)) {
03265 $desc['StemV'] = 120;
03266 }
03267 } elseif ($type == 'core') {
03268 $name = $this->CoreFonts[$fontkey];
03269 } elseif (($type == 'TrueType') OR ($type == 'Type1')) {
03270
03271 } elseif ($type == 'TrueTypeUnicode') {
03272 $enc = 'Identity-H';
03273 } else {
03274 $this->Error('Unknow font type: '.$type.'');
03275 }
03276 $this->setFontBuffer($fontkey, array('i' => $this->numfonts, 'type' => $type, 'name' => $name, 'desc' => $desc, 'up' => $up, 'ut' => $ut, 'cw' => $cw, 'dw' => $dw, 'enc' => $enc, 'cidinfo' => $cidinfo, 'file' => $file, 'ctg' => $ctg));
03277 if (isset($diff) AND (!empty($diff))) {
03278
03279 $d = 0;
03280 $nb = count($this->diffs);
03281 for ($i=1; $i <= $nb; ++$i) {
03282 if ($this->diffs[$i] == $diff) {
03283 $d = $i;
03284 break;
03285 }
03286 }
03287 if ($d == 0) {
03288 $d = $nb + 1;
03289 $this->diffs[$d] = $diff;
03290 }
03291 $this->setFontSubBuffer($fontkey, 'diff', $d);
03292 }
03293 if (!$this->empty_string($file)) {
03294 if ((strcasecmp($type,'TrueType') == 0) OR (strcasecmp($type, 'TrueTypeUnicode') == 0)) {
03295 $this->FontFiles[$file] = array('length1' => $originalsize, 'fontdir' => $fontdir);
03296 } elseif ($type != 'core') {
03297 $this->FontFiles[$file] = array('length1' => $size1, 'length2' => $size2, 'fontdir' => $fontdir);
03298 }
03299 }
03300 return $fontdata;
03301 }
03302
03317 public function SetFont($family, $style='', $size=0, $fontfile='') {
03318
03319 if ($size == 0) {
03320 $size = $this->FontSizePt;
03321 }
03322
03323 $fontdata = $this->AddFont($family, $style, $fontfile);
03324 $this->FontFamily = $fontdata['family'];
03325 $this->FontStyle = $fontdata['style'];
03326 $this->CurrentFont = $this->getFontBuffer($fontdata['fontkey']);
03327 $this->SetFontSize($size);
03328 }
03329
03337 public function SetFontSize($size) {
03338
03339 $this->FontSizePt = $size;
03340 $this->FontSize = $size / $this->k;
03341 if (isset($this->CurrentFont['desc']['Ascent']) AND ($this->CurrentFont['desc']['Ascent'] > 0)) {
03342 $this->FontAscent = $this->CurrentFont['desc']['Ascent'] * $this->FontSize / 1000;
03343 } else {
03344 $this->FontAscent = 0.8 * $this->FontSize;
03345 }
03346 if (isset($this->CurrentFont['desc']['Descent']) AND ($this->CurrentFont['desc']['Descent'] > 0)) {
03347 $this->FontDescent = - $this->CurrentFont['desc']['Descent'] * $this->FontSize / 1000;
03348 } else {
03349 $this->FontDescent = 0.2 * $this->FontSize;
03350 }
03351 if (($this->page > 0) AND (isset($this->CurrentFont['i']))) {
03352 $this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
03353 }
03354 }
03355
03362 public function SetDefaultMonospacedFont($font) {
03363 $this->default_monospaced_font = $font;
03364 }
03365
03373 public function AddLink() {
03374
03375 $n = count($this->links) + 1;
03376 $this->links[$n] = array(0, 0);
03377 return $n;
03378 }
03379
03389 public function SetLink($link, $y=0, $page=-1) {
03390 if ($y == -1) {
03391 $y = $this->y;
03392 }
03393 if ($page == -1) {
03394 $page = $this->page;
03395 }
03396 $this->links[$link] = array($page, $y);
03397 }
03398
03412 public function Link($x, $y, $w, $h, $link, $spaces=0) {
03413 $this->Annotation($x, $y, $w, $h, $link, array('Subtype'=>'Link'), $spaces);
03414 }
03415
03429 public function Annotation($x='', $y='', $w, $h, $text, $opt=array('Subtype'=>'Text'), $spaces=0) {
03430 if ($x === '') {
03431 $x = $this->x;
03432 }
03433 if ($y === '') {
03434 $y = $this->y;
03435 }
03436
03437 if (isset($this->transfmatrix)) {
03438 for ($i=$this->transfmatrix_key; $i > 0; --$i) {
03439 $maxid = count($this->transfmatrix[$i]) - 1;
03440 for ($j=$maxid; $j >= 0; --$j) {
03441 $ctm = $this->transfmatrix[$i][$j];
03442 if (isset($ctm['a'])) {
03443 $x = $x * $this->k;
03444 $y = ($this->h - $y) * $this->k;
03445 $w = $w * $this->k;
03446 $h = $h * $this->k;
03447
03448 $xt = $x;
03449 $yt = $y;
03450 $x1 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
03451 $y1 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
03452
03453 $xt = $x + $w;
03454 $yt = $y;
03455 $x2 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
03456 $y2 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
03457
03458 $xt = $x;
03459 $yt = $y - $h;
03460 $x3 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
03461 $y3 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
03462
03463 $xt = $x + $w;
03464 $yt = $y - $h;
03465 $x4 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
03466 $y4 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
03467
03468 $x = min($x1, $x2, $x3, $x4);
03469 $y = max($y1, $y2, $y3, $y4);
03470 $w = (max($x1, $x2, $x3, $x4) - $x) / $this->k;
03471 $h = ($y - min($y1, $y2, $y3, $y4)) / $this->k;
03472 $x = $x / $this->k;
03473 $y = $this->h - ($y / $this->k);
03474 }
03475 }
03476 }
03477 }
03478 if ($this->page <= 0) {
03479 $page = 1;
03480 } else {
03481 $page = $this->page;
03482 }
03483 if (!isset($this->PageAnnots[$page])) {
03484 $this->PageAnnots[$page] = array();
03485 }
03486 $this->PageAnnots[$page][] = array('x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'txt' => $text, 'opt' => $opt, 'numspaces' => $spaces);
03487 if (($opt['Subtype'] == 'FileAttachment') AND (!$this->empty_string($opt['FS'])) AND file_exists($opt['FS']) AND (!isset($this->embeddedfiles[basename($opt['FS'])]))) {
03488 $this->embeddedfiles[basename($opt['FS'])] = array('file' => $opt['FS'], 'n' => (count($this->embeddedfiles) + $this->embedded_start_obj_id));
03489 }
03490
03491 if (isset($opt['mk']['i']) AND file_exists($opt['mk']['i'])) {
03492 $this->Image($opt['mk']['i'], '', '', 10, 10, '', '', '', false, 300, '', false, false, 0, false, true);
03493 }
03494 if (isset($opt['mk']['ri']) AND file_exists($opt['mk']['ri'])) {
03495 $this->Image($opt['mk']['ri'], '', '', 0, 0, '', '', '', false, 300, '', false, false, 0, false, true);
03496 }
03497 if (isset($opt['mk']['ix']) AND file_exists($opt['mk']['ix'])) {
03498 $this->Image($opt['mk']['ix'], '', '', 0, 0, '', '', '', false, 300, '', false, false, 0, false, true);
03499 }
03500 ++$this->annot_obj_id;
03501 }
03502
03509 protected function _putEmbeddedFiles() {
03510 reset($this->embeddedfiles);
03511 foreach ($this->embeddedfiles as $filename => $filedata) {
03512 $data = file_get_contents($filedata['file']);
03513 $filter = '';
03514 if ($this->compress) {
03515 $data = gzcompress($data);
03516 $filter = ' /Filter /FlateDecode';
03517 }
03518 $this->offsets[$filedata['n']] = $this->bufferlen;
03519 $this->_out($filedata['n'].' 0 obj');
03520 $this->_out('<</Type /EmbeddedFile'.$filter.' /Length '.strlen($data).' >>');
03521 $this->_putstream($data);
03522 $this->_out('endobj');
03523 }
03524 }
03525
03540 public function Text($x, $y, $txt, $stroke=0, $clip=false) {
03541
03542 if ($this->rtl) {
03543
03544 $s = $this->utf8Bidi($this->UTF8StringToArray($txt), $txt, $this->tmprtl);
03545 $l = $this->GetArrStringWidth($s);
03546 $xr = $this->w - $x - $this->GetArrStringWidth($s);
03547 } else {
03548 $xr = $x;
03549 }
03550 $opt = '';
03551 if (($stroke > 0) AND (!$clip)) {
03552 $opt .= '1 Tr '.intval($stroke).' w ';
03553 } elseif (($stroke > 0) AND $clip) {
03554 $opt .= '5 Tr '.intval($stroke).' w ';
03555 } elseif ($clip) {
03556 $opt .= '7 Tr ';
03557 }
03558 $s = sprintf('BT %.2F %.2F Td %s(%s) Tj ET 0 Tr', $xr * $this->k, ($this->h-$y) * $this->k, $opt, $this->_escapetext($txt));
03559 if ($this->underline AND ($txt!='')) {
03560 $s .= ' '.$this->_dounderline($xr, $y, $txt);
03561 }
03562 if ($this->linethrough AND ($txt!='')) {
03563 $s .= ' '.$this->_dolinethrough($xr, $y, $txt);
03564 }
03565 if ($this->ColorFlag AND (!$clip)) {
03566 $s='q '.$this->TextColor.' '.$s.' Q';
03567 }
03568 $this->_out($s);
03569 }
03570
03580 public function AcceptPageBreak() {
03581 return $this->AutoPageBreak;
03582 }
03583
03593 protected function checkPageBreak($h=0, $y='', $addpage=true) {
03594 if ($this->empty_string($y)) {
03595 $y = $this->y;
03596 }
03597 if ((($y + $h) > $this->PageBreakTrigger) AND (!$this->InFooter) AND ($this->AcceptPageBreak())) {
03598 if ($addpage) {
03599
03600 $x = $this->x;
03601 $this->AddPage($this->CurOrientation);
03602 $this->y = $this->tMargin;
03603 $oldpage = $this->page - 1;
03604 if ($this->rtl) {
03605 if ($this->pagedim[$this->page]['orm'] != $this->pagedim[$oldpage]['orm']) {
03606 $this->x = $x - ($this->pagedim[$this->page]['orm'] - $this->pagedim[$oldpage]['orm']);
03607 } else {
03608 $this->x = $x;
03609 }
03610 } else {
03611 if ($this->pagedim[$this->page]['olm'] != $this->pagedim[$oldpage]['olm']) {
03612 $this->x = $x + ($this->pagedim[$this->page]['olm'] - $this->pagedim[$oldpage]['olm']);
03613 } else {
03614 $this->x = $x;
03615 }
03616 }
03617 }
03618 return true;
03619 }
03620 return false;
03621 }
03622
03641 public function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=0, $link='', $stretch=0, $ignore_min_height=false) {
03642
03643 $min_cell_height = $this->FontSize * $this->cell_height_ratio;
03644 if ($h < $min_cell_height) {
03645 $h = $min_cell_height;
03646 }
03647 $this->checkPageBreak($h);
03648 $this->_out($this->getCellCode($w, $h, $txt, $border, $ln, $align, $fill, $link, $stretch, $ignore_min_height));
03649 }
03650
03658 public function removeSHY($txt='') {
03659
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669 $txt = preg_replace('/([\\xc2]{1}[\\xad]{1})/', '', $txt);
03670 if (!$this->isunicode) {
03671 $txt = preg_replace('/([\\xad]{1})/', '', $txt);
03672 }
03673 return $txt;
03674 }
03675
03693 protected function getCellCode($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=0, $link='', $stretch=0, $ignore_min_height=false) {
03694 $txt = $this->removeSHY($txt);
03695 $rs = '';
03696 if (!$ignore_min_height) {
03697 $min_cell_height = $this->FontSize * $this->cell_height_ratio;
03698 if ($h < $min_cell_height) {
03699 $h = $min_cell_height;
03700 }
03701 }
03702 $k = $this->k;
03703 if ($this->empty_string($w) OR ($w <= 0)) {
03704 if ($this->rtl) {
03705 $w = $this->x - $this->lMargin;
03706 } else {
03707 $w = $this->w - $this->rMargin - $this->x;
03708 }
03709 }
03710 $s = '';
03711 if (($fill == 1) OR ($border == 1)) {
03712 if ($fill == 1) {
03713 $op = ($border == 1) ? 'B' : 'f';
03714 } else {
03715 $op = 'S';
03716 }
03717 if ($this->rtl) {
03718 $xk = (($this->x - $w) * $k);
03719 } else {
03720 $xk = ($this->x * $k);
03721 }
03722 $s .= sprintf('%.2F %.2F %.2F %.2F re %s ', $xk, (($this->h - $this->y) * $k), ($w * $k), (-$h * $k), $op);
03723 }
03724 if (is_string($border)) {
03725 $lm = ($this->LineWidth / 2);
03726 $x = $this->x;
03727 $y = $this->y;
03728 if (strpos($border,'L') !== false) {
03729 if ($this->rtl) {
03730 $xk = ($x - $w) * $k;
03731 } else {
03732 $xk = $x * $k;
03733 }
03734 $s .= sprintf('%.2F %.2F m %.2F %.2F l S ', $xk, (($this->h - $y + $lm) * $k), $xk, (($this->h - ($y + $h + $lm)) * $k));
03735 }
03736 if (strpos($border,'T') !== false) {
03737 if ($this->rtl) {
03738 $xk = ($x - $w + $lm) * $k;
03739 $xwk = ($x - $lm) * $k;
03740 } else {
03741 $xk = ($x - $lm) * $k;
03742 $xwk = ($x + $w + $lm) * $k;
03743 }
03744 $s .= sprintf('%.2F %.2F m %.2F %.2F l S ', $xk, (($this->h - $y) * $k), $xwk, (($this->h - $y) * $k));
03745 }
03746 if (strpos($border,'R') !== false) {
03747 if ($this->rtl) {
03748 $xk = $x * $k;
03749 } else {
03750 $xk = ($x + $w) * $k;
03751 }
03752 $s .= sprintf('%.2F %.2F m %.2F %.2F l S ', $xk, (($this->h - $y + $lm) * $k), $xk, (($this->h - ($y + $h + $lm))* $k));
03753 }
03754 if (strpos($border,'B') !== false) {
03755 if ($this->rtl) {
03756 $xk = ($x - $w + $lm) * $k;
03757 $xwk = ($x - $lm) * $k;
03758 } else {
03759 $xk = ($x - $lm) * $k;
03760 $xwk = ($x + $w + $lm) * $k;
03761 }
03762 $s .= sprintf('%.2F %.2F m %.2F %.2F l S ', $xk, (($this->h - ($y + $h)) * $k), $xwk, (($this->h - ($y + $h)) * $k));
03763 }
03764 }
03765 if ($txt != '') {
03766
03767 $width = $this->GetStringWidth($txt);
03768
03769 if ($width <= 0) {
03770 $ratio = 1;
03771 } else {
03772 $ratio = ($w - (2 * $this->cMargin)) / $width;
03773 }
03774
03775 if (($stretch > 0) AND (($ratio < 1) OR (($ratio > 1) AND (($stretch % 2) == 0)))) {
03776 if ($stretch > 2) {
03777
03778
03779 $char_space = (($w - $width - (2 * $this->cMargin)) * $this->k) / max($this->GetNumChars($txt)-1,1);
03780
03781 $rs .= sprintf('BT %.2F Tc ET ', $char_space);
03782 } else {
03783
03784
03785 $horiz_scale = $ratio * 100.0;
03786
03787 $rs .= sprintf('BT %.2F Tz ET ', $horiz_scale);
03788 }
03789 $align = '';
03790 $width = $w - (2 * $this->cMargin);
03791 } else {
03792 $stretch == 0;
03793 }
03794 if ($align == 'L') {
03795 if ($this->rtl) {
03796 $dx = $w - $width - $this->cMargin;
03797 } else {
03798 $dx = $this->cMargin;
03799 }
03800 } elseif ($align == 'R') {
03801 if ($this->rtl) {
03802 $dx = $this->cMargin;
03803 } else {
03804 $dx = $w - $width - $this->cMargin;
03805 }
03806 } elseif ($align == 'C') {
03807 $dx = ($w - $width) / 2;
03808 } elseif ($align == 'J') {
03809 if ($this->rtl) {
03810 $dx = $w - $width - $this->cMargin;
03811 } else {
03812 $dx = $this->cMargin;
03813 }
03814 } else {
03815 $dx = $this->cMargin;
03816 }
03817 if ($this->ColorFlag) {
03818 $s .= 'q '.$this->TextColor.' ';
03819 }
03820 $txt2 = $this->_escapetext($txt);
03821 if ($this->rtl) {
03822 $xdk = ($this->x - $dx - $width) * $k;
03823 } else {
03824 $xdk = ($this->x + $dx) * $k;
03825 }
03826
03827 if ($align == 'J') {
03828
03829 $ns = substr_count($txt, ' ');
03830 if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
03831
03832 $width = $this->GetStringWidth(str_replace(' ', '', $txt));
03833
03834 $spacewidth = -1000 * ($w - $width - (2 * $this->cMargin)) / ($ns?$ns:1) / $this->FontSize;
03835
03836 $txt2 = str_replace(chr(0).' ', ') '.($spacewidth).' (', $txt2);
03837 } else {
03838
03839 $width = $this->GetStringWidth($txt);
03840 $spacewidth = (($w - $width - (2 * $this->cMargin)) / ($ns?$ns:1)) * $this->k;
03841 $rs .= sprintf('BT %.3F Tw ET ', $spacewidth);
03842 }
03843 }
03844
03845
03846 $basefonty = $this->y + ($h/2) + ($this->FontSize/3);
03847
03848 $s .= sprintf('BT %.2F %.2F Td [(%s)] TJ ET', $xdk, (($this->h - $basefonty) * $k), $txt2);
03849 if ($this->rtl) {
03850 $xdx = $this->x - $dx - $width;
03851 } else {
03852 $xdx = $this->x + $dx;
03853 }
03854 if ($this->underline) {
03855 $s .= ' '.$this->_dounderline($xdx, $basefonty, $txt);
03856 }
03857 if ($this->linethrough) {
03858 $s .= ' '.$this->_dolinethrough($xdx, $basefonty, $txt);
03859 }
03860 if ($this->ColorFlag) {
03861 $s .= ' Q';
03862 }
03863 if ($link) {
03864 $this->Link($xdx, $this->y + (($h - $this->FontSize)/2), $width, $this->FontSize, $link, substr_count($txt, chr(32)));
03865 }
03866 }
03867
03868 if ($s) {
03869
03870 $rs .= $s;
03871
03872 if ($stretch > 2) {
03873
03874 $rs .= ' BT 0 Tc ET';
03875 } elseif ($stretch > 0) {
03876
03877 $rs .= ' BT 100 Tz ET';
03878 }
03879 }
03880
03881 if (!(($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) AND ($align == 'J')) {
03882 $rs .= ' BT 0 Tw ET';
03883 }
03884 $this->lasth = $h;
03885 if ($ln > 0) {
03886
03887 $this->y += $h;
03888 if ($ln == 1) {
03889 if ($this->rtl) {
03890 $this->x = $this->w - $this->rMargin;
03891 } else {
03892 $this->x = $this->lMargin;
03893 }
03894 }
03895 } else {
03896
03897 if ($this->rtl) {
03898 $this->x -= $w;
03899 } else {
03900 $this->x += $w;
03901 }
03902 }
03903 $gstyles = ''.$this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor.' '.$this->FillColor."\n";
03904 $rs = $gstyles.$rs;
03905 return $rs;
03906 }
03907
03931 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) {
03932 if ($this->empty_string($this->lasth) OR $reseth) {
03933
03934 $this->lasth = $this->FontSize * $this->cell_height_ratio;
03935 }
03936 if (!$this->empty_string($y)) {
03937 $this->SetY($y);
03938 } else {
03939 $y = $this->GetY();
03940 }
03941
03942 $this->checkPageBreak($h);
03943 $y = $this->GetY();
03944
03945 $startpage = $this->page;
03946 if (!$this->empty_string($x)) {
03947 $this->SetX($x);
03948 } else {
03949 $x = $this->GetX();
03950 }
03951 if ($this->empty_string($w) OR ($w <= 0)) {
03952 if ($this->rtl) {
03953 $w = $this->x - $this->lMargin;
03954 } else {
03955 $w = $this->w - $this->rMargin - $this->x;
03956 }
03957 }
03958
03959 $lMargin = $this->lMargin;
03960 $rMargin = $this->rMargin;
03961 if ($this->rtl) {
03962 $this->SetRightMargin($this->w - $this->x);
03963 $this->SetLeftMargin($this->x - $w);
03964 } else {
03965 $this->SetLeftMargin($this->x);
03966 $this->SetRightMargin($this->w - $this->x - $w);
03967 }
03968 $starty = $this->y;
03969 if ($autopadding) {
03970
03971 if ($this->cMargin < ($this->LineWidth / 2)) {
03972 $this->cMargin = ($this->LineWidth / 2);
03973 }
03974
03975 if (($this->lasth - $this->FontSize) < $this->LineWidth) {
03976 $this->y += $this->LineWidth / 2;
03977 }
03978
03979 $this->y += $this->cMargin;
03980 }
03981 if ($ishtml) {
03982
03983 $this->writeHTML($txt, true, 0, $reseth, true, $align);
03984 $nl = 1;
03985 } else {
03986
03987 $nl = $this->Write($this->lasth, $txt, '', 0, $align, true, $stretch, false, false, $maxh);
03988 }
03989 if ($autopadding) {
03990
03991 $this->y += $this->cMargin;
03992
03993 if (($this->lasth - $this->FontSize) < $this->LineWidth) {
03994 $this->y += $this->LineWidth / 2;
03995 }
03996 }
03997
03998 $currentY = $this->y;
03999
04000 $endpage = $this->page;
04001
04002 if ($endpage > $startpage) {
04003
04004 for ($page=$startpage; $page <= $endpage; ++$page) {
04005 $this->setPage($page);
04006 if ($page == $startpage) {
04007 $this->y = $starty;
04008 $h = $this->getPageHeight() - $starty - $this->getBreakMargin();
04009 $cborder = $this->getBorderMode($border, $position='start');
04010 } elseif ($page == $endpage) {
04011 $this->y = $this->tMargin;
04012 $h = $currentY - $this->tMargin;
04013 $cborder = $this->getBorderMode($border, $position='end');
04014 } else {
04015 $this->y = $this->tMargin;
04016 $h = $this->getPageHeight() - $this->tMargin - $this->getBreakMargin();
04017 $cborder = $this->getBorderMode($border, $position='middle');
04018 }
04019 $nx = $x;
04020
04021 if ($page > $startpage) {
04022 if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) {
04023 $nx = $x + ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']);
04024 } elseif ((!$this->rtl) AND ($this->pagedim[$page]['olm'] != $this->pagedim[$startpage]['olm'])) {
04025 $nx = $x + ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']);
04026 }
04027 }
04028 $this->SetX($nx);
04029 $ccode = $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, false);
04030 if ($cborder OR $fill) {
04031 $pagebuff = $this->getPageBuffer($this->page);
04032 $pstart = substr($pagebuff, 0, $this->intmrk[$this->page]);
04033 $pend = substr($pagebuff, $this->intmrk[$this->page]);
04034 $this->setPageBuffer($this->page, $pstart.$ccode."\n".$pend);
04035 $this->intmrk[$this->page] += strlen($ccode."\n");
04036 }
04037 }
04038 } else {
04039 $h = max($h, ($currentY - $y));
04040
04041 $this->SetY($y);
04042 $this->SetX($x);
04043
04044 $ccode = $this->getCellCode($w, $h, '', $border, 1, '', $fill, '', 0, true);
04045 if ($border OR $fill) {
04046 if (end($this->transfmrk[$this->page]) !== false) {
04047 $pagemarkkey = key($this->transfmrk[$this->page]);
04048 $pagemark = &$this->transfmrk[$this->page][$pagemarkkey];
04049 } elseif ($this->InFooter) {
04050 $pagemark = &$this->footerpos[$this->page];
04051 } else {
04052 $pagemark = &$this->intmrk[$this->page];
04053 }
04054 $pagebuff = $this->getPageBuffer($this->page);
04055 $pstart = substr($pagebuff, 0, $pagemark);
04056 $pend = substr($pagebuff, $pagemark);
04057 $this->setPageBuffer($this->page, $pstart.$ccode."\n".$pend);
04058 $pagemark += strlen($ccode."\n");
04059 }
04060 }
04061
04062 $currentY = $this->GetY();
04063
04064 $this->SetLeftMargin($lMargin);
04065 $this->SetRightMargin($rMargin);
04066 if ($ln > 0) {
04067
04068 $this->SetY($currentY);
04069 if ($ln == 2) {
04070 $this->SetX($x + $w);
04071 }
04072 } else {
04073
04074 $this->setPage($startpage);
04075 $this->y = $y;
04076 $this->SetX($x + $w);
04077 }
04078 $this->setContentMark();
04079 return $nl;
04080 }
04081
04090 protected function getBorderMode($border, $position='start') {
04091 if ((!$this->opencell) AND ($border == 1)) {
04092 return 1;
04093 }
04094 $cborder = '';
04095 switch ($position) {
04096 case 'start': {
04097 if ($border == 1) {
04098 $cborder = 'LTR';
04099 } else {
04100 if (!(false === strpos($border, 'L'))) {
04101 $cborder .= 'L';
04102 }
04103 if (!(false === strpos($border, 'T'))) {
04104 $cborder .= 'T';
04105 }
04106 if (!(false === strpos($border, 'R'))) {
04107 $cborder .= 'R';
04108 }
04109 if ((!$this->opencell) AND (!(false === strpos($border, 'B')))) {
04110 $cborder .= 'B';
04111 }
04112 }
04113 break;
04114 }
04115 case 'middle': {
04116 if ($border == 1) {
04117 $cborder = 'LR';
04118 } else {
04119 if (!(false === strpos($border, 'L'))) {
04120 $cborder .= 'L';
04121 }
04122 if ((!$this->opencell) AND (!(false === strpos($border, 'T')))) {
04123 $cborder .= 'T';
04124 }
04125 if (!(false === strpos($border, 'R'))) {
04126 $cborder .= 'R';
04127 }
04128 if ((!$this->opencell) AND (!(false === strpos($border, 'B')))) {
04129 $cborder .= 'B';
04130 }
04131 }
04132 break;
04133 }
04134 case 'end': {
04135 if ($border == 1) {
04136 $cborder = 'LRB';
04137 } else {
04138 if (!(false === strpos($border, 'L'))) {
04139 $cborder .= 'L';
04140 }
04141 if ((!$this->opencell) AND (!(false === strpos($border, 'T')))) {
04142 $cborder .= 'T';
04143 }
04144 if (!(false === strpos($border, 'R'))) {
04145 $cborder .= 'R';
04146 }
04147 if (!(false === strpos($border, 'B'))) {
04148 $cborder .= 'B';
04149 }
04150 }
04151 break;
04152 }
04153 default: {
04154 $cborder = $border;
04155 break;
04156 }
04157 }
04158 return $cborder;
04159 }
04160
04169 public function getNumLines($txt, $w=0) {
04170 $lines = 0;
04171 if ($this->empty_string($w) OR ($w <= 0)) {
04172 if ($this->rtl) {
04173 $w = $this->x - $this->lMargin;
04174 } else {
04175 $w = $this->w - $this->rMargin - $this->x;
04176 }
04177 }
04178
04179 $wmax = $w - (2 * $this->cMargin);
04180
04181 $txt = str_replace("\r", '', $txt);
04182
04183 if (substr($txt,-1) == "\n") {
04184 $txt = substr($txt, 0, -1);
04185 }
04186
04187 $txtblocks = explode("\n", $txt);
04188
04189 foreach ($txtblocks as $block) {
04190
04191 $lines += $this->empty_string($block) ? 1 : (ceil($this->GetStringWidth($block) / $wmax));
04192 }
04193 return $lines;
04194 }
04195
04212 public function Write($h, $txt, $link='', $fill=0, $align='', $ln=false, $stretch=0, $firstline=false, $firstblock=false, $maxh=0) {
04213 if (strlen($txt) == 0) {
04214 $txt = ' ';
04215 }
04216
04217 $s = str_replace("\r", '', $txt);
04218
04219 if (preg_match(K_RE_PATTERN_ARABIC, $s)) {
04220 $arabic = true;
04221 } else {
04222 $arabic = false;
04223 }
04224
04225 if ($arabic OR $this->tmprtl OR preg_match(K_RE_PATTERN_RTL, $txt)) {
04226 $rtlmode = true;
04227 } else {
04228 $rtlmode = false;
04229 }
04230
04231 $chrwidth = $this->GetCharWidth('.');
04232
04233 $chars = $this->UTF8StringToArray($s);
04234
04235 $uchars = $this->UTF8ArrayToUniArray($chars);
04236
04237 $nb = count($chars);
04238
04239 $shy_replacement = 45;
04240 $shy_replacement_char = $this->unichr($shy_replacement);
04241
04242 $shy_replacement_width = $this->GetCharWidth($shy_replacement);
04243
04244 $prevx = $this->x;
04245 $prevy = $this->y;
04246
04247 $maxy = $this->y + $maxh - $h - (2 * $this->cMargin);
04248
04249 if ($this->rtl) {
04250 $w = $this->x - $this->lMargin;
04251 } else {
04252 $w = $this->w - $this->rMargin - $this->x;
04253 }
04254
04255 $wmax = $w - (2 * $this->cMargin);
04256 if ((!$firstline) AND (($chrwidth > $wmax) OR ($this->GetCharWidth($chars[0]) > $wmax))) {
04257
04258 return '';
04259 }
04260 $i = 0;
04261 $j = 0;
04262 $sep = -1;
04263 $shy = false;
04264 $l = 0;
04265 $nl = 0;
04266 $linebreak = false;
04267
04268 while ($i < $nb) {
04269 if (($maxh > 0) AND ($this->y >= $maxy) ) {
04270 $firstline = true;
04271 }
04272
04273 $c = $chars[$i];
04274 if ($c == 10) {
04275
04276 if ($align == 'J') {
04277 if ($this->rtl) {
04278 $talign = 'R';
04279 } else {
04280 $talign = 'L';
04281 }
04282 } else {
04283 $talign = $align;
04284 }
04285 $tmpstr = $this->UniArrSubString($uchars, $j, $i);
04286 if ($firstline) {
04287 $startx = $this->x;
04288 $tmparr = array_slice($chars, $j, $i);
04289 if ($rtlmode) {
04290 $tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
04291 }
04292 $linew = $this->GetArrStringWidth($tmparr);
04293 unset($tmparr);
04294 if ($this->rtl) {
04295 $this->endlinex = $startx - $linew;
04296 } else {
04297 $this->endlinex = $startx + $linew;
04298 }
04299 $w = $linew;
04300 $tmpcmargin = $this->cMargin;
04301 if ($maxh == 0) {
04302 $this->cMargin = 0;
04303 }
04304 }
04305 $this->Cell($w, $h, $tmpstr, 0, 1, $talign, $fill, $link, $stretch);
04306 unset($tmpstr);
04307 if ($firstline) {
04308 $this->cMargin = $tmpcmargin;
04309 return ($this->UniArrSubString($uchars, $i));
04310 }
04311 ++$nl;
04312 $j = $i + 1;
04313 $l = 0;
04314 $sep = -1;
04315 $shy = false;
04316
04317 if ((($this->y + $this->lasth) > $this->PageBreakTrigger) AND (!$this->InFooter)) {
04318
04319 $this->AcceptPageBreak();
04320 }
04321 $w = $this->getRemainingWidth();
04322 $wmax = $w - (2 * $this->cMargin);
04323 } else {
04324
04325
04326
04327
04328
04329 if (($c != 160) AND (($c == 173) OR preg_match($this->re_spaces, $this->unichr($c)))) {
04330
04331 $sep = $i;
04332
04333 if ($c == 173) {
04334 $shy = true;
04335 } else {
04336 $shy = false;
04337 }
04338 }
04339
04340 if ((($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) AND ($arabic)) {
04341
04342
04343 $l = $this->GetArrStringWidth($this->utf8Bidi(array_slice($chars, $j, $i-$j+1), '', $this->tmprtl));
04344 } else {
04345 $l += $this->GetCharWidth($c);
04346 }
04347 if (($l > $wmax) OR ($shy AND (($l + $shy_replacement_width) > $wmax)) ) {
04348
04349 if ($sep == -1) {
04350
04351 if (($this->rtl AND ($this->x <= ($this->w - $this->rMargin - $chrwidth)))
04352 OR ((!$this->rtl) AND ($this->x >= ($this->lMargin + $chrwidth)))) {
04353
04354 $this->Cell($w, $h, '', 0, 1);
04355 $linebreak = true;
04356 if ($firstline) {
04357 return ($this->UniArrSubString($uchars, $j));
04358 }
04359 } else {
04360
04361 $tmpstr = $this->UniArrSubString($uchars, $j, $i);
04362 if ($firstline) {
04363 $startx = $this->x;
04364 $tmparr = array_slice($chars, $j, $i);
04365 if ($rtlmode) {
04366 $tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
04367 }
04368 $linew = $this->GetArrStringWidth($tmparr);
04369 unset($tmparr);
04370 if ($this->rtl) {
04371 $this->endlinex = $startx - $linew;
04372 } else {
04373 $this->endlinex = $startx + $linew;
04374 }
04375 $w = $linew;
04376 $tmpcmargin = $this->cMargin;
04377 if ($maxh == 0) {
04378 $this->cMargin = 0;
04379 }
04380 }
04381 $this->Cell($w, $h, $tmpstr, 0, 1, $align, $fill, $link, $stretch);
04382 unset($tmpstr);
04383 if ($firstline) {
04384 $this->cMargin = $tmpcmargin;
04385 return ($this->UniArrSubString($uchars, $i));
04386 }
04387 $j = $i;
04388 --$i;
04389 }
04390 } else {
04391
04392 if ($this->rtl AND (!$firstblock)) {
04393 $endspace = 1;
04394 } else {
04395 $endspace = 0;
04396 }
04397 if ($shy) {
04398
04399 $shy_width = $shy_replacement_width;
04400 if ($this->rtl) {
04401 $shy_char_left = $shy_replacement_char;
04402 $shy_char_right = '';
04403 } else {
04404 $shy_char_left = '';
04405 $shy_char_right = $shy_replacement_char;
04406 }
04407 } else {
04408 $shy_width = 0;
04409 $shy_char_left = '';
04410 $shy_char_right = '';
04411 }
04412 $tmpstr = $this->UniArrSubString($uchars, $j, ($sep + $endspace));
04413 if ($firstline) {
04414 $startx = $this->x;
04415 $tmparr = array_slice($chars, $j, ($sep + $endspace));
04416 if ($rtlmode) {
04417 $tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
04418 }
04419 $linew = $this->GetArrStringWidth($tmparr);
04420 unset($tmparr);
04421 if ($this->rtl) {
04422 $this->endlinex = $startx - $linew - $shy_width;
04423 } else {
04424 $this->endlinex = $startx + $linew + $shy_width;
04425 }
04426 $w = $linew;
04427 $tmpcmargin = $this->cMargin;
04428 if ($maxh == 0) {
04429 $this->cMargin = 0;
04430 }
04431 }
04432
04433 $this->Cell($w, $h, $shy_char_left.$tmpstr.$shy_char_right, 0, 1, $align, $fill, $link, $stretch);
04434 unset($tmpstr);
04435 if ($firstline) {
04436
04437 $this->cMargin = $tmpcmargin;
04438 return ($this->UniArrSubString($uchars, ($sep + $endspace)));
04439 }
04440 $i = $sep;
04441 $sep = -1;
04442 $shy = false;
04443 $j = ($i+1);
04444 }
04445
04446 if ((($this->y + $this->lasth) > $this->PageBreakTrigger) AND (!$this->InFooter)) {
04447
04448 $this->AcceptPageBreak();
04449 }
04450 $w = $this->getRemainingWidth();
04451 $wmax = $w - (2 * $this->cMargin);
04452 if ($linebreak) {
04453 $linebreak = false;
04454 } else {
04455 ++$nl;
04456 $l = 0;
04457 }
04458 }
04459 }
04460 ++$i;
04461 }
04462
04463 if ($l > 0) {
04464 switch ($align) {
04465 case 'J':
04466 case 'C': {
04467 $w = $w;
04468 break;
04469 }
04470 case 'L': {
04471 if ($this->rtl) {
04472 $w = $w;
04473 } else {
04474 $w = $l;
04475 }
04476 break;
04477 }
04478 case 'R': {
04479 if ($this->rtl) {
04480 $w = $l;
04481 } else {
04482 $w = $w;
04483 }
04484 break;
04485 }
04486 default: {
04487 $w = $l;
04488 break;
04489 }
04490 }
04491 $tmpstr = $this->UniArrSubString($uchars, $j, $nb);
04492 if ($firstline) {
04493 $startx = $this->x;
04494 $tmparr = array_slice($chars, $j, $nb);
04495 if ($rtlmode) {
04496 $tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
04497 }
04498 $linew = $this->GetArrStringWidth($tmparr);
04499 unset($tmparr);
04500 if ($this->rtl) {
04501 $this->endlinex = $startx - $linew;
04502 } else {
04503 $this->endlinex = $startx + $linew;
04504 }
04505 $w = $linew;
04506 $tmpcmargin = $this->cMargin;
04507 if ($maxh == 0) {
04508 $this->cMargin = 0;
04509 }
04510 }
04511 $this->Cell($w, $h, $tmpstr, 0, $ln, $align, $fill, $link, $stretch);
04512 unset($tmpstr);
04513 if ($firstline) {
04514 $this->cMargin = $tmpcmargin;
04515 return ($this->UniArrSubString($uchars, $nb));
04516 }
04517 ++$nl;
04518 }
04519 if ($firstline) {
04520 return '';
04521 }
04522 return $nl;
04523 }
04524
04530 protected function getRemainingWidth() {
04531 if ($this->rtl) {
04532 return ($this->x - $this->lMargin);
04533 } else {
04534 return ($this->w - $this->rMargin - $this->x);
04535 }
04536 }
04537
04546 public function UTF8ArrSubString($strarr, $start='', $end='') {
04547 if (strlen($start) == 0) {
04548 $start = 0;
04549 }
04550 if (strlen($end) == 0) {
04551 $end = count($strarr);
04552 }
04553 $string = '';
04554 for ($i=$start; $i < $end; ++$i) {
04555 $string .= $this->unichr($strarr[$i]);
04556 }
04557 return $string;
04558 }
04559
04569 public function UniArrSubString($uniarr, $start='', $end='') {
04570 if (strlen($start) == 0) {
04571 $start = 0;
04572 }
04573 if (strlen($end) == 0) {
04574 $end = count($uniarr);
04575 }
04576 $string = '';
04577 for ($i=$start; $i < $end; ++$i) {
04578 $string .= $uniarr[$i];
04579 }
04580 return $string;
04581 }
04582
04590 public function UTF8ArrayToUniArray($ta) {
04591 return array_map(array($this, 'unichr'), $ta);
04592 }
04593
04602 public function unichr($c) {
04603 if (!$this->isunicode) {
04604 return chr($c);
04605 } elseif ($c <= 0x7F) {
04606
04607 return chr($c);
04608 } elseif ($c <= 0x7FF) {
04609
04610 return chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F);
04611 } elseif ($c <= 0xFFFF) {
04612
04613 return chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
04614 } elseif ($c <= 0x10FFFF) {
04615
04616 return chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
04617 } else {
04618 return '';
04619 }
04620 }
04621
04653 public function Image($file, $x='', $y='', $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0, $fitbox=false, $hidden=false) {
04654 if ($x === '') {
04655 $x = $this->x;
04656 }
04657 if ($y === '') {
04658 $y = $this->y;
04659 }
04660
04661 $imsize = @getimagesize($file);
04662 if ($imsize === FALSE) {
04663
04664 $file = str_replace(' ', '%20', $file);
04665 $imsize = @getimagesize($file);
04666 if ($imsize === FALSE) {
04667 $this->Error('[Image] No such file or directory in '.$file);
04668 }
04669 }
04670
04671 list($pixw, $pixh) = $imsize;
04672
04673 if (($w <= 0) AND ($h <= 0)) {
04674
04675 $w = $this->pixelsToUnits($pixw);
04676 $h = $this->pixelsToUnits($pixh);
04677 } elseif ($w <= 0) {
04678 $w = $h * $pixw / $pixh;
04679 } elseif ($h <= 0) {
04680 $h = $w * $pixh / $pixw;
04681 } elseif ($fitbox AND ($w > 0) AND ($h > 0)) {
04682
04683 if ((($w * $pixh) / ($h * $pixw)) < 1) {
04684 $h = $w * $pixh / $pixw;
04685 } else {
04686 $w = $h * $pixw / $pixh;
04687 }
04688 }
04689
04690 $neww = round($w * $this->k * $dpi / $this->dpi);
04691 $newh = round($h * $this->k * $dpi / $this->dpi);
04692
04693 if (($neww * $newh) >= ($pixw * $pixh)) {
04694 $resize = false;
04695 }
04696
04697 if (!in_array($file, $this->imagekeys)) {
04698
04699 if ($type == '') {
04700 $fileinfo = pathinfo($file);
04701 if (isset($fileinfo['extension']) AND (!$this->empty_string($fileinfo['extension']))) {
04702 $type = $fileinfo['extension'];
04703 } else {
04704 $this->Error('Image file has no extension and no type was specified: '.$file);
04705 }
04706 }
04707 $type = strtolower($type);
04708 if ($type == 'jpg') {
04709 $type = 'jpeg';
04710 }
04711 $mqr = $this->get_mqr();
04712 $this->set_mqr(false);
04713
04714 $mtd = '_parse'.$type;
04715
04716 $gdfunction = 'imagecreatefrom'.$type;
04717 $info = false;
04718 if ((method_exists($this, $mtd)) AND (!($resize AND function_exists($gdfunction)))) {
04719
04720 $info = $this->$mtd($file);
04721 if ($info == 'pngalpha') {
04722 return $this->ImagePngAlpha($file, $x, $y, $w, $h, 'PNG', $link, $align, $resize, $dpi, $palign);
04723 }
04724 }
04725 if (!$info) {
04726 if (function_exists($gdfunction)) {
04727
04728 $img = $gdfunction($file);
04729 if ($resize) {
04730 $imgr = imagecreatetruecolor($neww, $newh);
04731 imagecopyresampled($imgr, $img, 0, 0, 0, 0, $neww, $newh, $pixw, $pixh);
04732 $info = $this->_toJPEG($imgr);
04733 } else {
04734 $info = $this->_toJPEG($img);
04735 }
04736 } elseif (extension_loaded('imagick')) {
04737
04738 $img = new Imagick();
04739 $img->readImage($file);
04740 if ($resize) {
04741 $img->resizeImage($neww, $newh, 10, 1, false);
04742 }
04743 $img->setCompressionQuality($this->jpeg_quality);
04744 $img->setImageFormat('jpeg');
04745 $tempname = tempnam(K_PATH_CACHE, 'jpg_');
04746 $img->writeImage($tempname);
04747 $info = $this->_parsejpeg($tempname);
04748 unlink($tempname);
04749 $img->destroy();
04750 } else {
04751 return;
04752 }
04753 }
04754 if ($info === false) {
04755
04756 return;
04757 }
04758 $this->set_mqr($mqr);
04759 if ($ismask) {
04760
04761 $info['cs'] = 'DeviceGray';
04762 }
04763 $info['i'] = $this->numimages + 1;
04764 if ($imgmask !== false) {
04765 $info['masked'] = $imgmask;
04766 }
04767
04768 $this->setImageBuffer($file, $info);
04769 } else {
04770 $info = $this->getImageBuffer($file);
04771 }
04772
04773 if ($this->checkPageBreak($h, $y)) {
04774 $y = $this->GetY() + $this->cMargin;
04775 }
04776
04777 $this->img_rb_y = $y + $h;
04778
04779 if ($this->rtl) {
04780 if ($palign == 'L') {
04781 $ximg = $this->lMargin;
04782
04783 $this->img_rb_x = $ximg + $w;
04784 } elseif ($palign == 'C') {
04785 $ximg = ($this->w - $x - $w) / 2;
04786
04787 $this->img_rb_x = $ximg + $w;
04788 } else {
04789 $ximg = $this->w - $x - $w;
04790
04791 $this->img_rb_x = $ximg;
04792 }
04793 } else {
04794 if ($palign == 'R') {
04795 $ximg = $this->w - $this->rMargin - $w;
04796
04797 $this->img_rb_x = $ximg;
04798 } elseif ($palign == 'C') {
04799 $ximg = ($this->w - $x - $w) / 2;
04800
04801 $this->img_rb_x = $ximg + $w;
04802 } else {
04803 $ximg = $x;
04804
04805 $this->img_rb_x = $ximg + $w;
04806 }
04807 }
04808 if ($ismask OR $hidden) {
04809
04810 return $info['i'];
04811 }
04812 $xkimg = $ximg * $this->k;
04813 $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']));
04814 if (!empty($border)) {
04815 $bx = $x;
04816 $by = $y;
04817 $this->x = $ximg;
04818 $this->y = $y;
04819 $this->Cell($w, $h, '', $border, 0, '', 0, '', 0);
04820 $this->x = $bx;
04821 $this->y = $by;
04822 }
04823 if ($link) {
04824 $this->Link($ximg, $y, $w, $h, $link, 0);
04825 }
04826
04827 switch($align) {
04828 case 'T': {
04829 $this->y = $y;
04830 $this->x = $this->img_rb_x;
04831 break;
04832 }
04833 case 'M': {
04834 $this->y = $y + round($h/2);
04835 $this->x = $this->img_rb_x;
04836 break;
04837 }
04838 case 'B': {
04839 $this->y = $this->img_rb_y;
04840 $this->x = $this->img_rb_x;
04841 break;
04842 }
04843 case 'N': {
04844 $this->SetY($this->img_rb_y);
04845 break;
04846 }
04847 default:{
04848 break;
04849 }
04850 }
04851 $this->endlinex = $this->img_rb_x;
04852 return $info['i'];
04853 }
04854
04860 public function set_mqr($mqr) {
04861 if (function_exists('set_magic_quotes_runtime')) {
04862 @set_magic_quotes_runtime($mqr);
04863 }
04864 }
04865
04871 public function get_mqr() {
04872 if (function_exists('get_magic_quotes_runtime')) {
04873 return @get_magic_quotes_runtime();
04874 }
04875 return 0;
04876 }
04877
04886 protected function _toJPEG($image) {
04887 $tempname = tempnam(K_PATH_CACHE, 'jpg_');
04888 imagejpeg($image, $tempname, $this->jpeg_quality);
04889 imagedestroy($image);
04890 $retvars = $this->_parsejpeg($tempname);
04891
04892 unlink($tempname);
04893 return $retvars;
04894 }
04895
04902 protected function _parsejpeg($file) {
04903 $a = getimagesize($file);
04904 if (empty($a)) {
04905 $this->Error('Missing or incorrect image file: '.$file);
04906 }
04907 if ($a[2] != 2) {
04908 $this->Error('Not a JPEG file: '.$file);
04909 }
04910 if ((!isset($a['channels'])) OR ($a['channels'] == 3)) {
04911 $colspace = 'DeviceRGB';
04912 } elseif ($a['channels'] == 4) {
04913 $colspace = 'DeviceCMYK';
04914 } else {
04915 $colspace = 'DeviceGray';
04916 }
04917 $bpc = isset($a['bits']) ? $a['bits'] : 8;
04918 $data = file_get_contents($file);
04919 return array('w' => $a[0], 'h' => $a[1], 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'DCTDecode', 'data' => $data);
04920 }
04921
04928 protected function _parsepng($file) {
04929 $f = fopen($file, 'rb');
04930 if ($f === false) {
04931 $this->Error('Can\'t open image file: '.$file);
04932 }
04933
04934 if (fread($f, 8) != chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
04935 $this->Error('Not a PNG file: '.$file);
04936 }
04937
04938 fread($f, 4);
04939 if (fread($f, 4) != 'IHDR') {
04940 $this->Error('Incorrect PNG file: '.$file);
04941 }
04942 $w = $this->_freadint($f);
04943 $h = $this->_freadint($f);
04944 $bpc = ord(fread($f, 1));
04945 if ($bpc > 8) {
04946
04947 fclose($f);
04948 return false;
04949 }
04950 $ct = ord(fread($f, 1));
04951 if ($ct == 0) {
04952 $colspace = 'DeviceGray';
04953 } elseif ($ct == 2) {
04954 $colspace = 'DeviceRGB';
04955 } elseif ($ct == 3) {
04956 $colspace = 'Indexed';
04957 } else {
04958
04959 fclose($f);
04960 return 'pngalpha';
04961 }
04962 if (ord(fread($f, 1)) != 0) {
04963
04964 fclose($f);
04965 return false;
04966 }
04967 if (ord(fread($f, 1)) != 0) {
04968
04969 fclose($f);
04970 return false;
04971 }
04972 if (ord(fread($f, 1)) != 0) {
04973
04974 fclose($f);
04975 return false;
04976 }
04977 fread($f, 4);
04978 $parms = '/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
04979
04980 $pal = '';
04981 $trns = '';
04982 $data = '';
04983 do {
04984 $n = $this->_freadint($f);
04985 $type = fread($f, 4);
04986 if ($type == 'PLTE') {
04987
04988 $pal = $this->rfread($f, $n);
04989 fread($f, 4);
04990 } elseif ($type == 'tRNS') {
04991
04992 $t = $this->rfread($f, $n);
04993 if ($ct == 0) {
04994 $trns = array(ord(substr($t, 1, 1)));
04995 } elseif ($ct == 2) {
04996 $trns = array(ord(substr($t, 1, 1)), ord(substr($t, 3, 1)), ord(substr($t, 5, 1)));
04997 } else {
04998 $pos = strpos($t, chr(0));
04999 if ($pos !== false) {
05000 $trns = array($pos);
05001 }
05002 }
05003 fread($f, 4);
05004 } elseif ($type == 'IDAT') {
05005
05006 $data .= $this->rfread($f, $n);
05007 fread($f, 4);
05008 } elseif ($type == 'IEND') {
05009 break;
05010 } else {
05011 $this->rfread($f, $n + 4);
05012 }
05013 } while ($n);
05014 if (($colspace == 'Indexed') AND (empty($pal))) {
05015
05016 fclose($f);
05017 return false;
05018 }
05019 fclose($f);
05020 return array('w' => $w, 'h' => $h, 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'FlateDecode', 'parms' => $parms, 'pal' => $pal, 'trns' => $trns, 'data' => $data);
05021 }
05022
05033 protected function rfread($handle, $length) {
05034 $data = fread($handle, $length);
05035 if ($data === false) {
05036 return false;
05037 }
05038 $rest = $length - strlen($data);
05039 if ($rest > 0) {
05040 $data .= $this->rfread($handle, $rest);
05041 }
05042 return $data;
05043 }
05044
05063 protected function ImagePngAlpha($file, $x='', $y='', $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='') {
05064
05065 list($wpx, $hpx) = getimagesize($file);
05066
05067 $img = imagecreatefrompng($file);
05068 $imgalpha = imagecreate($wpx, $hpx);
05069
05070 for ($c = 0; $c < 256; ++$c) {
05071 ImageColorAllocate($imgalpha, $c, $c, $c);
05072 }
05073
05074 for ($xpx = 0; $xpx < $wpx; ++$xpx) {
05075 for ($ypx = 0; $ypx < $hpx; ++$ypx) {
05076 $colorindex = imagecolorat($img, $xpx, $ypx);
05077 $col = imagecolorsforindex($img, $colorindex);
05078 imagesetpixel($imgalpha, $xpx, $ypx, $this->getGDgamma((127 - $col['alpha']) * 255 / 127));
05079 }
05080 }
05081
05082 $tempfile_alpha = tempnam(K_PATH_CACHE, 'mska_');
05083 imagepng($imgalpha, $tempfile_alpha);
05084 imagedestroy($imgalpha);
05085
05086 $imgplain = imagecreatetruecolor($wpx, $hpx);
05087 imagecopy($imgplain, $img, 0, 0, 0, 0, $wpx, $hpx);
05088
05089 $tempfile_plain = tempnam(K_PATH_CACHE, 'mskp_');
05090 imagepng($imgplain, $tempfile_plain);
05091 imagedestroy($imgplain);
05092
05093 $imgmask = $this->Image($tempfile_alpha, $x, $y, $w, $h, 'PNG', '', '', $resize, $dpi, '', true, false);
05094
05095 $this->Image($tempfile_plain, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, false, $imgmask);
05096
05097 unlink($tempfile_alpha);
05098 unlink($tempfile_plain);
05099 }
05100
05107 protected function getGDgamma($v) {
05108 return (pow(($v / 255), 2.2) * 255);
05109 }
05110
05120 public function Ln($h='', $cell=false) {
05121
05122 if ($cell) {
05123 $cellmargin = $this->cMargin;
05124 } else {
05125 $cellmargin = 0;
05126 }
05127 if ($this->rtl) {
05128 $this->x = $this->w - $this->rMargin - $cellmargin;
05129 } else {
05130 $this->x = $this->lMargin + $cellmargin;
05131 }
05132 if (is_string($h)) {
05133 $this->y += $this->lasth;
05134 } else {
05135 $this->y += $h;
05136 }
05137 $this->newline = true;
05138 }
05139
05148 public function GetX() {
05149
05150 if ($this->rtl) {
05151 return ($this->w - $this->x);
05152 } else {
05153 return $this->x;
05154 }
05155 }
05156
05164 public function GetAbsX() {
05165 return $this->x;
05166 }
05167
05175 public function GetY() {
05176
05177 return $this->y;
05178 }
05179
05188 public function SetX($x) {
05189
05190 if ($this->rtl) {
05191 if ($x >= 0) {
05192 $this->x = $this->w - $x;
05193 } else {
05194 $this->x = abs($x);
05195 }
05196 } else {
05197 if ($x >= 0) {
05198 $this->x = $x;
05199 } else {
05200 $this->x = $this->w + $x;
05201 }
05202 }
05203 if ($this->x < 0) {
05204 $this->x = 0;
05205 }
05206 if ($this->x > $this->w) {
05207 $this->x = $this->w;
05208 }
05209 }
05210
05220 public function SetY($y, $resetx=true) {
05221 if ($resetx) {
05222
05223 if ($this->rtl) {
05224 $this->x = $this->w - $this->rMargin;
05225 } else {
05226 $this->x = $this->lMargin;
05227 }
05228 }
05229 if ($y >= 0) {
05230 $this->y = $y;
05231 } else {
05232 $this->y = $this->h + $y;
05233 }
05234 if ($this->y < 0) {
05235 $this->y = 0;
05236 }
05237 if ($this->y > $this->h) {
05238 $this->y = $this->h;
05239 }
05240 }
05241
05251 public function SetXY($x, $y) {
05252
05253 $this->SetY($y);
05254 $this->SetX($x);
05255 }
05256
05267 public function Output($name='doc.pdf', $dest='I') {
05268
05269
05270 if ($this->state < 3) {
05271 $this->Close();
05272 }
05273
05274 if (is_bool($dest)) {
05275 $dest = $dest ? 'D' : 'F';
05276 }
05277 $dest = strtoupper($dest);
05278 if ($dest != 'F') {
05279 $name = preg_replace('/[\s]+/', '_', $name);
05280 $name = preg_replace('/[^a-zA-Z0-9_\.-]/', '', $name);
05281 }
05282 if ($this->sign) {
05283
05284
05285 $pdfdoc = $this->getBuffer();
05286
05287 $pdfdoc = substr($pdfdoc, 0, -1);
05288
05289 if (isset($this->diskcache) AND $this->diskcache) {
05290
05291 unlink($this->buffer);
05292 }
05293 unset($this->buffer);
05294
05295 $byterange_string_len = strlen($this->byterange_string);
05296
05297 $byte_range = array();
05298 $byte_range[0] = 0;
05299 $byte_range[1] = strpos($pdfdoc, $this->byterange_string) + $byterange_string_len + 10;
05300 $byte_range[2] = $byte_range[1] + $this->signature_max_lenght + 2;
05301 $byte_range[3] = strlen($pdfdoc) - $byte_range[2];
05302 $pdfdoc = substr($pdfdoc, 0, $byte_range[1]).substr($pdfdoc, $byte_range[2]);
05303
05304 $byterange = sprintf('/ByteRange[0 %u %u %u]', $byte_range[1], $byte_range[2], $byte_range[3]);
05305 $byterange .= str_repeat(' ', ($byterange_string_len - strlen($byterange)));
05306 $pdfdoc = str_replace($this->byterange_string, $byterange, $pdfdoc);
05307
05308 $tempdoc = tempnam(K_PATH_CACHE, 'tmppdf_');
05309 $f = fopen($tempdoc, 'wb');
05310 if (!$f) {
05311 $this->Error('Unable to create temporary file: '.$tempdoc);
05312 }
05313 $pdfdoc_lenght = strlen($pdfdoc);
05314 fwrite($f, $pdfdoc, $pdfdoc_lenght);
05315 fclose($f);
05316
05317 $tempsign = tempnam(K_PATH_CACHE, 'tmpsig_');
05318 if (empty($this->signature_data['extracerts'])) {
05319 openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED);
05320 } else {
05321 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']);
05322 }
05323 unlink($tempdoc);
05324
05325 $signature = file_get_contents($tempsign, false, null, $pdfdoc_lenght);
05326 unlink($tempsign);
05327
05328 $signature = substr($signature, (strpos($signature, "%%EOF\n\n------") + 13));
05329 $tmparr = explode("\n\n", $signature);
05330 $signature = $tmparr[1];
05331 unset($tmparr);
05332
05333 $signature = base64_decode(trim($signature));
05334
05335 $signature = current(unpack('H*', $signature));
05336 $signature = str_pad($signature, $this->signature_max_lenght, '0');
05337
05338 $pdfdoc = substr($pdfdoc, 0, $byte_range[1]).'<'.$signature.'>'.substr($pdfdoc, ($byte_range[1]));
05339 $this->diskcache = false;
05340 $this->buffer = &$pdfdoc;
05341 $this->bufferlen = strlen($pdfdoc);
05342 }
05343 switch($dest) {
05344 case 'I': {
05345
05346 if (ob_get_contents()) {
05347 $this->Error('Some data has already been output, can\'t send PDF file');
05348 }
05349 if (php_sapi_name() != 'cli') {
05350
05351 header('Content-Type: application/pdf');
05352 if (headers_sent()) {
05353 $this->Error('Some data has already been output to browser, can\'t send PDF file');
05354 }
05355 header('Cache-Control: public, must-revalidate, max-age=0');
05356 header('Pragma: public');
05357 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
05358 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
05359 header('Content-Length: '.$this->bufferlen);
05360 header('Content-Disposition: inline; filename="'.basename($name).'";');
05361 }
05362 echo $this->getBuffer();
05363 break;
05364 }
05365 case 'D': {
05366
05367 if (ob_get_contents()) {
05368 $this->Error('Some data has already been output, can\'t send PDF file');
05369 }
05370 header('Content-Description: File Transfer');
05371 if (headers_sent()) {
05372 $this->Error('Some data has already been output to browser, can\'t send PDF file');
05373 }
05374 header('Cache-Control: public, must-revalidate, max-age=0');
05375 header('Pragma: public');
05376 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
05377 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
05378
05379 header('Content-Type: application/force-download');
05380 header('Content-Type: application/octet-stream', false);
05381 header('Content-Type: application/download', false);
05382 header('Content-Type: application/pdf', false);
05383
05384 header('Content-Disposition: attachment; filename="'.basename($name).'";');
05385 header('Content-Transfer-Encoding: binary');
05386 header('Content-Length: '.$this->bufferlen);
05387 echo $this->getBuffer();
05388 break;
05389 }
05390 case 'F': {
05391
05392 if ($this->diskcache) {
05393 copy($this->buffer, $name);
05394 } else {
05395 $f = fopen($name, 'wb');
05396 if (!$f) {
05397 $this->Error('Unable to create output file: '.$name);
05398 }
05399 fwrite($f, $this->getBuffer(), $this->bufferlen);
05400 fclose($f);
05401 }
05402 break;
05403 }
05404 case 'S': {
05405
05406 return $this->getBuffer();
05407 }
05408 default: {
05409 $this->Error('Incorrect output destination: '.$dest);
05410 }
05411 }
05412 return '';
05413 }
05414
05422 public function _destroy($destroyall=false, $preserve_objcopy=false) {
05423 if ($destroyall AND isset($this->diskcache) AND $this->diskcache AND (!$preserve_objcopy) AND (!$this->empty_string($this->buffer))) {
05424
05425 unlink($this->buffer);
05426 }
05427 foreach (array_keys(get_object_vars($this)) as $val) {
05428 if ($destroyall OR (
05429 ($val != 'internal_encoding')
05430 AND ($val != 'state')
05431 AND ($val != 'bufferlen')
05432 AND ($val != 'buffer')
05433 AND ($val != 'diskcache')
05434 AND ($val != 'sign')
05435 AND ($val != 'signature_data')
05436 AND ($val != 'signature_max_lenght')
05437 AND ($val != 'byterange_string')
05438 )) {
05439 if (!$preserve_objcopy OR ($val != 'objcopy')) {
05440 unset($this->$val);
05441 }
05442 }
05443 }
05444 }
05445
05450 protected function _dochecks() {
05451
05452 if (1.1 == 1) {
05453 $this->Error('Don\'t alter the locale before including class file');
05454 }
05455
05456 if (sprintf('%.1F', 1.0) != '1.0') {
05457 setlocale(LC_NUMERIC, 'C');
05458 }
05459 }
05460
05466 protected function _getfontpath() {
05467 if (!defined('K_PATH_FONTS') AND is_dir(dirname(__FILE__).'/fonts')) {
05468 define('K_PATH_FONTS', dirname(__FILE__).'/fonts/');
05469 }
05470 return defined('K_PATH_FONTS') ? K_PATH_FONTS : '';
05471 }
05472
05477 protected function _putpages() {
05478 $nb = $this->numpages;
05479 if (!empty($this->AliasNbPages)) {
05480 $nbs = $this->formatPageNumber($nb);
05481 $nbu = $this->UTF8ToUTF16BE($nbs, false);
05482 $alias_a = $this->_escape($this->AliasNbPages);
05483 $alias_au = $this->_escape('{'.$this->AliasNbPages.'}');
05484 if ($this->isunicode) {
05485 $alias_b = $this->_escape($this->UTF8ToLatin1($this->AliasNbPages));
05486 $alias_bu = $this->_escape($this->UTF8ToLatin1('{'.$this->AliasNbPages.'}'));
05487 $alias_c = $this->_escape($this->utf8StrRev($this->AliasNbPages, false, $this->tmprtl));
05488 $alias_cu = $this->_escape($this->utf8StrRev('{'.$this->AliasNbPages.'}', false, $this->tmprtl));
05489 }
05490 }
05491 if (!empty($this->AliasNumPage)) {
05492 $alias_pa = $this->_escape($this->AliasNumPage);
05493 $alias_pau = $this->_escape('{'.$this->AliasNumPage.'}');
05494 if ($this->isunicode) {
05495 $alias_pb = $this->_escape($this->UTF8ToLatin1($this->AliasNumPage));
05496 $alias_pbu = $this->_escape($this->UTF8ToLatin1('{'.$this->AliasNumPage.'}'));
05497 $alias_pc = $this->_escape($this->utf8StrRev($this->AliasNumPage, false, $this->tmprtl));
05498 $alias_pcu = $this->_escape($this->utf8StrRev('{'.$this->AliasNumPage.'}', false, $this->tmprtl));
05499 }
05500 }
05501 $pagegroupnum = 0;
05502 $filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
05503 for ($n=1; $n <= $nb; ++$n) {
05504 $temppage = $this->getPageBuffer($n);
05505 if (!empty($this->pagegroups)) {
05506 if(isset($this->newpagegroup[$n])) {
05507 $pagegroupnum = 0;
05508 }
05509 ++$pagegroupnum;
05510 foreach ($this->pagegroups as $k => $v) {
05511
05512 $vs = $this->formatPageNumber($v);
05513 $vu = $this->UTF8ToUTF16BE($vs, false);
05514 $alias_ga = $this->_escape($k);
05515 $alias_gau = $this->_escape('{'.$k.'}');
05516 if ($this->isunicode) {
05517 $alias_gb = $this->_escape($this->UTF8ToLatin1($k));
05518 $alias_gbu = $this->_escape($this->UTF8ToLatin1('{'.$k.'}'));
05519 $alias_gc = $this->_escape($this->utf8StrRev($k, false, $this->tmprtl));
05520 $alias_gcu = $this->_escape($this->utf8StrRev('{'.$k.'}', false, $this->tmprtl));
05521 }
05522 $temppage = str_replace($alias_gau, $vu, $temppage);
05523 if ($this->isunicode) {
05524 $temppage = str_replace($alias_gbu, $vu, $temppage);
05525 $temppage = str_replace($alias_gcu, $vu, $temppage);
05526 $temppage = str_replace($alias_gb, $vs, $temppage);
05527 $temppage = str_replace($alias_gc, $vs, $temppage);
05528 }
05529 $temppage = str_replace($alias_ga, $vs, $temppage);
05530
05531 $pvs = $this->formatPageNumber($pagegroupnum);
05532 $pvu = $this->UTF8ToUTF16BE($pvs, false);
05533 $pk = str_replace('{nb', '{pnb', $k);
05534 $alias_pga = $this->_escape($pk);
05535 $alias_pgau = $this->_escape('{'.$pk.'}');
05536 if ($this->isunicode) {
05537 $alias_pgb = $this->_escape($this->UTF8ToLatin1($pk));
05538 $alias_pgbu = $this->_escape($this->UTF8ToLatin1('{'.$pk.'}'));
05539 $alias_pgc = $this->_escape($this->utf8StrRev($pk, false, $this->tmprtl));
05540 $alias_pgcu = $this->_escape($this->utf8StrRev('{'.$pk.'}', false, $this->tmprtl));
05541 }
05542 $temppage = str_replace($alias_pgau, $pvu, $temppage);
05543 if ($this->isunicode) {
05544 $temppage = str_replace($alias_pgbu, $pvu, $temppage);
05545 $temppage = str_replace($alias_pgcu, $pvu, $temppage);
05546 $temppage = str_replace($alias_pgb, $pvs, $temppage);
05547 $temppage = str_replace($alias_pgc, $pvs, $temppage);
05548 }
05549 $temppage = str_replace($alias_pga, $pvs, $temppage);
05550 }
05551 }
05552 if (!empty($this->AliasNbPages)) {
05553
05554 $temppage = str_replace($alias_au, $nbu, $temppage);
05555 if ($this->isunicode) {
05556 $temppage = str_replace($alias_bu, $nbu, $temppage);
05557 $temppage = str_replace($alias_cu, $nbu, $temppage);
05558 $temppage = str_replace($alias_b, $nbs, $temppage);
05559 $temppage = str_replace($alias_c, $nbs, $temppage);
05560 }
05561 $temppage = str_replace($alias_a, $nbs, $temppage);
05562 }
05563 if (!empty($this->AliasNumPage)) {
05564
05565 $pnbs = $this->formatPageNumber($n);
05566 $pnbu = $this->UTF8ToUTF16BE($pnbs, false);
05567 $temppage = str_replace($alias_pau, $pnbu, $temppage);
05568 if ($this->isunicode) {
05569 $temppage = str_replace($alias_pbu, $pnbu, $temppage);
05570 $temppage = str_replace($alias_pcu, $pnbu, $temppage);
05571 $temppage = str_replace($alias_pb, $pnbs, $temppage);
05572 $temppage = str_replace($alias_pc, $pnbs, $temppage);
05573 }
05574 $temppage = str_replace($alias_pa, $pnbs, $temppage);
05575 }
05576 $temppage = str_replace($this->epsmarker, '', $temppage);
05577
05578 $this->page_obj_id[$n] = $this->_newobj();
05579 $this->_out('<</Type /Page');
05580 $this->_out('/Parent 1 0 R');
05581 $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]', $this->pagedim[$n]['w'], $this->pagedim[$n]['h']));
05582 $this->_out('/Resources 2 0 R');
05583 $this->_putannotsrefs($n);
05584 $this->_out('/Contents '.($this->n + 1).' 0 R>>');
05585 $this->_out('endobj');
05586
05587 $p = ($this->compress) ? gzcompress($temppage) : $temppage;
05588 $this->_newobj();
05589 $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
05590 $this->_putstream($p);
05591 $this->_out('endobj');
05592 if ($this->diskcache) {
05593
05594 unlink($this->pages[$n]);
05595 }
05596 }
05597
05598 $this->offsets[1] = $this->bufferlen;
05599 $this->_out('1 0 obj');
05600 $this->_out('<</Type /Pages');
05601 $this->_out('/Kids [');
05602 foreach($this->page_obj_id as $page_obj) {
05603 $this->_out($page_obj.' 0 R');
05604 }
05605 $this->_out(']');
05606 $this->_out('/Count '.$nb);
05607 $this->_out('>>');
05608 $this->_out('endobj');
05609 }
05610
05618 protected function _putannotsrefs($n) {
05619 if (!(isset($this->PageAnnots[$n]) OR ($this->sign AND isset($this->signature_data['cert_type'])))) {
05620 return;
05621 }
05622 $this->_out('/Annots [');
05623 if (isset($this->PageAnnots[$n])) {
05624 $num_annots = count($this->PageAnnots[$n]);
05625 for ($i = 0; $i < $num_annots; ++$i) {
05626 ++$this->curr_annot_obj_id;
05627 if (!in_array($this->curr_annot_obj_id, $this->radio_groups)) {
05628 $this->_out($this->curr_annot_obj_id.' 0 R');
05629 } else {
05630 ++$num_annots;
05631 }
05632 }
05633 }
05634 if (($n==1) AND $this->sign AND isset($this->signature_data['cert_type'])) {
05635
05636 $this->_out($this->sig_annot_ref);
05637 }
05638 $this->_out(']');
05639 }
05640
05649 protected function _putannotsobjs() {
05650
05651 $this->annot_obj_id = $this->annots_start_obj_id;
05652 for ($n=1; $n <= $this->numpages; ++$n) {
05653 if (isset($this->PageAnnots[$n])) {
05654
05655 foreach ($this->PageAnnots[$n] as $key => $pl) {
05656
05657 if (isset($this->radiobutton_groups[$n][$pl['txt']]) AND is_array($this->radiobutton_groups[$n][$pl['txt']])) {
05658 $annots = '<<';
05659 $annots .= ' /Type /Annot';
05660 $annots .= ' /Subtype /Widget';
05661 $annots .= ' /T '.$this->_datastring($pl['txt']);
05662 $annots .= ' /FT /Btn';
05663 $annots .= ' /Ff 49152';
05664 $annots .= ' /Kids [';
05665 foreach ($this->radiobutton_groups[$n][$pl['txt']] as $data) {
05666 $annots .= ' '.$data['kid'].' 0 R';
05667 if ($data['def'] !== 'Off') {
05668 $defval = $data['def'];
05669 }
05670 }
05671 $annots .= ' ]';
05672 if (isset($defval)) {
05673 $annots .= ' /V /'.$defval;
05674 }
05675 $annots .= ' >>';
05676 ++$this->annot_obj_id;
05677 $this->offsets[$this->annot_obj_id] = $this->bufferlen;
05678 $this->_out($this->annot_obj_id.' 0 obj');
05679 $this->_out($annots);
05680 $this->_out('endobj');
05681 $this->form_obj_id[] = $this->annot_obj_id;
05682
05683 $this->radiobutton_groups[$n][$pl['txt']] = $this->annot_obj_id;
05684 }
05685 $formfield = false;
05686 $pl['opt'] = array_change_key_case($pl['opt'], CASE_LOWER);
05687 $a = $pl['x'] * $this->k;
05688 $b = $this->pagedim[$n]['h'] - (($pl['y'] + $pl['h']) * $this->k);
05689 $c = $pl['w'] * $this->k;
05690 $d = $pl['h'] * $this->k;
05691 $rect = sprintf('%.2F %.2F %.2F %.2F', $a, $b, $a+$c, $b+$d);
05692
05693 $annots = '<</Type /Annot';
05694 $annots .= ' /Subtype /'.$pl['opt']['subtype'];
05695 $annots .= ' /Rect ['.$rect.']';
05696 $ft = array('Btn', 'Tx', 'Ch', 'Sig');
05697 if (isset($pl['opt']['ft']) AND in_array($pl['opt']['ft'], $ft)) {
05698 $annots .= ' /FT /'.$pl['opt']['ft'];
05699 $formfield = true;
05700 }
05701 $annots .= ' /Contents '.$this->_textstring($pl['txt']);
05702 $annots .= ' /P '.$this->page_obj_id[$n].' 0 R';
05703 $annots .= ' /NM '.$this->_datastring(sprintf('%04u-%04u', $n, $key));
05704 $annots .= ' /M '.$this->_datestring();
05705 if (isset($pl['opt']['f'])) {
05706 $val = 0;
05707 if (is_array($pl['opt']['f'])) {
05708 foreach ($pl['opt']['f'] as $f) {
05709 switch (strtolower($f)) {
05710 case 'invisible': {
05711 $val += 1 << 0;
05712 break;
05713 }
05714 case 'hidden': {
05715 $val += 1 << 1;
05716 break;
05717 }
05718 case 'print': {
05719 $val += 1 << 2;
05720 break;
05721 }
05722 case 'nozoom': {
05723 $val += 1 << 3;
05724 break;
05725 }
05726 case 'norotate': {
05727 $val += 1 << 4;
05728 break;
05729 }
05730 case 'noview': {
05731 $val += 1 << 5;
05732 break;
05733 }
05734 case 'readonly': {
05735 $val += 1 << 6;
05736 break;
05737 }
05738 case 'locked': {
05739 $val += 1 << 8;
05740 break;
05741 }
05742 case 'togglenoview': {
05743 $val += 1 << 9;
05744 break;
05745 }
05746 case 'lockedcontents': {
05747 $val += 1 << 10;
05748 break;
05749 }
05750 default: {
05751 break;
05752 }
05753 }
05754 }
05755 } else {
05756 $val = intval($pl['opt']['f']);
05757 }
05758 $annots .= ' /F '.intval($val);
05759 }
05760 if (isset($pl['opt']['as']) AND is_string($pl['opt']['as'])) {
05761 $annots .= ' /AS /'.$pl['opt']['as'];
05762 }
05763 if (isset($pl['opt']['ap'])) {
05764
05765 $annots .= ' /AP <<';
05766 if (is_array($pl['opt']['ap'])) {
05767 foreach ($pl['opt']['ap'] as $apmode => $apdef) {
05768
05769 $annots .= ' /'.strtoupper($apmode);
05770 if (is_array($apdef)) {
05771 $annots .= ' <<';
05772 foreach ($apdef as $apstate => $stream) {
05773
05774 $apsobjid = $this->_putAPXObject($c, $d, $stream);
05775 $annots .= ' /'.$apstate.' '.$apsobjid.' 0 R';
05776 }
05777 $annots .= ' >>';
05778 } else {
05779
05780 $apsobjid = $this->_putAPXObject($c, $d, $apdef);
05781 $annots .= ' '.$apsobjid.' 0 R';
05782 }
05783 }
05784 } else {
05785 $annots .= $pl['opt']['ap'];
05786 }
05787 $annots .= ' >>';
05788 }
05789 if (isset($pl['opt']['bs']) AND (is_array($pl['opt']['bs']))) {
05790 $annots .= ' /BS <<';
05791 $annots .= ' /Type /Border';
05792 if (isset($pl['opt']['bs']['w'])) {
05793 $annots .= ' /W '.intval($pl['opt']['bs']['w']);
05794 }
05795 $bstyles = array('S', 'D', 'B', 'I', 'U');
05796 if (isset($pl['opt']['bs']['s']) AND in_array($pl['opt']['bs']['s'], $bstyles)) {
05797 $annots .= ' /S /'.$pl['opt']['bs']['s'];
05798 }
05799 if (isset($pl['opt']['bs']['d']) AND (is_array($pl['opt']['bs']['d']))) {
05800 $annots .= ' /D [';
05801 foreach ($pl['opt']['bs']['d'] as $cord) {
05802 $annots .= ' '.intval($cord);
05803 }
05804 $annots .= ']';
05805 }
05806 $annots .= ' >>';
05807 } else {
05808 $annots .= ' /Border [';
05809 if (isset($pl['opt']['border']) AND (count($pl['opt']['border']) >= 3)) {
05810 $annots .= intval($pl['opt']['border'][0]).' ';
05811 $annots .= intval($pl['opt']['border'][1]).' ';
05812 $annots .= intval($pl['opt']['border'][2]);
05813 if (isset($pl['opt']['border'][3]) AND is_array($pl['opt']['border'][3])) {
05814 $annots .= ' [';
05815 foreach ($pl['opt']['border'][3] as $dash) {
05816 $annots .= intval($dash).' ';
05817 }
05818 $annots .= ']';
05819 }
05820 } else {
05821 $annots .= '0 0 0';
05822 }
05823 $annots .= ']';
05824 }
05825 if (isset($pl['opt']['be']) AND (is_array($pl['opt']['be']))) {
05826 $annots .= ' /BE <<';
05827 $bstyles = array('S', 'C');
05828 if (isset($pl['opt']['be']['s']) AND in_array($pl['opt']['be']['s'], $markups)) {
05829 $annots .= ' /S /'.$pl['opt']['bs']['s'];
05830 } else {
05831 $annots .= ' /S /S';
05832 }
05833 if (isset($pl['opt']['be']['i']) AND ($pl['opt']['be']['i'] >= 0) AND ($pl['opt']['be']['i'] <= 2)) {
05834 $annots .= ' /I '.sprintf(" %.4F", $pl['opt']['be']['i']);
05835 }
05836 $annots .= '>>';
05837 }
05838 if (isset($pl['opt']['c']) AND (is_array($pl['opt']['c'])) AND !empty($pl['opt']['c'])) {
05839 $annots .= ' /C [';
05840 foreach ($pl['opt']['c'] as $col) {
05841 $col = intval($col);
05842 $color = $col <= 0 ? 0 : ($col >= 255 ? 1 : $col / 255);
05843 $annots .= sprintf(" %.4F", $color);
05844 }
05845 $annots .= ']';
05846 }
05847
05848
05849 $markups = array('text', 'freetext', 'line', 'square', 'circle', 'polygon', 'polyline', 'highlight', 'underline', 'squiggly', 'strikeout', 'stamp', 'caret', 'ink', 'fileattachment', 'sound');
05850 if (in_array(strtolower($pl['opt']['subtype']), $markups)) {
05851
05852 if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) {
05853 $annots .= ' /T '.$this->_textstring($pl['opt']['t']);
05854 }
05855
05856 if (isset($pl['opt']['ca'])) {
05857 $annots .= ' /CA '.sprintf("%.4F", floatval($pl['opt']['ca']));
05858 }
05859 if (isset($pl['opt']['rc'])) {
05860 $annots .= ' /RC '.$this->_textstring($pl['opt']['rc']);
05861 }
05862 $annots .= ' /CreationDate '.$this->_datestring();
05863
05864 if (isset($pl['opt']['subj'])) {
05865 $annots .= ' /Subj '.$this->_textstring($pl['opt']['subj']);
05866 }
05867
05868
05869
05870 }
05871 $lineendings = array('Square', 'Circle', 'Diamond', 'OpenArrow', 'ClosedArrow', 'None', 'Butt', 'ROpenArrow', 'RClosedArrow', 'Slash');
05872 switch (strtolower($pl['opt']['subtype'])) {
05873 case 'text': {
05874 if (isset($pl['opt']['open'])) {
05875 $annots .= ' /Open '. (strtolower($pl['opt']['open']) == 'true' ? 'true' : 'false');
05876 }
05877 $iconsapp = array('Comment', 'Help', 'Insert', 'Key', 'NewParagraph', 'Note', 'Paragraph');
05878 if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) {
05879 $annots .= ' /Name /'.$pl['opt']['name'];
05880 } else {
05881 $annots .= ' /Name /Note';
05882 }
05883 $statemodels = array('Marked', 'Review');
05884 if (isset($pl['opt']['statemodel']) AND in_array($pl['opt']['statemodel'], $statemodels)) {
05885 $annots .= ' /StateModel /'.$pl['opt']['statemodel'];
05886 } else {
05887 $pl['opt']['statemodel'] = 'Marked';
05888 $annots .= ' /StateModel /'.$pl['opt']['statemodel'];
05889 }
05890 if ($pl['opt']['statemodel'] == 'Marked') {
05891 $states = array('Accepted', 'Unmarked');
05892 } else {
05893 $states = array('Accepted', 'Rejected', 'Cancelled', 'Completed', 'None');
05894 }
05895 if (isset($pl['opt']['state']) AND in_array($pl['opt']['state'], $states)) {
05896 $annots .= ' /State /'.$pl['opt']['state'];
05897 } else {
05898 if ($pl['opt']['statemodel'] == 'Marked') {
05899 $annots .= ' /State /Unmarked';
05900 } else {
05901 $annots .= ' /State /None';
05902 }
05903 }
05904 break;
05905 }
05906 case 'link': {
05907 if(is_string($pl['txt'])) {
05908
05909 $annots .= ' /A <</S /URI /URI '.$this->_datastring($this->unhtmlentities($pl['txt'])).'>>';
05910 } else {
05911
05912 $l = $this->links[$pl['txt']];
05913 $annots .= sprintf(' /Dest [%d 0 R /XYZ 0 %.2F null]', (1 + (2 * $l[0])), ($this->pagedim[$l[0]]['h'] - ($l[1] * $this->k)));
05914 }
05915 $hmodes = array('N', 'I', 'O', 'P');
05916 if (isset($pl['opt']['h']) AND in_array($pl['opt']['h'], $hmodes)) {
05917 $annots .= ' /H /'.$pl['opt']['h'];
05918 } else {
05919 $annots .= ' /H /I';
05920 }
05921
05922
05923 break;
05924 }
05925 case 'freetext': {
05926 if (isset($pl['opt']['da']) AND !empty($pl['opt']['da'])) {
05927 $annots .= ' /DA ('.$pl['opt']['da'].')';
05928 }
05929 if (isset($pl['opt']['q']) AND ($pl['opt']['q'] >= 0) AND ($pl['opt']['q'] <= 2)) {
05930 $annots .= ' /Q '.intval($pl['opt']['q']);
05931 }
05932 if (isset($pl['opt']['rc'])) {
05933 $annots .= ' /RC '.$this->_textstring($pl['opt']['rc']);
05934 }
05935 if (isset($pl['opt']['ds'])) {
05936 $annots .= ' /DS '.$this->_textstring($pl['opt']['ds']);
05937 }
05938 if (isset($pl['opt']['cl']) AND is_array($pl['opt']['cl'])) {
05939 $annots .= ' /CL [';
05940 foreach ($pl['opt']['cl'] as $cl) {
05941 $annots .= sprintf("%.4F ", $cl * $this->k);
05942 }
05943 $annots .= ']';
05944 }
05945 $tfit = array('FreeText', 'FreeTextCallout', 'FreeTextTypeWriter');
05946 if (isset($pl['opt']['it']) AND in_array($pl['opt']['it'], $tfit)) {
05947 $annots .= ' /IT '.$pl['opt']['it'];
05948 }
05949 if (isset($pl['opt']['rd']) AND is_array($pl['opt']['rd'])) {
05950 $l = $pl['opt']['rd'][0] * $this->k;
05951 $r = $pl['opt']['rd'][1] * $this->k;
05952 $t = $pl['opt']['rd'][2] * $this->k;
05953 $b = $pl['opt']['rd'][3] * $this->k;
05954 $annots .= ' /RD ['.sprintf('%.2F %.2F %.2F %.2F', $l, $r, $t, $b).']';
05955 }
05956 if (isset($pl['opt']['le']) AND in_array($pl['opt']['le'], $lineendings)) {
05957 $annots .= ' /LE /'.$pl['opt']['le'];
05958 }
05959 break;
05960 }
05961 case 'line': {
05962 break;
05963 }
05964 case 'square': {
05965 break;
05966 }
05967 case 'circle': {
05968 break;
05969 }
05970 case 'polygon': {
05971 break;
05972 }
05973 case 'polyline': {
05974 break;
05975 }
05976 case 'highlight': {
05977 break;
05978 }
05979 case 'underline': {
05980 break;
05981 }
05982 case 'squiggly': {
05983 break;
05984 }
05985 case 'strikeout': {
05986 break;
05987 }
05988 case 'stamp': {
05989 break;
05990 }
05991 case 'caret': {
05992 break;
05993 }
05994 case 'ink': {
05995 break;
05996 }
05997 case 'popup': {
05998 break;
05999 }
06000 case 'fileattachment': {
06001 if (!isset($pl['opt']['fs'])) {
06002 break;
06003 }
06004 $filename = basename($pl['opt']['fs']);
06005 if (isset($this->embeddedfiles[$filename]['n'])) {
06006 $annots .= ' /FS <</Type /Filespec /F '.$this->_datastring($filename).' /EF <</F '.$this->embeddedfiles[$filename]['n'].' 0 R>> >>';
06007 $iconsapp = array('Graph', 'Paperclip', 'PushPin', 'Tag');
06008 if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) {
06009 $annots .= ' /Name /'.$pl['opt']['name'];
06010 } else {
06011 $annots .= ' /Name /PushPin';
06012 }
06013 }
06014 break;
06015 }
06016 case 'sound': {
06017 if (!isset($pl['opt']['sound'])) {
06018 break;
06019 }
06020 $filename = basename($pl['opt']['sound']);
06021 if (isset($this->embeddedfiles[$filename]['n'])) {
06022 $annots .= ' /Sound <</Type /Sound';
06023
06024
06025
06026 $iconsapp = array('Speaker', 'Mic');
06027 if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) {
06028 $annots .= ' /Name /'.$pl['opt']['name'];
06029 } else {
06030 $annots .= ' /Name /Speaker';
06031 }
06032 }
06033 break;
06034 }
06035 case 'movie': {
06036 break;
06037 }
06038 case 'widget': {
06039 $hmode = array('N', 'I', 'O', 'P', 'T');
06040 if (isset($pl['opt']['h']) AND in_array($pl['opt']['h'], $hmode)) {
06041 $annots .= ' /H /'.$pl['opt']['h'];
06042 }
06043 if (isset($pl['opt']['mk']) AND (is_array($pl['opt']['mk'])) AND !empty($pl['opt']['mk'])) {
06044 $annots .= ' /MK <<';
06045 if (isset($pl['opt']['mk']['r'])) {
06046 $annots .= ' /R '.$pl['opt']['mk']['r'];
06047 }
06048 if (isset($pl['opt']['mk']['bc']) AND (is_array($pl['opt']['mk']['bc']))) {
06049 $annots .= ' /BC [';
06050 foreach($pl['opt']['mk']['bc'] AS $col) {
06051 $col = intval($col);
06052 $color = $col <= 0 ? 0 : ($col >= 255 ? 1 : $col / 255);
06053 $annots .= ' '.$color;
06054 }
06055 $annots .= ']';
06056 }
06057 if (isset($pl['opt']['mk']['bg']) AND (is_array($pl['opt']['mk']['bg']))) {
06058 $annots .= ' /BG [';
06059 foreach($pl['opt']['mk']['bg'] AS $col) {
06060 $col = intval($col);
06061 $color = $col <= 0 ? 0 : ($col >= 255 ? 1 : $col / 255);
06062 $annots .= ' '.$color;
06063 }
06064 $annots .= ']';
06065 }
06066 if (isset($pl['opt']['mk']['ca'])) {
06067 $annots .= ' /CA '.$pl['opt']['mk']['ca'].'';
06068 }
06069 if (isset($pl['opt']['mk']['rc'])) {
06070 $annots .= ' /RC '.$pl['opt']['mk']['ca'].'';
06071 }
06072 if (isset($pl['opt']['mk']['ac'])) {
06073 $annots .= ' /AC '.$pl['opt']['mk']['ca'].'';
06074 }
06075 if (isset($pl['opt']['mk']['i'])) {
06076 $info = $this->getImageBuffer($pl['opt']['mk']['i']);
06077 if ($info !== false) {
06078 $annots .= ' /I '.$info['n'].' 0 R';
06079 }
06080 }
06081 if (isset($pl['opt']['mk']['ri'])) {
06082 $info = $this->getImageBuffer($pl['opt']['mk']['ri']);
06083 if ($info !== false) {
06084 $annots .= ' /RI '.$info['n'].' 0 R';
06085 }
06086 }
06087 if (isset($pl['opt']['mk']['ix'])) {
06088 $info = $this->getImageBuffer($pl['opt']['mk']['ix']);
06089 if ($info !== false) {
06090 $annots .= ' /IX '.$info['n'].' 0 R';
06091 }
06092 }
06093 if (isset($pl['opt']['mk']['if']) AND (is_array($pl['opt']['mk']['if'])) AND !empty($pl['opt']['mk']['if'])) {
06094 $annots .= ' /IF <<';
06095 $if_sw = array('A', 'B', 'S', 'N');
06096 if (isset($pl['opt']['mk']['if']['sw']) AND in_array($pl['opt']['mk']['if']['sw'], $if_sw)) {
06097 $annots .= ' /SW /'.$pl['opt']['mk']['if']['sw'];
06098 }
06099 $if_s = array('A', 'P');
06100 if (isset($pl['opt']['mk']['if']['s']) AND in_array($pl['opt']['mk']['if']['s'], $if_s)) {
06101 $annots .= ' /S /'.$pl['opt']['mk']['if']['s'];
06102 }
06103 if (isset($pl['opt']['mk']['if']['a']) AND (is_array($pl['opt']['mk']['if']['a'])) AND !empty($pl['opt']['mk']['if']['a'])) {
06104 $annots .= ' /A ['.$pl['opt']['mk']['if']['a'][0].' '.$pl['opt']['mk']['if']['a'][1].']';
06105 }
06106 if (isset($pl['opt']['mk']['if']['fb']) AND ($pl['opt']['mk']['if']['fb'])) {
06107 $annots .= ' /FB true';
06108 }
06109 $annots .= '>>';
06110 }
06111 if (isset($pl['opt']['mk']['tp']) AND ($pl['opt']['mk']['tp'] >= 0) AND ($pl['opt']['mk']['tp'] <= 6)) {
06112 $annots .= ' /TP '.$pl['opt']['mk']['tp'];
06113 } else {
06114 $annots .= ' /TP 0';
06115 }
06116 $annots .= '>>';
06117 }
06118
06119 if (isset($this->radiobutton_groups[$n][$pl['txt']])) {
06120
06121 $annots .= ' /Parent '.$this->radiobutton_groups[$n][$pl['txt']].' 0 R';
06122 }
06123 if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) {
06124 $annots .= ' /T '.$this->_datastring($pl['opt']['t']);
06125 }
06126 if (isset($pl['opt']['tu']) AND is_string($pl['opt']['tu'])) {
06127 $annots .= ' /TU '.$this->_datastring($pl['opt']['tu']);
06128 }
06129 if (isset($pl['opt']['tm']) AND is_string($pl['opt']['tm'])) {
06130 $annots .= ' /TM '.$this->_datastring($pl['opt']['tm']);
06131 }
06132 if (isset($pl['opt']['ff'])) {
06133 if (is_array($pl['opt']['ff'])) {
06134
06135 $flag = 0;
06136 foreach($pl['opt']['ff'] as $val) {
06137 $flag += 1 << ($val - 1);
06138 }
06139 } else {
06140 $flag = intval($pl['opt']['ff']);
06141 }
06142 $annots .= ' /Ff '.$flag;
06143 }
06144 if (isset($pl['opt']['maxlen'])) {
06145 $annots .= ' /MaxLen '.intval($pl['opt']['maxlen']);
06146 }
06147 if (isset($pl['opt']['v'])) {
06148 $annots .= ' /V';
06149 if (is_array($pl['opt']['v'])) {
06150 foreach ($pl['opt']['v'] AS $optval) {
06151 $annots .= ' '.$optval;
06152 }
06153 } else {
06154 $annots .= ' '.$this->_textstring($pl['opt']['v']);
06155 }
06156 }
06157 if (isset($pl['opt']['dv']) AND is_string($pl['opt']['dv'])) {
06158 $annots .= ' /DV';
06159 if (is_array($pl['opt']['dv'])) {
06160 foreach ($pl['opt']['dv'] AS $optval) {
06161 $annots .= ' '.$optval;
06162 }
06163 } else {
06164 $annots .= ' '.$this->_textstring($pl['opt']['dv']);
06165 }
06166 }
06167 if (isset($pl['opt']['rv']) AND is_string($pl['opt']['rv'])) {
06168 $annots .= ' /RV';
06169 if (is_array($pl['opt']['rv'])) {
06170 foreach ($pl['opt']['rv'] AS $optval) {
06171 $annots .= ' '.$optval;
06172 }
06173 } else {
06174 $annots .= ' '.$this->_textstring($pl['opt']['rv']);
06175 }
06176 }
06177 if (isset($pl['opt']['a']) AND !empty($pl['opt']['a'])) {
06178 $annots .= ' /A << '.$pl['opt']['a'].' >>';
06179 }
06180 if (isset($pl['opt']['aa']) AND !empty($pl['opt']['aa'])) {
06181 $annots .= ' /AA << '.$pl['opt']['aa'].' >>';
06182 }
06183 if (isset($pl['opt']['da']) AND !empty($pl['opt']['da'])) {
06184 $annots .= ' /DA ('.$pl['opt']['da'].')';
06185 }
06186 if (isset($pl['opt']['q']) AND ($pl['opt']['q'] >= 0) AND ($pl['opt']['q'] <= 2)) {
06187 $annots .= ' /Q '.intval($pl['opt']['q']);
06188 }
06189 if (isset($pl['opt']['opt']) AND (is_array($pl['opt']['opt'])) AND !empty($pl['opt']['opt'])) {
06190 $annots .= ' /Opt [';
06191 foreach($pl['opt']['opt'] AS $copt) {
06192 if (is_array($copt)) {
06193 $annots .= ' ['.$this->_textstring($copt[0]).' '.$this->_textstring($copt[1]).']';
06194 } else {
06195 $annots .= ' '.$this->_textstring($copt);
06196 }
06197 }
06198 $annots .= ']';
06199 }
06200 if (isset($pl['opt']['ti'])) {
06201 $annots .= ' /TI '.intval($pl['opt']['ti']);
06202 }
06203 if (isset($pl['opt']['i']) AND (is_array($pl['opt']['i'])) AND !empty($pl['opt']['i'])) {
06204 $annots .= ' /I [';
06205 foreach($pl['opt']['i'] AS $copt) {
06206 $annots .= intval($copt).' ';
06207 }
06208 $annots .= ']';
06209 }
06210 break;
06211 }
06212 case 'screen': {
06213 break;
06214 }
06215 case 'printermark': {
06216 break;
06217 }
06218 case 'trapnet': {
06219 break;
06220 }
06221 case 'watermark': {
06222 break;
06223 }
06224 case '3d': {
06225 break;
06226 }
06227 default: {
06228 break;
06229 }
06230 }
06231 $annots .= '>>';
06232
06233 ++$this->annot_obj_id;
06234 $this->offsets[$this->annot_obj_id] = $this->bufferlen;
06235 $this->_out($this->annot_obj_id.' 0 obj');
06236 $this->_out($annots);
06237 $this->_out('endobj');
06238 if ($formfield AND ! isset($this->radiobutton_groups[$n][$pl['txt']])) {
06239
06240 $this->form_obj_id[] = $this->annot_obj_id;
06241 }
06242 }
06243 }
06244 }
06245 }
06246
06256 protected function _putAPXObject($w=0, $h=0, $stream='') {
06257 $stream = trim($stream);
06258 ++$this->apxo_obj_id;
06259 $this->offsets[$this->apxo_obj_id] = $this->bufferlen;
06260 $this->_out($this->apxo_obj_id.' 0 obj');
06261 $this->_out('<<');
06262 $this->_out('/Type /XObject');
06263 $this->_out('/Subtype /Form');
06264 $this->_out('/FormType 1');
06265 if ($this->compress) {
06266 $stream = gzcompress($stream);
06267 $this->_out('/Filter /FlateDecode');
06268 }
06269 $rect = sprintf('%.2F %.2F', $w, $h);
06270 $this->_out('/BBox [0 0 '.$rect.']');
06271 $this->_out('/Matrix [1 0 0 1 0 0]');
06272 $this->_out('/Resources <</ProcSet [/PDF]>>');
06273 $this->_out('/Length '.strlen($stream));
06274 $this->_out('>>');
06275 $this->_putstream($stream);
06276 $this->_out('endobj');
06277 return $this->apxo_obj_id;
06278 }
06279
06284 protected function _putfonts() {
06285 $nf = $this->n;
06286 foreach ($this->diffs as $diff) {
06287
06288 $this->_newobj();
06289 $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
06290 $this->_out('endobj');
06291 }
06292 $mqr = $this->get_mqr();
06293 $this->set_mqr(false);
06294 foreach ($this->FontFiles as $file => $info) {
06295
06296 $fontdir = $info['fontdir'];
06297 $file = strtolower($file);
06298 $fontfile = '';
06299
06300 if (file_exists($fontdir.$file)) {
06301 $fontfile = $fontdir.$file;
06302 } elseif (file_exists($this->_getfontpath().$file)) {
06303 $fontfile = $this->_getfontpath().$file;
06304 } elseif (file_exists($file)) {
06305 $fontfile = $file;
06306 }
06307 if (!$this->empty_string($fontfile)) {
06308 $font = file_get_contents($fontfile);
06309 $compressed = (substr($file, -2) == '.z');
06310 if ((!$compressed) AND (isset($info['length2']))) {
06311 $header = (ord($font{0}) == 128);
06312 if ($header) {
06313
06314 $font = substr($font, 6);
06315 }
06316 if ($header AND (ord($font{$info['length1']}) == 128)) {
06317
06318 $font = substr($font, 0, $info['length1']).substr($font, ($info['length1'] + 6));
06319 }
06320 }
06321 $this->_newobj();
06322 $this->FontFiles[$file]['n'] = $this->n;
06323 $this->_out('<</Length '.strlen($font));
06324 if ($compressed) {
06325 $this->_out('/Filter /FlateDecode');
06326 }
06327 $this->_out('/Length1 '.$info['length1']);
06328 if (isset($info['length2'])) {
06329 $this->_out('/Length2 '.$info['length2'].' /Length3 0');
06330 }
06331 $this->_out('>>');
06332 $this->_putstream($font);
06333 $this->_out('endobj');
06334 }
06335 }
06336 $this->set_mqr($mqr);
06337 foreach ($this->fontkeys as $k) {
06338
06339 $this->setFontSubBuffer($k, 'n', $this->n + 1);
06340 $font = $this->getFontBuffer($k);
06341 $type = $font['type'];
06342 $name = $font['name'];
06343 if ($type == 'core') {
06344
06345 $obj_id = $this->_newobj();
06346 $this->_out('<</Type /Font');
06347 $this->_out('/Subtype /Type1');
06348 $this->_out('/BaseFont /'.$name);
06349 $this->_out('/Name /F'.$font['i']);
06350 if ((strtolower($name) != 'symbol') AND (strtolower($name) != 'zapfdingbats')) {
06351 $this->_out('/Encoding /WinAnsiEncoding');
06352 }
06353 if (strtolower($name) == 'helvetica') {
06354
06355 $this->annotation_fonts['helvetica'] = $k;
06356 }
06357 $this->_out('>>');
06358 $this->_out('endobj');
06359 } elseif (($type == 'Type1') OR ($type == 'TrueType')) {
06360
06361 $obj_id = $this->_newobj();
06362 $this->_out('<</Type /Font');
06363 $this->_out('/Subtype /'.$type);
06364 $this->_out('/BaseFont /'.$name);
06365 $this->_out('/Name /F'.$font['i']);
06366 $this->_out('/FirstChar 32 /LastChar 255');
06367 $this->_out('/Widths '.($this->n + 1).' 0 R');
06368 $this->_out('/FontDescriptor '.($this->n + 2).' 0 R');
06369 if ($font['enc']) {
06370 if (isset($font['diff'])) {
06371 $this->_out('/Encoding '.($nf + $font['diff']).' 0 R');
06372 } else {
06373 $this->_out('/Encoding /WinAnsiEncoding');
06374 }
06375 }
06376 $this->_out('>>');
06377 $this->_out('endobj');
06378
06379 $this->_newobj();
06380 $cw = &$font['cw'];
06381 $s = '[';
06382 for ($i = 32; $i < 256; ++$i) {
06383 $s .= $cw[$i].' ';
06384 }
06385 $this->_out($s.']');
06386 $this->_out('endobj');
06387
06388 $this->_newobj();
06389 $s = '<</Type /FontDescriptor /FontName /'.$name;
06390 foreach ($font['desc'] as $fdk => $fdv) {
06391 $s .= ' /'.$fdk.' '.$fdv.'';
06392 }
06393 if (!$this->empty_string($font['file'])) {
06394 $s .= ' /FontFile'.($type == 'Type1' ? '' : '2').' '.$this->FontFiles[$font['file']]['n'].' 0 R';
06395 }
06396 $this->_out($s.'>>');
06397 $this->_out('endobj');
06398 } else {
06399
06400 $mtd = '_put'.strtolower($type);
06401 if (!method_exists($this, $mtd)) {
06402 $this->Error('Unsupported font type: '.$type);
06403 }
06404 $obj_id = $this->$mtd($font);
06405 }
06406
06407 $this->font_obj_ids[$k] = $obj_id;
06408 }
06409 }
06410
06419 protected function _putfontwidths($font, $cidoffset=0) {
06420 ksort($font['cw']);
06421 $rangeid = 0;
06422 $range = array();
06423 $prevcid = -2;
06424 $prevwidth = -1;
06425 $interval = false;
06426
06427 foreach ($font['cw'] as $cid => $width) {
06428 $cid -= $cidoffset;
06429 if ($width != $font['dw']) {
06430 if ($cid == ($prevcid + 1)) {
06431
06432 if ($width == $prevwidth) {
06433 if ($width == $range[$rangeid][0]) {
06434 $range[$rangeid][] = $width;
06435 } else {
06436 array_pop($range[$rangeid]);
06437
06438 $rangeid = $prevcid;
06439 $range[$rangeid] = array();
06440 $range[$rangeid][] = $prevwidth;
06441 $range[$rangeid][] = $width;
06442 }
06443 $interval = true;
06444 $range[$rangeid]['interval'] = true;
06445 } else {
06446 if ($interval) {
06447
06448 $rangeid = $cid;
06449 $range[$rangeid] = array();
06450 $range[$rangeid][] = $width;
06451 } else {
06452 $range[$rangeid][] = $width;
06453 }
06454 $interval = false;
06455 }
06456 } else {
06457
06458 $rangeid = $cid;
06459 $range[$rangeid] = array();
06460 $range[$rangeid][] = $width;
06461 $interval = false;
06462 }
06463 $prevcid = $cid;
06464 $prevwidth = $width;
06465 }
06466 }
06467
06468 $prevk = -1;
06469 $nextk = -1;
06470 $prevint = false;
06471 foreach ($range as $k => $ws) {
06472 $cws = count($ws);
06473 if (($k == $nextk) AND (!$prevint) AND ((!isset($ws['interval'])) OR ($cws < 4))) {
06474 if (isset($range[$k]['interval'])) {
06475 unset($range[$k]['interval']);
06476 }
06477 $range[$prevk] = array_merge($range[$prevk], $range[$k]);
06478 unset($range[$k]);
06479 } else {
06480 $prevk = $k;
06481 }
06482 $nextk = $k + $cws;
06483 if (isset($ws['interval'])) {
06484 if ($cws > 3) {
06485 $prevint = true;
06486 } else {
06487 $prevint = false;
06488 }
06489 unset($range[$k]['interval']);
06490 --$nextk;
06491 } else {
06492 $prevint = false;
06493 }
06494 }
06495
06496 $w = '';
06497 foreach ($range as $k => $ws) {
06498 if (count(array_count_values($ws)) == 1) {
06499
06500 $w .= ' '.$k.' '.($k + count($ws) - 1).' '.$ws[0];
06501 } else {
06502
06503 $w .= ' '.$k.' [ '.implode(' ', $ws).' ]';
06504 }
06505 }
06506 $this->_out('/W ['.$w.' ]');
06507 }
06508
06518 protected function _puttruetypeunicode($font) {
06519
06520
06521 $obj_id = $this->_newobj();
06522 $this->_out('<</Type /Font');
06523 $this->_out('/Subtype /Type0');
06524 $this->_out('/BaseFont /'.$font['name'].'');
06525 $this->_out('/Name /F'.$font['i']);
06526 $this->_out('/Encoding /'.$font['enc']);
06527 $this->_out('/ToUnicode /Identity-H');
06528 $this->_out('/DescendantFonts ['.($this->n + 1).' 0 R]');
06529 $this->_out('>>');
06530 $this->_out('endobj');
06531
06532
06533 $this->_newobj();
06534 $this->_out('<</Type /Font');
06535 $this->_out('/Subtype /CIDFontType2');
06536 $this->_out('/BaseFont /'.$font['name'].'');
06537
06538 $cidinfo = '/Registry '.$this->_datastring($font['cidinfo']['Registry']);
06539 $cidinfo .= ' /Ordering '.$this->_datastring($font['cidinfo']['Ordering']);
06540 $cidinfo .= ' /Supplement '.$font['cidinfo']['Supplement'];
06541 $this->_out('/CIDSystemInfo <<'.$cidinfo.'>>');
06542 $this->_out('/FontDescriptor '.($this->n + 1).' 0 R');
06543 $this->_out('/DW '.$font['dw'].'');
06544 $this->_putfontwidths($font, 0);
06545 $this->_out('/CIDToGIDMap '.($this->n + 2).' 0 R');
06546 $this->_out('>>');
06547 $this->_out('endobj');
06548
06549
06550 $this->_newobj();
06551 $this->_out('<</Type /FontDescriptor');
06552 $this->_out('/FontName /'.$font['name']);
06553 foreach ($font['desc'] as $key => $value) {
06554 $this->_out('/'.$key.' '.$value);
06555 }
06556 $fontdir = '';
06557 if (!$this->empty_string($font['file'])) {
06558
06559 $this->_out('/FontFile2 '.$this->FontFiles[$font['file']]['n'].' 0 R');
06560 $fontdir = $this->FontFiles[$font['file']]['fontdir'];
06561 }
06562 $this->_out('>>');
06563 $this->_out('endobj');
06564 $this->_newobj();
06565 if (isset($font['ctg']) AND (!$this->empty_string($font['ctg']))) {
06566
06567
06568
06569 $ctgfile = strtolower($font['ctg']);
06570
06571 $fontfile = '';
06572
06573 if (file_exists($fontdir.$ctgfile)) {
06574 $fontfile = $fontdir.$ctgfile;
06575 } elseif (file_exists($this->_getfontpath().$ctgfile)) {
06576 $fontfile = $this->_getfontpath().$ctgfile;
06577 } elseif (file_exists($ctgfile)) {
06578 $fontfile = $ctgfile;
06579 }
06580 if ($this->empty_string($fontfile)) {
06581 $this->Error('Font file not found: '.$ctgfile);
06582 }
06583 $size = filesize($fontfile);
06584 $this->_out('<</Length '.$size.'');
06585 if (substr($fontfile, -2) == '.z') {
06586
06587
06588
06589 $this->_out('/Filter /FlateDecode');
06590 }
06591 $this->_out('>>');
06592 $this->_putstream(file_get_contents($fontfile));
06593 }
06594 $this->_out('endobj');
06595 return $obj_id;
06596 }
06597
06607 protected function _putcidfont0($font) {
06608 $cidoffset = 0;
06609 if (!isset($font['cw'][1])) {
06610 $cidoffset = 31;
06611 }
06612 if (isset($font['cidinfo']['uni2cid'])) {
06613
06614 $uni2cid = $font['cidinfo']['uni2cid'];
06615 $cw = array();
06616 foreach ($font['cw'] as $uni => $width) {
06617 if (isset($uni2cid[$uni])) {
06618 $cw[($uni2cid[$uni] + $cidoffset)] = $width;
06619 } elseif ($uni < 256) {
06620 $cw[$uni] = $width;
06621 }
06622 }
06623 $font = array_merge($font, array('cw' => $cw));
06624 }
06625 $name = $font['name'];
06626 $enc = $font['enc'];
06627 if ($enc) {
06628 $longname = $name.'-'.$enc;
06629 } else {
06630 $longname = $name;
06631 }
06632 $obj_id = $this->_newobj();
06633 $this->_out('<</Type /Font');
06634 $this->_out('/Subtype /Type0');
06635 $this->_out('/BaseFont /'.$longname);
06636 $this->_out('/Name /F'.$font['i']);
06637 if ($enc) {
06638 $this->_out('/Encoding /'.$enc);
06639 }
06640 $this->_out('/DescendantFonts ['.($this->n + 1).' 0 R]');
06641 $this->_out('>>');
06642 $this->_out('endobj');
06643 $this->_newobj();
06644 $this->_out('<</Type /Font');
06645 $this->_out('/Subtype /CIDFontType0');
06646 $this->_out('/BaseFont /'.$name);
06647 $cidinfo = '/Registry '.$this->_datastring($font['cidinfo']['Registry']);
06648 $cidinfo .= ' /Ordering '.$this->_datastring($font['cidinfo']['Ordering']);
06649 $cidinfo .= ' /Supplement '.$font['cidinfo']['Supplement'];
06650 $this->_out('/CIDSystemInfo <<'.$cidinfo.'>>');
06651 $this->_out('/FontDescriptor '.($this->n + 1).' 0 R');
06652 $this->_out('/DW '.$font['dw']);
06653 $this->_putfontwidths($font, $cidoffset);
06654 $this->_out('>>');
06655 $this->_out('endobj');
06656 $this->_newobj();
06657 $s = '<</Type /FontDescriptor /FontName /'.$name;
06658 foreach ($font['desc'] as $k => $v) {
06659 if ($k != 'Style') {
06660 $s .= ' /'.$k.' '.$v.'';
06661 }
06662 }
06663 $this->_out($s.'>>');
06664 $this->_out('endobj');
06665 return $obj_id;
06666 }
06667
06672 protected function _putimages() {
06673 $filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
06674 foreach ($this->imagekeys as $file) {
06675 $info = $this->getImageBuffer($file);
06676 $this->_newobj();
06677 $this->setImageSubBuffer($file, 'n', $this->n);
06678 $this->_out('<</Type /XObject');
06679 $this->_out('/Subtype /Image');
06680 $this->_out('/Width '.$info['w']);
06681 $this->_out('/Height '.$info['h']);
06682 if (isset($info['masked'])) {
06683 $this->_out('/SMask '.($this->n - 1).' 0 R');
06684 }
06685 if ($info['cs'] == 'Indexed') {
06686 $this->_out('/ColorSpace [/Indexed /DeviceRGB '.((strlen($info['pal']) / 3) - 1).' '.($this->n + 1).' 0 R]');
06687 } else {
06688 $this->_out('/ColorSpace /'.$info['cs']);
06689 if ($info['cs'] == 'DeviceCMYK') {
06690 $this->_out('/Decode [1 0 1 0 1 0 1 0]');
06691 }
06692 }
06693 $this->_out('/BitsPerComponent '.$info['bpc']);
06694 if (isset($info['f'])) {
06695 $this->_out('/Filter /'.$info['f']);
06696 }
06697 if (isset($info['parms'])) {
06698 $this->_out($info['parms']);
06699 }
06700 if (isset($info['trns']) AND is_array($info['trns'])) {
06701 $trns='';
06702 $count_info = count($info['trns']);
06703 for ($i=0; $i < $count_info; ++$i) {
06704 $trns .= $info['trns'][$i].' '.$info['trns'][$i].' ';
06705 }
06706 $this->_out('/Mask ['.$trns.']');
06707 }
06708 $this->_out('/Length '.strlen($info['data']).'>>');
06709 $this->_putstream($info['data']);
06710 $this->_out('endobj');
06711
06712 if ($info['cs'] == 'Indexed') {
06713 $this->_newobj();
06714 $pal = ($this->compress) ? gzcompress($info['pal']) : $info['pal'];
06715 $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
06716 $this->_putstream($pal);
06717 $this->_out('endobj');
06718 }
06719 }
06720 }
06721
06727 protected function _putspotcolors() {
06728 foreach ($this->spot_colors as $name => $color) {
06729 $this->_newobj();
06730 $this->spot_colors[$name]['n'] = $this->n;
06731 $this->_out('[/Separation /'.str_replace(' ', '#20', $name));
06732 $this->_out('/DeviceCMYK <<');
06733 $this->_out('/Range [0 1 0 1 0 1 0 1] /C0 [0 0 0 0] ');
06734 $this->_out(sprintf('/C1 [%.4F %.4F %.4F %.4F] ', $color['c']/100, $color['m']/100, $color['y']/100, $color['k']/100));
06735 $this->_out('/FunctionType 2 /Domain [0 1] /N 1>>]');
06736 $this->_out('endobj');
06737 }
06738 }
06739
06744 protected function _putxobjectdict() {
06745 foreach ($this->imagekeys as $file) {
06746 $info = $this->getImageBuffer($file);
06747 $this->_out('/I'.$info['i'].' '.$info['n'].' 0 R');
06748 }
06749 }
06750
06755 protected function _putresourcedict() {
06756 $this->_out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
06757 $this->_out('/Font <<');
06758 foreach ($this->fontkeys as $fontkey) {
06759 $font = $this->getFontBuffer($fontkey);
06760 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
06761 }
06762 $this->_out('>>');
06763 $this->_out('/XObject <<');
06764 $this->_putxobjectdict();
06765 $this->_out('>>');
06766
06767 $this->_out('/Properties <</OC1 '.$this->n_ocg_print.' 0 R /OC2 '.$this->n_ocg_view.' 0 R>>');
06768
06769 $this->_out('/ExtGState <<');
06770 foreach ($this->extgstates as $k => $extgstate) {
06771 $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
06772 }
06773 $this->_out('>>');
06774
06775 if (isset($this->gradients) AND (count($this->gradients) > 0)) {
06776 $this->_out('/Shading <<');
06777 foreach ($this->gradients as $id => $grad) {
06778 $this->_out('/Sh'.$id.' '.$grad['id'].' 0 R');
06779 }
06780 $this->_out('>>');
06781 }
06782
06783 if (isset($this->spot_colors) AND (count($this->spot_colors) > 0)) {
06784 $this->_out('/ColorSpace <<');
06785 foreach ($this->spot_colors as $color) {
06786 $this->_out('/CS'.$color['i'].' '.$color['n'].' 0 R');
06787 }
06788 $this->_out('>>');
06789 }
06790 }
06791
06796 protected function _putresources() {
06797 $this->_putextgstates();
06798 $this->_putocg();
06799 $this->_putfonts();
06800 $this->_putimages();
06801 $this->_putspotcolors();
06802 $this->_putshaders();
06803
06804 $this->offsets[2] = $this->bufferlen;
06805 $this->_out('2 0 obj');
06806 $this->_out('<<');
06807 $this->_putresourcedict();
06808 $this->_out('>>');
06809 $this->_out('endobj');
06810 $this->_putbookmarks();
06811 $this->_putEmbeddedFiles();
06812 $this->_putannotsobjs();
06813 $this->_putjavascript();
06814
06815 if ($this->encrypted) {
06816 $this->_newobj();
06817 $this->enc_obj_id = $this->n;
06818 $this->_out('<<');
06819 $this->_putencryption();
06820 $this->_out('>>');
06821 $this->_out('endobj');
06822 }
06823 }
06824
06830 protected function _putinfo() {
06831 if ($this->empty_string($this->title)) {
06832 $this->title = '?';
06833 }
06834 $this->_out('/Title '.$this->_textstring($this->title));
06835 if ($this->empty_string($this->author)) {
06836 $this->author = '?';
06837 }
06838 $this->_out('/Author '.$this->_textstring($this->author));
06839 if ($this->empty_string($this->subject)) {
06840 $this->subject = '?';
06841 }
06842 $this->_out('/Subject '.$this->_textstring($this->subject));
06843 if ($this->empty_string($this->keywords)) {
06844 $this->keywords = '?';
06845 }
06846 $this->_out('/Keywords '.$this->_textstring($this->keywords));
06847 if ($this->empty_string($this->creator)) {
06848 $this->creator = '?';
06849 }
06850 $this->_out('/Creator '.$this->_textstring($this->creator));
06851 if (defined('PDF_PRODUCER')) {
06852 $this->_out('/Producer '.$this->_textstring(PDF_PRODUCER));
06853 } else {
06854 $this->_out('/Producer '.$this->_textstring('TCPDF'));
06855 }
06856 $this->_out('/CreationDate '.$this->_datestring());
06857 $this->_out('/ModDate '.$this->_datestring());
06858 }
06859
06864 protected function _putcatalog() {
06865 $this->_out('/Type /Catalog');
06866 $this->_out('/Pages 1 0 R');
06867 if ($this->ZoomMode == 'fullpage') {
06868 $this->_out('/OpenAction [3 0 R /Fit]');
06869 } elseif ($this->ZoomMode == 'fullwidth') {
06870 $this->_out('/OpenAction [3 0 R /FitH null]');
06871 } elseif ($this->ZoomMode == 'real') {
06872 $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
06873 } elseif (!is_string($this->ZoomMode)) {
06874 $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode / 100).']');
06875 }
06876 if (isset($this->LayoutMode) AND (!$this->empty_string($this->LayoutMode))) {
06877 $this->_out('/PageLayout /'.$this->LayoutMode.'');
06878 }
06879 if (isset($this->PageMode) AND (!$this->empty_string($this->PageMode))) {
06880 $this->_out('/PageMode /'.$this->PageMode);
06881 }
06882 if (isset($this->l['a_meta_language'])) {
06883 $this->_out('/Lang /'.$this->l['a_meta_language']);
06884 }
06885 $this->_out('/Names <<');
06886 if ((!empty($this->javascript)) OR (!empty($this->js_objects))) {
06887 $this->_out('/JavaScript '.($this->n_js).' 0 R');
06888 }
06889 $this->_out('>>');
06890 if (count($this->outlines) > 0) {
06891 $this->_out('/Outlines '.$this->OutlineRoot.' 0 R');
06892 $this->_out('/PageMode /UseOutlines');
06893 }
06894 $this->_putviewerpreferences();
06895 $p = $this->n_ocg_print.' 0 R';
06896 $v = $this->n_ocg_view.' 0 R';
06897 $as = '<</Event /Print /OCGs ['.$p.' '.$v.'] /Category [/Print]>> <</Event /View /OCGs ['.$p.' '.$v.'] /Category [/View]>>';
06898 $this->_out('/OCProperties <</OCGs ['.$p.' '.$v.'] /D <</ON ['.$p.'] /OFF ['.$v.'] /AS ['.$as.']>>>>');
06899
06900 if (!empty($this->form_obj_id) OR ($this->sign AND isset($this->signature_data['cert_type']))) {
06901 $this->_out('/AcroForm<<');
06902 $objrefs = '';
06903 if ($this->sign AND isset($this->signature_data['cert_type'])) {
06904 $objrefs .= $this->sig_obj_id.' 0 R';
06905 }
06906 if (!empty($this->form_obj_id)) {
06907 foreach($this->form_obj_id as $objid) {
06908 $objrefs .= ' '.$objid.' 0 R';
06909 }
06910 }
06911 $this->_out('/Fields ['.$objrefs.']');
06912 $this->_out('/NeedAppearances '.(empty($this->form_obj_id)?'false':'true'));
06913 if ($this->sign AND isset($this->signature_data['cert_type'])) {
06914 $this->_out('/SigFlags 3');
06915 }
06916
06917 if (isset($this->annotation_fonts) AND !empty($this->annotation_fonts)) {
06918 $this->_out('/DR <<');
06919 $this->_out('/Font <<');
06920 foreach ($this->annotation_fonts as $font => $fontkey) {
06921 $this->_out('/F'.($fontkey + 1).' '.$this->font_obj_ids[$font].' 0 R');
06922 }
06923 $this->_out('>>');
06924 $this->_out('>>');
06925 }
06926 $this->_out('/DA (/F'.(array_search('helvetica', $this->fontkeys) + 1).' 0 Tf 0 g)');
06927 $this->_out('/Q '.(($this->rtl)?'2':'0'));
06928
06929 $this->_out('>>');
06930
06931 if ($this->sign AND isset($this->signature_data['cert_type'])) {
06932 if ($this->signature_data['cert_type'] > 0) {
06933 $this->_out('/Perms<</DocMDP '.($this->sig_obj_id + 1).' 0 R>>');
06934 } else {
06935 $this->_out('/Perms<</UR3 '.($this->sig_obj_id + 1).' 0 R>>');
06936 }
06937 }
06938 }
06939 }
06940
06947 protected function _putviewerpreferences() {
06948 $this->_out('/ViewerPreferences<<');
06949 if ($this->rtl) {
06950 $this->_out('/Direction /R2L');
06951 } else {
06952 $this->_out('/Direction /L2R');
06953 }
06954 if (isset($this->viewer_preferences['HideToolbar']) AND ($this->viewer_preferences['HideToolbar'])) {
06955 $this->_out('/HideToolbar true');
06956 }
06957 if (isset($this->viewer_preferences['HideMenubar']) AND ($this->viewer_preferences['HideMenubar'])) {
06958 $this->_out('/HideMenubar true');
06959 }
06960 if (isset($this->viewer_preferences['HideWindowUI']) AND ($this->viewer_preferences['HideWindowUI'])) {
06961 $this->_out('/HideWindowUI true');
06962 }
06963 if (isset($this->viewer_preferences['FitWindow']) AND ($this->viewer_preferences['FitWindow'])) {
06964 $this->_out('/FitWindow true');
06965 }
06966 if (isset($this->viewer_preferences['CenterWindow']) AND ($this->viewer_preferences['CenterWindow'])) {
06967 $this->_out('/CenterWindow true');
06968 }
06969 if (isset($this->viewer_preferences['DisplayDocTitle']) AND ($this->viewer_preferences['DisplayDocTitle'])) {
06970 $this->_out('/DisplayDocTitle true');
06971 }
06972 if (isset($this->viewer_preferences['NonFullScreenPageMode'])) {
06973 $this->_out('/NonFullScreenPageMode /'.$this->viewer_preferences['NonFullScreenPageMode'].'');
06974 }
06975 if (isset($this->viewer_preferences['ViewArea'])) {
06976 $this->_out('/ViewArea /'.$this->viewer_preferences['ViewArea']);
06977 }
06978 if (isset($this->viewer_preferences['ViewClip'])) {
06979 $this->_out('/ViewClip /'.$this->viewer_preferences['ViewClip']);
06980 }
06981 if (isset($this->viewer_preferences['PrintArea'])) {
06982 $this->_out('/PrintArea /'.$this->viewer_preferences['PrintArea']);
06983 }
06984 if (isset($this->viewer_preferences['PrintClip'])) {
06985 $this->_out('/PrintClip /'.$this->viewer_preferences['PrintClip']);
06986 }
06987 if (isset($this->viewer_preferences['PrintScaling'])) {
06988 $this->_out('/PrintScaling /'.$this->viewer_preferences['PrintScaling']);
06989 }
06990 if (isset($this->viewer_preferences['Duplex']) AND (!$this->empty_string($this->viewer_preferences['Duplex']))) {
06991 $this->_out('/Duplex /'.$this->viewer_preferences['Duplex']);
06992 }
06993 if (isset($this->viewer_preferences['PickTrayByPDFSize'])) {
06994 if ($this->viewer_preferences['PickTrayByPDFSize']) {
06995 $this->_out('/PickTrayByPDFSize true');
06996 } else {
06997 $this->_out('/PickTrayByPDFSize false');
06998 }
06999 }
07000 if (isset($this->viewer_preferences['PrintPageRange'])) {
07001 $PrintPageRangeNum = '';
07002 foreach ($this->viewer_preferences['PrintPageRange'] as $k => $v) {
07003 $PrintPageRangeNum .= ' '.($v - 1).'';
07004 }
07005 $this->_out('/PrintPageRange ['.substr($PrintPageRangeNum,1).']');
07006 }
07007 if (isset($this->viewer_preferences['NumCopies'])) {
07008 $this->_out('/NumCopies '.intval($this->viewer_preferences['NumCopies']));
07009 }
07010 $this->_out('>>');
07011 }
07012
07017 protected function _puttrailer() {
07018 $this->_out('/Size '.($this->n + 1));
07019 $this->_out('/Root '.$this->n.' 0 R');
07020 $this->_out('/Info '.($this->n - 1).' 0 R');
07021 if ($this->encrypted) {
07022 $this->_out('/Encrypt '.$this->enc_obj_id.' 0 R');
07023 $this->_out('/ID [()()]');
07024 }
07025 }
07026
07031 protected function _putheader() {
07032 $this->_out('%PDF-'.$this->PDFVersion);
07033 }
07034
07039 protected function _enddoc() {
07040 $this->state = 1;
07041 $this->_putheader();
07042 $this->_putpages();
07043 $this->_putresources();
07044
07045 if ($this->sign AND isset($this->signature_data['cert_type'])) {
07046
07047 $this->sig_obj_id = $this->_newobj();
07048
07049
07050 $pdfdoc = $this->getBuffer();
07051
07052 if (isset($this->diskcache) AND $this->diskcache) {
07053
07054 unlink($this->buffer);
07055 }
07056 unset($this->buffer);
07057 $signature_widget_ref = sprintf('%u 0 R', $this->sig_obj_id);
07058 $signature_widget_ref .= str_repeat(' ', (strlen($this->sig_annot_ref) - strlen($signature_widget_ref)));
07059 $pdfdoc = str_replace($this->sig_annot_ref, $signature_widget_ref, $pdfdoc);
07060 $this->diskcache = false;
07061 $this->buffer = &$pdfdoc;
07062 $this->bufferlen = strlen($pdfdoc);
07063
07064 $this->_out('<<');
07065 $this->_out('/Type /Annot /Subtype /Widget /Rect [0 0 0 0]');
07066 $this->_out('/P 3 0 R');
07067 $this->_out('/FT /Sig');
07068 $this->_out('/T '.$this->_textstring('Signature'));
07069 $this->_out('/Ff 0');
07070 $this->_out('/V '.($this->sig_obj_id + 1).' 0 R');
07071 $this->_out('>>');
07072 $this->_out('endobj');
07073
07074 $this->_newobj();
07075 $this->_out('<<');
07076 $this->_putsignature();
07077 $this->_out('>>');
07078 $this->_out('endobj');
07079 }
07080
07081 $this->_newobj();
07082 $this->_out('<<');
07083 $this->_putinfo();
07084 $this->_out('>>');
07085 $this->_out('endobj');
07086
07087 $this->_newobj();
07088 $this->_out('<<');
07089 $this->_putcatalog();
07090 $this->_out('>>');
07091 $this->_out('endobj');
07092
07093 $o = $this->bufferlen;
07094 $this->_out('xref');
07095 $this->_out('0 '.($this->n + 1));
07096 $this->_out('0000000000 65535 f ');
07097 for ($i=1; $i <= $this->n; ++$i) {
07098 $this->_out(sprintf('%010d 00000 n ', $this->offsets[$i]));
07099 }
07100
07101 if (isset($this->embeddedfiles) AND count($this->embeddedfiles) > 0) {
07102 $this->_out($this->embedded_start_obj_id.' '.count($this->embeddedfiles));
07103 foreach ($this->embeddedfiles as $filename => $filedata) {
07104 $this->_out(sprintf('%010d 00000 n ', $this->offsets[$filedata['n']]));
07105 }
07106 }
07107
07108 if ($this->annot_obj_id > $this->annots_start_obj_id) {
07109 $this->_out(($this->annots_start_obj_id + 1).' '.($this->annot_obj_id - $this->annots_start_obj_id));
07110 for ($i = ($this->annots_start_obj_id + 1); $i <= $this->annot_obj_id; ++$i) {
07111 $this->_out(sprintf('%010d 00000 n ', $this->offsets[$i]));
07112 }
07113 }
07114
07115 if ($this->js_obj_id > $this->js_start_obj_id) {
07116 $this->_out(($this->js_start_obj_id + 1).' '.($this->js_obj_id - $this->js_start_obj_id));
07117 for ($i = ($this->js_start_obj_id + 1); $i <= $this->js_obj_id; ++$i) {
07118 $this->_out(sprintf('%010d 00000 n ', $this->offsets[$i]));
07119 }
07120 }
07121
07122 if ($this->apxo_obj_id > $this->apxo_start_obj_id) {
07123 $this->_out(($this->apxo_start_obj_id + 1).' '.($this->apxo_obj_id - $this->apxo_start_obj_id));
07124 for ($i = ($this->apxo_start_obj_id + 1); $i <= $this->apxo_obj_id; ++$i) {
07125 $this->_out(sprintf('%010d 00000 n ', $this->offsets[$i]));
07126 }
07127 }
07128
07129 $this->_out('trailer');
07130 $this->_out('<<');
07131 $this->_puttrailer();
07132 $this->_out('>>');
07133 $this->_out('startxref');
07134 $this->_out($o);
07135 $this->_out('%%EOF');
07136 $this->state = 3;
07137 if ($this->diskcache) {
07138
07139 foreach ($this->imagekeys as $key) {
07140
07141 unlink($this->images[$key]);
07142 }
07143 foreach ($this->fontkeys as $key) {
07144
07145 unlink($this->fonts[$key]);
07146 }
07147 }
07148 }
07149
07156 protected function _beginpage($orientation='', $format='') {
07157 ++$this->page;
07158 $this->setPageBuffer($this->page, '');
07159
07160 $this->transfmrk[$this->page] = array();
07161 $this->state = 2;
07162 if ($this->empty_string($orientation)) {
07163 if (isset($this->CurOrientation)) {
07164 $orientation = $this->CurOrientation;
07165 } else {
07166 $orientation = 'P';
07167 }
07168 }
07169 if ($this->empty_string($format)) {
07170 $this->setPageOrientation($orientation);
07171 } else {
07172 $this->setPageFormat($format, $orientation);
07173 }
07174 if ($this->rtl) {
07175 $this->x = $this->w - $this->rMargin;
07176 } else {
07177 $this->x = $this->lMargin;
07178 }
07179 $this->y = $this->tMargin;
07180 if (isset($this->newpagegroup[$this->page])) {
07181
07182 $n = sizeof($this->pagegroups) + 1;
07183 $alias = '{nb'.$n.'}';
07184 $this->pagegroups[$alias] = 1;
07185 $this->currpagegroup = $alias;
07186 } elseif ($this->currpagegroup) {
07187 ++$this->pagegroups[$this->currpagegroup];
07188 }
07189 }
07190
07195 protected function _endpage() {
07196 $this->setVisibility('all');
07197 $this->state = 1;
07198 }
07199
07205 protected function _newobj() {
07206 ++$this->n;
07207 $this->offsets[$this->n] = $this->bufferlen;
07208 $this->_out($this->n.' 0 obj');
07209 return $this->n;
07210 }
07211
07219 protected function _dounderline($x, $y, $txt) {
07220 $up = $this->CurrentFont['up'];
07221 $ut = $this->CurrentFont['ut'];
07222 $w = $this->GetStringWidth($txt);
07223 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);
07224 }
07225
07233 protected function _dolinethrough($x, $y, $txt) {
07234 $up = $this->CurrentFont['up'];
07235 $ut = $this->CurrentFont['ut'];
07236 $w = $this->GetStringWidth($txt);
07237 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);
07238 }
07239
07246 protected function _freadint($f) {
07247 $a = unpack('Ni', fread($f, 4));
07248 return $a['i'];
07249 }
07250
07257 protected function _escape($s) {
07258
07259 return strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r'));
07260 }
07261
07268 protected function _datastring($s) {
07269 if ($this->encrypted) {
07270 $s = $this->_RC4($this->_objectkey($this->n), $s);
07271 }
07272 return '('. $this->_escape($s).')';
07273 }
07274
07281 protected function _datestring() {
07282 $current_time = substr_replace(date('YmdHisO'), '\'', (0 - 2), 0).'\'';
07283 return $this->_datastring('D:'.$current_time);
07284 }
07285
07292 protected function _textstring($s) {
07293 if ($this->isunicode) {
07294
07295 $s = $this->UTF8ToUTF16BE($s, true);
07296 }
07297 return $this->_datastring($s);
07298 }
07299
07306 protected function _escapetext($s) {
07307 if ($this->isunicode) {
07308 if (($this->CurrentFont['type'] == 'core') OR ($this->CurrentFont['type'] == 'TrueType') OR ($this->CurrentFont['type'] == 'Type1')) {
07309 $s = $this->UTF8ToLatin1($s);
07310 } else {
07311
07312 $s = $this->utf8StrRev($s, false, $this->tmprtl);
07313 }
07314 }
07315 return $this->_escape($s);
07316 }
07317
07323 protected function _putstream($s) {
07324 if ($this->encrypted) {
07325 $s = $this->_RC4($this->_objectkey($this->n), $s);
07326 }
07327 $this->_out('stream');
07328 $this->_out($s);
07329 $this->_out('endstream');
07330 }
07331
07337 protected function _out($s) {
07338 if ($this->state == 2) {
07339 if ((!$this->InFooter) AND isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) {
07340
07341 $pagebuff = $this->getPageBuffer($this->page);
07342 $page = substr($pagebuff, 0, -$this->footerlen[$this->page]);
07343 $footer = substr($pagebuff, -$this->footerlen[$this->page]);
07344 $this->setPageBuffer($this->page, $page.$s."\n".$footer);
07345
07346 $this->footerpos[$this->page] += strlen($s."\n");
07347 } else {
07348 $this->setPageBuffer($this->page, $s."\n", true);
07349 }
07350 } else {
07351 $this->setBuffer($s."\n");
07352 }
07353 }
07354
07389 protected function UTF8StringToArray($str) {
07390 if (isset($this->cache_UTF8StringToArray['_'.$str])) {
07391
07392 return($this->cache_UTF8StringToArray['_'.$str]);
07393 }
07394
07395 if ($this->cache_size_UTF8StringToArray >= $this->cache_maxsize_UTF8StringToArray) {
07396
07397 array_shift($this->cache_UTF8StringToArray);
07398 }
07399 ++$this->cache_size_UTF8StringToArray;
07400 if (!$this->isunicode) {
07401
07402 $strarr = array();
07403 $strlen = strlen($str);
07404 for ($i=0; $i < $strlen; ++$i) {
07405 $strarr[] = ord($str{$i});
07406 }
07407
07408 $this->cache_UTF8StringToArray['_'.$str] = $strarr;
07409 return $strarr;
07410 }
07411 $unicode = array();
07412 $bytes = array();
07413 $numbytes = 1;
07414 $str .= '';
07415 $length = strlen($str);
07416 for ($i = 0; $i < $length; ++$i) {
07417 $char = ord($str{$i});
07418 if (count($bytes) == 0) {
07419 if ($char <= 0x7F) {
07420 $unicode[] = $char;
07421 $numbytes = 1;
07422 } elseif (($char >> 0x05) == 0x06) {
07423 $bytes[] = ($char - 0xC0) << 0x06;
07424 $numbytes = 2;
07425 } elseif (($char >> 0x04) == 0x0E) {
07426 $bytes[] = ($char - 0xE0) << 0x0C;
07427 $numbytes = 3;
07428 } elseif (($char >> 0x03) == 0x1E) {
07429 $bytes[] = ($char - 0xF0) << 0x12;
07430 $numbytes = 4;
07431 } else {
07432
07433 $unicode[] = 0xFFFD;
07434 $bytes = array();
07435 $numbytes = 1;
07436 }
07437 } elseif (($char >> 0x06) == 0x02) {
07438 $bytes[] = $char - 0x80;
07439 if (count($bytes) == $numbytes) {
07440
07441 $char = $bytes[0];
07442 for ($j = 1; $j < $numbytes; ++$j) {
07443 $char += ($bytes[$j] << (($numbytes - $j - 1) * 0x06));
07444 }
07445 if ((($char >= 0xD800) AND ($char <= 0xDFFF)) OR ($char >= 0x10FFFF)) {
07446
07447
07448
07449
07450 $unicode[] = 0xFFFD;
07451 } else {
07452 $unicode[] = $char;
07453 }
07454
07455 $bytes = array();
07456 $numbytes = 1;
07457 }
07458 } else {
07459
07460 $unicode[] = 0xFFFD;
07461 $bytes = array();
07462 $numbytes = 1;
07463 }
07464 }
07465
07466 $this->cache_UTF8StringToArray['_'.$str] = $unicode;
07467 return $unicode;
07468 }
07469
07480 protected function UTF8ToUTF16BE($str, $setbom=true) {
07481 if (!$this->isunicode) {
07482 return $str;
07483 }
07484 $unicode = $this->UTF8StringToArray($str);
07485 return $this->arrUTF8ToUTF16BE($unicode, $setbom);
07486 }
07487
07496 protected function UTF8ToLatin1($str) {
07497 global $utf8tolatin;
07498 if (!$this->isunicode) {
07499 return $str;
07500 }
07501 $outstr = '';
07502 $unicode = $this->UTF8StringToArray($str);
07503 foreach ($unicode as $char) {
07504 if ($char < 256) {
07505 $outstr .= chr($char);
07506 } elseif (array_key_exists($char, $utf8tolatin)) {
07507
07508 $outstr .= chr($utf8tolatin[$char]);
07509 } elseif ($char == 0xFFFD) {
07510
07511 } else {
07512 $outstr .= '?';
07513 }
07514 }
07515 return $outstr;
07516 }
07517
07556 protected function arrUTF8ToUTF16BE($unicode, $setbom=true) {
07557 $outstr = '';
07558 if ($setbom) {
07559 $outstr .= "\xFE\xFF";
07560 }
07561 foreach ($unicode as $char) {
07562 if ($char == 0xFFFD) {
07563 $outstr .= "\xFF\xFD";
07564 } elseif ($char < 0x10000) {
07565 $outstr .= chr($char >> 0x08);
07566 $outstr .= chr($char & 0xFF);
07567 } else {
07568 $char -= 0x10000;
07569 $w1 = 0xD800 | ($char >> 0x10);
07570 $w2 = 0xDC00 | ($char & 0x3FF);
07571 $outstr .= chr($w1 >> 0x08);
07572 $outstr .= chr($w1 & 0xFF);
07573 $outstr .= chr($w2 >> 0x08);
07574 $outstr .= chr($w2 & 0xFF);
07575 }
07576 }
07577 return $outstr;
07578 }
07579
07580
07587 public function setHeaderFont($font) {
07588 $this->header_font = $font;
07589 }
07590
07597 public function getHeaderFont() {
07598 return $this->header_font;
07599 }
07600
07607 public function setFooterFont($font) {
07608 $this->footer_font = $font;
07609 }
07610
07617 public function getFooterFont() {
07618 return $this->footer_font;
07619 }
07620
07627 public function setLanguageArray($language) {
07628 $this->l = $language;
07629 if (isset($this->l['a_meta_dir'])) {
07630 $this->rtl = $this->l['a_meta_dir']=='rtl' ? true : false;
07631 } else {
07632 $this->rtl = false;
07633 }
07634 }
07635
07640 public function getPDFData() {
07641 if ($this->state < 3) {
07642 $this->Close();
07643 }
07644 return $this->buffer;
07645 }
07646
07658 public function addHtmlLink($url, $name, $fill=0, $firstline=false, $color='', $style=-1) {
07659 if (!$this->empty_string($url) AND ($url{0} == '#')) {
07660
07661 $page = intval(substr($url, 1));
07662 $url = $this->AddLink();
07663 $this->SetLink($url, 0, $page);
07664 }
07665
07666 $prevcolor = $this->fgcolor;
07667 $prevstyle = $this->FontStyle;
07668 if (empty($color)) {
07669 $this->SetTextColorArray($this->htmlLinkColorArray);
07670 } else {
07671 $this->SetTextColorArray($color);
07672 }
07673 if ($style == -1) {
07674 $this->SetFont('', $this->FontStyle.$this->htmlLinkFontStyle);
07675 } else {
07676 $this->SetFont('', $this->FontStyle.$style);
07677 }
07678 $ret = $this->Write($this->lasth, $name, $url, $fill, '', false, 0, $firstline);
07679
07680 $this->SetFont('', $prevstyle);
07681 $this->SetTextColorArray($prevcolor);
07682 return $ret;
07683 }
07684
07691 public function convertHTMLColorToDec($color='#FFFFFF') {
07692 global $webcolor;
07693 $returncolor = false;
07694 $color = preg_replace('/[\s]*/', '', $color);
07695 $color = strtolower($color);
07696 if (($dotpos = strpos($color, '.')) !== false) {
07697
07698 $color = substr($color, ($dotpos + 1));
07699 }
07700 if (strlen($color) == 0) {
07701 return false;
07702 }
07703 if (substr($color, 0, 3) == 'rgb') {
07704 $codes = substr($color, 4);
07705 $codes = str_replace(')', '', $codes);
07706 $returncolor = explode(',', $codes, 3);
07707 return $returncolor;
07708 }
07709 if (substr($color, 0, 1) != '#') {
07710
07711 if (isset($webcolor[$color])) {
07712 $color_code = $webcolor[$color];
07713 } else {
07714 return false;
07715 }
07716 } else {
07717 $color_code = substr($color, 1);
07718 }
07719 switch (strlen($color_code)) {
07720 case 3: {
07721
07722 $r = substr($color_code, 0, 1);
07723 $g = substr($color_code, 1, 1);
07724 $b = substr($color_code, 2, 1);
07725 $returncolor['R'] = hexdec($r.$r);
07726 $returncolor['G'] = hexdec($g.$g);
07727 $returncolor['B'] = hexdec($b.$b);
07728 break;
07729 }
07730 case 6: {
07731
07732 $returncolor['R'] = hexdec(substr($color_code, 0, 2));
07733 $returncolor['G'] = hexdec(substr($color_code, 2, 2));
07734 $returncolor['B'] = hexdec(substr($color_code, 4, 2));
07735 break;
07736 }
07737 }
07738 return $returncolor;
07739 }
07740
07748 public function pixelsToUnits($px) {
07749 return ($px / ($this->imgscale * $this->k));
07750 }
07751
07759 public function unhtmlentities($text_to_convert) {
07760 return html_entity_decode($text_to_convert, ENT_QUOTES, $this->encoding);
07761 }
07762
07763
07764
07765
07772 protected function _objectkey($n) {
07773 return substr($this->_md5_16($this->encryption_key.pack('VXxx', $n)), 0, 10);
07774 }
07775
07781 protected function _putencryption() {
07782 $this->_out('/Filter /Standard');
07783 $this->_out('/V 1');
07784 $this->_out('/R 2');
07785 $this->_out('/O ('.$this->_escape($this->Ovalue).')');
07786 $this->_out('/U ('.$this->_escape($this->Uvalue).')');
07787 $this->_out('/P '.$this->Pvalue);
07788 }
07789
07800 protected function _RC4($key, $text) {
07801 if ($this->last_rc4_key != $key) {
07802 $k = str_repeat($key, ((256 / strlen($key)) + 1));
07803 $rc4 = range(0, 255);
07804 $j = 0;
07805 for ($i = 0; $i < 256; ++$i) {
07806 $t = $rc4[$i];
07807 $j = ($j + $t + ord($k{$i})) % 256;
07808 $rc4[$i] = $rc4[$j];
07809 $rc4[$j] = $t;
07810 }
07811 $this->last_rc4_key = $key;
07812 $this->last_rc4_key_c = $rc4;
07813 } else {
07814 $rc4 = $this->last_rc4_key_c;
07815 }
07816 $len = strlen($text);
07817 $a = 0;
07818 $b = 0;
07819 $out = '';
07820 for ($i = 0; $i < $len; ++$i) {
07821 $a = ($a + 1) % 256;
07822 $t = $rc4[$a];
07823 $b = ($b + $t) % 256;
07824 $rc4[$a] = $rc4[$b];
07825 $rc4[$b] = $t;
07826 $k = $rc4[($rc4[$a] + $rc4[$b]) % 256];
07827 $out .= chr(ord($text{$i}) ^ $k);
07828 }
07829 return $out;
07830 }
07831
07840 protected function _md5_16($str) {
07841 return pack('H*', md5($str));
07842 }
07843
07853 protected function _Ovalue($user_pass, $owner_pass) {
07854 $tmp = $this->_md5_16($owner_pass);
07855 $owner_RC4_key = substr($tmp, 0, 5);
07856 return $this->_RC4($owner_RC4_key, $user_pass);
07857 }
07858
07866 protected function _Uvalue() {
07867 return $this->_RC4($this->encryption_key, $this->padding);
07868 }
07869
07879 protected function _generateencryptionkey($user_pass, $owner_pass, $protection) {
07880
07881 $user_pass = substr($user_pass.$this->padding, 0, 32);
07882 $owner_pass = substr($owner_pass.$this->padding, 0, 32);
07883
07884 $this->Ovalue = $this->_Ovalue($user_pass, $owner_pass);
07885
07886 $tmp = $this->_md5_16($user_pass.$this->Ovalue.chr($protection)."\xFF\xFF\xFF");
07887 $this->encryption_key = substr($tmp, 0, 5);
07888
07889 $this->Uvalue = $this->_Uvalue();
07890
07891 $this->Pvalue = -(($protection^255) + 1);
07892 }
07893
07911 public function SetProtection($permissions=array(), $user_pass='', $owner_pass=null) {
07912 $options = array('print' => 4, 'modify' => 8, 'copy' => 16, 'annot-forms' => 32);
07913 $protection = 192;
07914 foreach ($permissions as $permission) {
07915 if (!isset($options[$permission])) {
07916 $this->Error('Incorrect permission: '.$permission);
07917 }
07918 $protection += $options[$permission];
07919 }
07920 if ($owner_pass === null) {
07921 $owner_pass = uniqid(rand());
07922 }
07923 $this->encrypted = true;
07924 $this->_generateencryptionkey($user_pass, $owner_pass, $protection);
07925 }
07926
07927
07928
07929
07930
07939 public function StartTransform() {
07940 $this->_out('q');
07941 $this->transfmrk[$this->page][] = $this->pagelen[$this->page];
07942 ++$this->transfmatrix_key;
07943 $this->transfmatrix[$this->transfmatrix_key] = array();
07944 }
07945
07954 public function StopTransform() {
07955 $this->_out('Q');
07956 if (isset($this->transfmatrix[$this->transfmatrix_key])) {
07957 array_pop($this->transfmatrix[$this->transfmatrix_key]);
07958 --$this->transfmatrix_key;
07959 }
07960 array_pop($this->transfmrk[$this->page]);
07961 }
07971 public function ScaleX($s_x, $x='', $y='') {
07972 $this->Scale($s_x, 100, $x, $y);
07973 }
07974
07984 public function ScaleY($s_y, $x='', $y='') {
07985 $this->Scale(100, $s_y, $x, $y);
07986 }
07987
07997 public function ScaleXY($s, $x='', $y='') {
07998 $this->Scale($s, $s, $x, $y);
07999 }
08000
08011 public function Scale($s_x, $s_y, $x='', $y='') {
08012 if ($x === '') {
08013 $x = $this->x;
08014 }
08015 if ($y === '') {
08016 $y = $this->y;
08017 }
08018 if ($this->rtl) {
08019 $x = $this->w - $x;
08020 }
08021 if (($s_x == 0) OR ($s_y == 0)) {
08022 $this->Error('Please do not use values equal to zero for scaling');
08023 }
08024 $y = ($this->h - $y) * $this->k;
08025 $x *= $this->k;
08026
08027 $s_x /= 100;
08028 $s_y /= 100;
08029 $tm[0] = $s_x;
08030 $tm[1] = 0;
08031 $tm[2] = 0;
08032 $tm[3] = $s_y;
08033 $tm[4] = $x * (1 - $s_x);
08034 $tm[5] = $y * (1 - $s_y);
08035
08036 $this->Transform($tm);
08037 }
08038
08046 public function MirrorH($x='') {
08047 $this->Scale(-100, 100, $x);
08048 }
08049
08057 public function MirrorV($y='') {
08058 $this->Scale(100, -100, '', $y);
08059 }
08060
08069 public function MirrorP($x='',$y='') {
08070 $this->Scale(-100, -100, $x, $y);
08071 }
08072
08082 public function MirrorL($angle=0, $x='',$y='') {
08083 $this->Scale(-100, 100, $x, $y);
08084 $this->Rotate(-2*($angle-90), $x, $y);
08085 }
08086
08094 public function TranslateX($t_x) {
08095 $this->Translate($t_x, 0);
08096 }
08097
08105 public function TranslateY($t_y) {
08106 $this->Translate(0, $t_y);
08107 }
08108
08117 public function Translate($t_x, $t_y) {
08118 if ($this->rtl) {
08119 $t_x = -$t_x;
08120 }
08121
08122 $tm[0] = 1;
08123 $tm[1] = 0;
08124 $tm[2] = 0;
08125 $tm[3] = 1;
08126 $tm[4] = $t_x * $this->k;
08127 $tm[5] = -$t_y * $this->k;
08128
08129 $this->Transform($tm);
08130 }
08131
08141 public function Rotate($angle, $x='', $y='') {
08142 if ($x === '') {
08143 $x = $this->x;
08144 }
08145 if ($y === '') {
08146 $y = $this->y;
08147 }
08148 if ($this->rtl) {
08149 $x = $this->w - $x;
08150 $angle = -$angle;
08151 }
08152 $y = ($this->h - $y) * $this->k;
08153 $x *= $this->k;
08154
08155 $tm[0] = cos(deg2rad($angle));
08156 $tm[1] = sin(deg2rad($angle));
08157 $tm[2] = -$tm[1];
08158 $tm[3] = $tm[0];
08159 $tm[4] = $x + ($tm[1] * $y) - ($tm[0] * $x);
08160 $tm[5] = $y - ($tm[0] * $y) - ($tm[1] * $x);
08161
08162 $this->Transform($tm);
08163 }
08164
08174 public function SkewX($angle_x, $x='', $y='') {
08175 $this->Skew($angle_x, 0, $x, $y);
08176 }
08177
08187 public function SkewY($angle_y, $x='', $y='') {
08188 $this->Skew(0, $angle_y, $x, $y);
08189 }
08190
08201 public function Skew($angle_x, $angle_y, $x='', $y='') {
08202 if ($x === '') {
08203 $x = $this->x;
08204 }
08205 if ($y === '') {
08206 $y = $this->y;
08207 }
08208 if ($this->rtl) {
08209 $x = $this->w - $x;
08210 $angle_x = -$angle_x;
08211 }
08212 if (($angle_x <= -90) OR ($angle_x >= 90) OR ($angle_y <= -90) OR ($angle_y >= 90)) {
08213 $this->Error('Please use values between -90 and +90 degrees for Skewing.');
08214 }
08215 $x *= $this->k;
08216 $y = ($this->h - $y) * $this->k;
08217
08218 $tm[0] = 1;
08219 $tm[1] = tan(deg2rad($angle_y));
08220 $tm[2] = tan(deg2rad($angle_x));
08221 $tm[3] = 1;
08222 $tm[4] = -$tm[2] * $y;
08223 $tm[5] = -$tm[1] * $x;
08224
08225 $this->Transform($tm);
08226 }
08227
08234 protected function Transform($tm) {
08235 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5]));
08236
08237 $this->transfmatrix[$this->transfmatrix_key][] = array('a' => $tm[0], 'b' => $tm[1], 'c' => $tm[2], 'd' => $tm[3], 'e' => $tm[4], 'f' => $tm[5]);
08238
08239 if (end($this->transfmrk[$this->page]) !== false) {
08240 $key = key($this->transfmrk[$this->page]);
08241 $this->transfmrk[$this->page][$key] = $this->pagelen[$this->page];
08242 }
08243 }
08244
08245
08246
08247
08248
08249
08250
08258 public function SetLineWidth($width) {
08259
08260 $this->LineWidth = $width;
08261 $this->linestyleWidth = sprintf('%.2F w', ($width * $this->k));
08262 if ($this->page > 0) {
08263 $this->_out($this->linestyleWidth);
08264 }
08265 }
08266
08274 public function GetLineWidth() {
08275 return $this->LineWidth;
08276 }
08277
08299 public function SetLineStyle($style) {
08300 if (!is_array($style)) {
08301 return;
08302 }
08303 extract($style);
08304 if (isset($width)) {
08305 $width_prev = $this->LineWidth;
08306 $this->SetLineWidth($width);
08307 $this->LineWidth = $width_prev;
08308 }
08309 if (isset($cap)) {
08310 $ca = array('butt' => 0, 'round'=> 1, 'square' => 2);
08311 if (isset($ca[$cap])) {
08312 $this->linestyleCap = $ca[$cap].' J';
08313 $this->_out($this->linestyleCap);
08314 }
08315 }
08316 if (isset($join)) {
08317 $ja = array('miter' => 0, 'round' => 1, 'bevel' => 2);
08318 if (isset($ja[$join])) {
08319 $this->linestyleJoin = $ja[$join].' j';
08320 $this->_out($this->linestyleJoin);
08321 }
08322 }
08323 if (isset($dash)) {
08324 $dash_string = '';
08325 if ($dash) {
08326 if (preg_match('/^.+,/', $dash) > 0) {
08327 $tab = explode(',', $dash);
08328 } else {
08329 $tab = array($dash);
08330 }
08331 $dash_string = '';
08332 foreach ($tab as $i => $v) {
08333 if ($i) {
08334 $dash_string .= ' ';
08335 }
08336 $dash_string .= sprintf("%.2F", $v);
08337 }
08338 }
08339 if (!isset($phase) OR !$dash) {
08340 $phase = 0;
08341 }
08342 $this->linestyleDash = sprintf("[%s] %.2F d", $dash_string, $phase);
08343 $this->_out($this->linestyleDash);
08344 }
08345 if (isset($color)) {
08346 $this->SetDrawColorArray($color);
08347 }
08348 }
08349
08350
08351
08352
08353
08354
08355
08356
08357 protected function _outPoint($x, $y) {
08358 if ($this->rtl) {
08359 $x = $this->w - $x;
08360 }
08361 $this->_out(sprintf("%.2F %.2F m", $x * $this->k, ($this->h - $y) * $this->k));
08362 }
08363
08364
08365
08366
08367
08368
08369
08370
08371 protected function _outLine($x, $y) {
08372 if ($this->rtl) {
08373 $x = $this->w - $x;
08374 }
08375 $this->_out(sprintf("%.2F %.2F l", $x * $this->k, ($this->h - $y) * $this->k));
08376 }
08377
08388 protected function _outRect($x, $y, $w, $h, $op) {
08389 if ($this->rtl) {
08390 $x = $this->w - $x - $w;
08391 }
08392 $this->_out(sprintf('%.2F %.2F %.2F %.2F re %s', $x*$this->k, ($this->h-$y)*$this->k, $w*$this->k, -$h*$this->k, $op));
08393 }
08394
08395
08396
08397
08398
08399
08400
08401
08402
08403
08404
08405
08406
08407 protected function _outCurve($x1, $y1, $x2, $y2, $x3, $y3) {
08408 if ($this->rtl) {
08409 $x1 = $this->w - $x1;
08410 $x2 = $this->w - $x2;
08411 $x3 = $this->w - $x3;
08412 }
08413 $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));
08414 }
08415
08427 public function Line($x1, $y1, $x2, $y2, $style=array()) {
08428 if (is_array($style)) {
08429 $this->SetLineStyle($style);
08430 }
08431 $this->_outPoint($x1, $y1);
08432 $this->_outLine($x2, $y2);
08433 $this->_out(' S');
08434 }
08435
08462 public function Rect($x, $y, $w, $h, $style='', $border_style=array(), $fill_color=array()) {
08463 if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
08464 $this->SetFillColorArray($fill_color);
08465 }
08466 switch ($style) {
08467 case 'F': {
08468 $op = 'f';
08469 $border_style = array();
08470 $this->_outRect($x, $y, $w, $h, $op);
08471 break;
08472 }
08473 case 'DF':
08474 case 'FD': {
08475 if ((!$border_style) OR (isset($border_style['all']))) {
08476 $op = 'B';
08477 if (isset($border_style['all'])) {
08478 $this->SetLineStyle($border_style['all']);
08479 $border_style = array();
08480 }
08481 } else {
08482 $op = 'f';
08483 }
08484 $this->_outRect($x, $y, $w, $h, $op);
08485 break;
08486 }
08487 case 'CNZ': {
08488 $op = 'W n';
08489 $this->_outRect($x, $y, $w, $h, $op);
08490 break;
08491 }
08492 case 'CEO': {
08493 $op = 'W* n';
08494 $this->_outRect($x, $y, $w, $h, $op);
08495 break;
08496 }
08497 default: {
08498 $op = 'S';
08499 if ((!$border_style) OR (isset($border_style['all']))) {
08500 if (isset($border_style['all']) AND $border_style['all']) {
08501 $this->SetLineStyle($border_style['all']);
08502 $border_style = array();
08503 }
08504 $this->_outRect($x, $y, $w, $h, $op);
08505 }
08506 break;
08507 }
08508 }
08509 if ($border_style) {
08510 $border_style2 = array();
08511 foreach ($border_style as $line => $value) {
08512 $lenght = strlen($line);
08513 for ($i = 0; $i < $lenght; ++$i) {
08514 $border_style2[$line[$i]] = $value;
08515 }
08516 }
08517 $border_style = $border_style2;
08518 if (isset($border_style['L']) AND $border_style['L']) {
08519 $this->Line($x, $y, $x, $y + $h, $border_style['L']);
08520 }
08521 if (isset($border_style['T']) AND $border_style['T']) {
08522 $this->Line($x, $y, $x + $w, $y, $border_style['T']);
08523 }
08524 if (isset($border_style['R']) AND $border_style['R']) {
08525 $this->Line($x + $w, $y, $x + $w, $y + $h, $border_style['R']);
08526 }
08527 if (isset($border_style['B']) AND $border_style['B']) {
08528 $this->Line($x, $y + $h, $x + $w, $y + $h, $border_style['B']);
08529 }
08530 }
08531 }
08532
08533
08560 public function Curve($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3, $style='', $line_style=array(), $fill_color=array()) {
08561 if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
08562 $this->SetFillColorArray($fill_color);
08563 }
08564 switch ($style) {
08565 case 'F': {
08566 $op = 'f';
08567 $line_style = array();
08568 break;
08569 }
08570 case 'FD':
08571 case 'DF': {
08572 $op = 'B';
08573 break;
08574 }
08575 case 'CNZ': {
08576 $op = 'W n';
08577 break;
08578 }
08579 case 'CEO': {
08580 $op = 'W* n';
08581 break;
08582 }
08583 default: {
08584 $op = 'S';
08585 break;
08586 }
08587 }
08588 if ($line_style) {
08589 $this->SetLineStyle($line_style);
08590 }
08591 $this->_outPoint($x0, $y0);
08592 $this->_outCurve($x1, $y1, $x2, $y2, $x3, $y3);
08593 $this->_out($op);
08594 }
08595
08617 public function Polycurve($x0, $y0, $segments, $style='', $line_style=array(), $fill_color=array()) {
08618 if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
08619 $this->SetFillColorArray($fill_color);
08620 }
08621 switch ($style) {
08622 case 'F': {
08623 $op = 'f';
08624 $line_style = array();
08625 break;
08626 }
08627 case 'FD':
08628 case 'DF': {
08629 $op = 'B';
08630 break;
08631 }
08632 case 'CNZ': {
08633 $op = 'W n';
08634 break;
08635 }
08636 case 'CEO': {
08637 $op = 'W* n';
08638 break;
08639 }
08640 default: {
08641 $op = 'S';
08642 break;
08643 }
08644 }
08645 if ($line_style) {
08646 $this->SetLineStyle($line_style);
08647 }
08648 $this->_outPoint($x0, $y0);
08649 foreach ($segments as $segment) {
08650 list($x1, $y1, $x2, $y2, $x3, $y3) = $segment;
08651 $this->_outCurve($x1, $y1, $x2, $y2, $x3, $y3);
08652 }
08653 $this->_out($op);
08654 }
08655
08681 public function Ellipse($x0, $y0, $rx, $ry=0, $angle=0, $astart=0, $afinish=360, $style='', $line_style=array(), $fill_color=array(), $nc=8) {
08682 if ($angle) {
08683 $this->StartTransform();
08684 $this->Rotate($angle, $x0, $y0);
08685 $this->Ellipse($x0, $y0, $rx, $ry, 0, $astart, $afinish, $style, $line_style, $fill_color, $nc);
08686 $this->StopTransform();
08687 return;
08688 }
08689 if ($rx) {
08690 if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
08691 $this->SetFillColorArray($fill_color);
08692 }
08693 switch ($style) {
08694 case 'F': {
08695 $op = 'f';
08696 $line_style = array();
08697 break;
08698 }
08699 case 'FD':
08700 case 'DF': {
08701 $op = 'B';
08702 break;
08703 }
08704 case 'C': {
08705 $op = 's';
08706 break;
08707 }
08708 case 'CNZ': {
08709 $op = 'W n';
08710 break;
08711 }
08712 case 'CEO': {
08713 $op = 'W* n';
08714 break;
08715 }
08716 default: {
08717 $op = 'S';
08718 break;
08719 }
08720 }
08721 if ($line_style) {
08722 $this->SetLineStyle($line_style);
08723 }
08724 if (!$ry) {
08725 $ry = $rx;
08726 }
08727 $rx *= $this->k;
08728 $ry *= $this->k;
08729 if ($nc < 2) {
08730 $nc = 2;
08731 }
08732 $astart = deg2rad((float) $astart);
08733 $afinish = deg2rad((float) $afinish);
08734 $total_angle = $afinish - $astart;
08735 $dt = $total_angle / $nc;
08736 $dtm = $dt / 3;
08737 $x0 *= $this->k;
08738 $y0 = ($this->h - $y0) * $this->k;
08739 $t1 = $astart;
08740 $a0 = $x0 + ($rx * cos($t1));
08741 $b0 = $y0 + ($ry * sin($t1));
08742 $c0 = -$rx * sin($t1);
08743 $d0 = $ry * cos($t1);
08744 $this->_outPoint($a0 / $this->k, $this->h - ($b0 / $this->k));
08745 for ($i = 1; $i <= $nc; ++$i) {
08746
08747 $t1 = ($i * $dt) + $astart;
08748 $a1 = $x0 + ($rx * cos($t1));
08749 $b1 = $y0 + ($ry * sin($t1));
08750 $c1 = -$rx * sin($t1);
08751 $d1 = $ry * cos($t1);
08752 $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));
08753 $a0 = $a1;
08754 $b0 = $b1;
08755 $c0 = $c1;
08756 $d0 = $d1;
08757 }
08758 $this->_out($op);
08759 }
08760 }
08761
08785 public function Circle($x0, $y0, $r, $astart=0, $afinish=360, $style='', $line_style=array(), $fill_color=array(), $nc=8) {
08786 $this->Ellipse($x0, $y0, $r, 0, 0, $astart, $afinish, $style, $line_style, $fill_color, $nc);
08787 }
08788
08811 public function PolyLine($p, $style='', $line_style=array(), $fill_color=array()) {
08812 $this->Polygon($p, $style, $line_style, $fill_color, false);
08813 }
08814
08837 public function Polygon($p, $style='', $line_style=array(), $fill_color=array(), $closed=true) {
08838 $nc = count($p);
08839 $np = $nc / 2;
08840 if ($closed) {
08841
08842 for ($i = 0; $i < 4; ++$i) {
08843 $p[$nc + $i] = $p[$i];
08844 }
08845
08846 if (isset($line_style[0])) {
08847 $line_style[$np] = $line_style[0];
08848 }
08849 $nc += 4;
08850 }
08851 if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
08852 $this->SetFillColorArray($fill_color);
08853 }
08854 switch ($style) {
08855 case 'F': {
08856 $line_style = array();
08857 $op = 'f';
08858 break;
08859 }
08860 case 'FD':
08861 case 'DF': {
08862 $op = 'B';
08863 break;
08864 }
08865 case 'CNZ': {
08866 $op = 'W n';
08867 break;
08868 }
08869 case 'CEO': {
08870 $op = 'W* n';
08871 break;
08872 }
08873 default: {
08874 $op = 'S';
08875 break;
08876 }
08877 }
08878 $draw = true;
08879 if ($line_style) {
08880 if (isset($line_style['all'])) {
08881 $this->SetLineStyle($line_style['all']);
08882 } else {
08883 $draw = false;
08884 if ($op == 'B') {
08885
08886 $op = 'f';
08887 $this->_outPoint($p[0], $p[1]);
08888 for ($i = 2; $i < $nc; $i = $i + 2) {
08889 $this->_outLine($p[$i], $p[$i + 1]);
08890 }
08891 $this->_out($op);
08892 }
08893
08894 $this->_outPoint($p[0], $p[1]);
08895 for ($i = 2; $i < $nc; $i = $i + 2) {
08896 $line_num = ($i / 2) - 1;
08897 if (isset($line_style[$line_num])) {
08898 if ($line_style[$line_num] != 0) {
08899 if (is_array($line_style[$line_num])) {
08900 $this->_out('S');
08901 $this->SetLineStyle($line_style[$line_num]);
08902 $this->_outPoint($p[$i - 2], $p[$i - 1]);
08903 $this->_outLine($p[$i], $p[$i + 1]);
08904 $this->_out('S');
08905 $this->_outPoint($p[$i], $p[$i + 1]);
08906 } else {
08907 $this->_outLine($p[$i], $p[$i + 1]);
08908 }
08909 }
08910 } else {
08911 $this->_outLine($p[$i], $p[$i + 1]);
08912 }
08913 }
08914 $this->_out($op);
08915 }
08916 }
08917 if ($draw) {
08918 $this->_outPoint($p[0], $p[1]);
08919 for ($i = 2; $i < $nc; $i = $i + 2) {
08920 $this->_outLine($p[$i], $p[$i + 1]);
08921 }
08922 $this->_out($op);
08923 }
08924 }
08925
08962 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()) {
08963 if (3 > $ns) {
08964 $ns = 3;
08965 }
08966 if ($draw_circle) {
08967 $this->Circle($x0, $y0, $r, 0, 360, $circle_style, $circle_outLine_style, $circle_fill_color);
08968 }
08969 $p = array();
08970 for ($i = 0; $i < $ns; ++$i) {
08971 $a = $angle + ($i * 360 / $ns);
08972 $a_rad = deg2rad((float) $a);
08973 $p[] = $x0 + ($r * sin($a_rad));
08974 $p[] = $y0 + ($r * cos($a_rad));
08975 }
08976 $this->Polygon($p, $style, $line_style, $fill_color);
08977 }
08978
09017 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()) {
09018 if ($nv < 2) {
09019 $nv = 2;
09020 }
09021 if ($draw_circle) {
09022 $this->Circle($x0, $y0, $r, 0, 360, $circle_style, $circle_outLine_style, $circle_fill_color);
09023 }
09024 $p2 = array();
09025 $visited = array();
09026 for ($i = 0; $i < $nv; ++$i) {
09027 $a = $angle + ($i * 360 / $nv);
09028 $a_rad = deg2rad((float) $a);
09029 $p2[] = $x0 + ($r * sin($a_rad));
09030 $p2[] = $y0 + ($r * cos($a_rad));
09031 $visited[] = false;
09032 }
09033 $p = array();
09034 $i = 0;
09035 do {
09036 $p[] = $p2[$i * 2];
09037 $p[] = $p2[($i * 2) + 1];
09038 $visited[$i] = true;
09039 $i += $ng;
09040 $i %= $nv;
09041 } while (!$visited[$i]);
09042 $this->Polygon($p, $style, $line_style, $fill_color);
09043 }
09044
09066 public function RoundedRect($x, $y, $w, $h, $r, $round_corner='1111', $style='', $border_style=array(), $fill_color=array()) {
09067 if ('0000' == $round_corner) {
09068 $this->Rect($x, $y, $w, $h, $style, $border_style, $fill_color);
09069 } else {
09070 if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
09071 $this->SetFillColorArray($fill_color);
09072 }
09073 switch ($style) {
09074 case 'F': {
09075 $border_style = array();
09076 $op = 'f';
09077 break;
09078 }
09079 case 'FD':
09080 case 'DF': {
09081 $op = 'B';
09082 break;
09083 }
09084 case 'CNZ': {
09085 $op = 'W n';
09086 break;
09087 }
09088 case 'CEO': {
09089 $op = 'W* n';
09090 break;
09091 }
09092 default: {
09093 $op = 'S';
09094 break;
09095 }
09096 }
09097 if ($border_style) {
09098 $this->SetLineStyle($border_style);
09099 }
09100 $MyArc = 4 / 3 * (sqrt(2) - 1);
09101 $this->_outPoint($x + $r, $y);
09102 $xc = $x + $w - $r;
09103 $yc = $y + $r;
09104 $this->_outLine($xc, $y);
09105 if ($round_corner[0]) {
09106 $this->_outCurve($xc + ($r * $MyArc), $yc - $r, $xc + $r, $yc - ($r * $MyArc), $xc + $r, $yc);
09107 } else {
09108 $this->_outLine($x + $w, $y);
09109 }
09110 $xc = $x + $w - $r;
09111 $yc = $y + $h - $r;
09112 $this->_outLine($x + $w, $yc);
09113 if ($round_corner[1]) {
09114 $this->_outCurve($xc + $r, $yc + ($r * $MyArc), $xc + ($r * $MyArc), $yc + $r, $xc, $yc + $r);
09115 } else {
09116 $this->_outLine($x + $w, $y + $h);
09117 }
09118 $xc = $x + $r;
09119 $yc = $y + $h - $r;
09120 $this->_outLine($xc, $y + $h);
09121 if ($round_corner[2]) {
09122 $this->_outCurve($xc - ($r * $MyArc), $yc + $r, $xc - $r, $yc + ($r * $MyArc), $xc - $r, $yc);
09123 } else {
09124 $this->_outLine($x, $y + $h);
09125 }
09126 $xc = $x + $r;
09127 $yc = $y + $r;
09128 $this->_outLine($x, $yc);
09129 if ($round_corner[3]) {
09130 $this->_outCurve($xc - $r, $yc - ($r * $MyArc), $xc - ($r * $MyArc), $yc - $r, $xc, $yc - $r);
09131 } else {
09132 $this->_outLine($x, $y);
09133 $this->_outLine($x + $r, $y);
09134 }
09135 $this->_out($op);
09136 }
09137 }
09138
09151 public function Arrow($x0, $y0, $x1, $y1, $head_style=0, $arm_size=5, $arm_angle=15) {
09152
09153
09154 $dir_angle = rad2deg(atan2(($y0 - $y1), ($x0 - $x1)));
09155 $sx1 = $x1;
09156 $sy1 = $y1;
09157 if ($head_style > 0) {
09158
09159 $sx1 = $x1 + (($arm_size - $this->LineWidth) * cos(deg2rad($dir_angle)));
09160 $sy1 = $y1 + (($arm_size - $this->LineWidth) * sin(deg2rad($dir_angle)));
09161 }
09162
09163 $this->Line($x0, $y0, $sx1, $sy1);
09164
09165 $x2L = $x1 + ($arm_size * cos(deg2rad($dir_angle + $arm_angle)));
09166 $y2L = $y1 + ($arm_size * sin(deg2rad($dir_angle + $arm_angle)));
09167
09168 $x2R = $x1 + ($arm_size * cos(deg2rad($dir_angle - $arm_angle)));
09169 $y2R = $y1 + ($arm_size * sin(deg2rad($dir_angle - $arm_angle)));
09170 $mode = 'D';
09171 $style = array();
09172 switch ($head_style) {
09173 case 0: {
09174
09175 $mode = 'D';
09176 $style = array(1, 1, 0);
09177 break;
09178 }
09179 case 1: {
09180
09181 $mode = 'D';
09182 break;
09183 }
09184 case 2: {
09185
09186 $mode = 'DF';
09187 break;
09188 }
09189 case 3: {
09190
09191 $mode = 'F';
09192 break;
09193 }
09194 }
09195 $this->Polygon(array($x2L, $y2L, $x1, $y1, $x2R, $y2R), $mode, $style, array());
09196 }
09197
09198
09199
09200
09210 protected function utf8StrRev($str, $setbom=false, $forcertl=false) {
09211 return $this->arrUTF8ToUTF16BE($this->utf8Bidi($this->UTF8StringToArray($str), $str, $forcertl), $setbom);
09212 }
09213
09224 protected function utf8Bidi($ta, $str='', $forcertl=false) {
09225 global $unicode, $unicode_mirror, $unicode_arlet, $laa_array, $diacritics;
09226
09227 $pel = 0;
09228
09229 $maxlevel = 0;
09230 if ($this->empty_string($str)) {
09231
09232 $str = $this->UTF8ArrSubString($ta);
09233 }
09234
09235 if (preg_match(K_RE_PATTERN_ARABIC, $str)) {
09236 $arabic = true;
09237 } else {
09238 $arabic = false;
09239 }
09240
09241 if (!($forcertl OR $arabic OR preg_match(K_RE_PATTERN_RTL, $str))) {
09242 return $ta;
09243 }
09244
09245
09246 $numchars = count($ta);
09247
09248 if ($forcertl == 'R') {
09249 $pel = 1;
09250 } elseif ($forcertl == 'L') {
09251 $pel = 0;
09252 } else {
09253
09254
09255 for ($i=0; $i < $numchars; ++$i) {
09256 $type = $unicode[$ta[$i]];
09257 if ($type == 'L') {
09258 $pel = 0;
09259 break;
09260 } elseif (($type == 'AL') OR ($type == 'R')) {
09261 $pel = 1;
09262 break;
09263 }
09264 }
09265 }
09266
09267
09268 $cel = $pel;
09269
09270 $dos = 'N';
09271 $remember = array();
09272
09273 $sor = $pel % 2 ? 'R' : 'L';
09274 $eor = $sor;
09275
09276
09277 $chardata = Array();
09278
09279
09280
09281 for ($i=0; $i < $numchars; ++$i) {
09282 if ($ta[$i] == K_RLE) {
09283
09284
09285
09286 $next_level = $cel + ($cel % 2) + 1;
09287 if ($next_level < 62) {
09288 $remember[] = array('num' => K_RLE, 'cel' => $cel, 'dos' => $dos);
09289 $cel = $next_level;
09290 $dos = 'N';
09291 $sor = $eor;
09292 $eor = $cel % 2 ? 'R' : 'L';
09293 }
09294 } elseif ($ta[$i] == K_LRE) {
09295
09296
09297
09298 $next_level = $cel + 2 - ($cel % 2);
09299 if ( $next_level < 62 ) {
09300 $remember[] = array('num' => K_LRE, 'cel' => $cel, 'dos' => $dos);
09301 $cel = $next_level;
09302 $dos = 'N';
09303 $sor = $eor;
09304 $eor = $cel % 2 ? 'R' : 'L';
09305 }
09306 } elseif ($ta[$i] == K_RLO) {
09307
09308
09309
09310 $next_level = $cel + ($cel % 2) + 1;
09311 if ($next_level < 62) {
09312 $remember[] = array('num' => K_RLO, 'cel' => $cel, 'dos' => $dos);
09313 $cel = $next_level;
09314 $dos = 'R';
09315 $sor = $eor;
09316 $eor = $cel % 2 ? 'R' : 'L';
09317 }
09318 } elseif ($ta[$i] == K_LRO) {
09319
09320
09321
09322 $next_level = $cel + 2 - ($cel % 2);
09323 if ( $next_level < 62 ) {
09324 $remember[] = array('num' => K_LRO, 'cel' => $cel, 'dos' => $dos);
09325 $cel = $next_level;
09326 $dos = 'L';
09327 $sor = $eor;
09328 $eor = $cel % 2 ? 'R' : 'L';
09329 }
09330 } elseif ($ta[$i] == K_PDF) {
09331
09332 if (count($remember)) {
09333 $last = count($remember ) - 1;
09334 if (($remember[$last]['num'] == K_RLE) OR
09335 ($remember[$last]['num'] == K_LRE) OR
09336 ($remember[$last]['num'] == K_RLO) OR
09337 ($remember[$last]['num'] == K_LRO)) {
09338 $match = array_pop($remember);
09339 $cel = $match['cel'];
09340 $dos = $match['dos'];
09341 $sor = $eor;
09342 $eor = ($cel > $match['cel'] ? $cel : $match['cel']) % 2 ? 'R' : 'L';
09343 }
09344 }
09345 } elseif (($ta[$i] != K_RLE) AND
09346 ($ta[$i] != K_LRE) AND
09347 ($ta[$i] != K_RLO) AND
09348 ($ta[$i] != K_LRO) AND
09349 ($ta[$i] != K_PDF)) {
09350
09351
09352
09353 if ($dos != 'N') {
09354 $chardir = $dos;
09355 } else {
09356 if (isset($unicode[$ta[$i]])) {
09357 $chardir = $unicode[$ta[$i]];
09358 } else {
09359 $chardir = 'L';
09360 }
09361 }
09362
09363 $chardata[] = array('char' => $ta[$i], 'level' => $cel, 'type' => $chardir, 'sor' => $sor, 'eor' => $eor);
09364 }
09365 }
09366
09367
09368
09369
09370
09371
09372
09373
09374 $numchars = count($chardata);
09375
09376
09377 $prevlevel = -1;
09378 $levcount = 0;
09379 for ($i=0; $i < $numchars; ++$i) {
09380 if ($chardata[$i]['type'] == 'NSM') {
09381 if ($levcount) {
09382 $chardata[$i]['type'] = $chardata[$i]['sor'];
09383 } elseif ($i > 0) {
09384 $chardata[$i]['type'] = $chardata[($i-1)]['type'];
09385 }
09386 }
09387 if ($chardata[$i]['level'] != $prevlevel) {
09388 $levcount = 0;
09389 } else {
09390 ++$levcount;
09391 }
09392 $prevlevel = $chardata[$i]['level'];
09393 }
09394
09395
09396 $prevlevel = -1;
09397 $levcount = 0;
09398 for ($i=0; $i < $numchars; ++$i) {
09399 if ($chardata[$i]['char'] == 'EN') {
09400 for ($j=$levcount; $j >= 0; $j--) {
09401 if ($chardata[$j]['type'] == 'AL') {
09402 $chardata[$i]['type'] = 'AN';
09403 } elseif (($chardata[$j]['type'] == 'L') OR ($chardata[$j]['type'] == 'R')) {
09404 break;
09405 }
09406 }
09407 }
09408 if ($chardata[$i]['level'] != $prevlevel) {
09409 $levcount = 0;
09410 } else {
09411 ++$levcount;
09412 }
09413 $prevlevel = $chardata[$i]['level'];
09414 }
09415
09416
09417 for ($i=0; $i < $numchars; ++$i) {
09418 if ($chardata[$i]['type'] == 'AL') {
09419 $chardata[$i]['type'] = 'R';
09420 }
09421 }
09422
09423
09424 $prevlevel = -1;
09425 $levcount = 0;
09426 for ($i=0; $i < $numchars; ++$i) {
09427 if (($levcount > 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) {
09428 if (($chardata[$i]['type'] == 'ES') AND ($chardata[($i-1)]['type'] == 'EN') AND ($chardata[($i+1)]['type'] == 'EN')) {
09429 $chardata[$i]['type'] = 'EN';
09430 } elseif (($chardata[$i]['type'] == 'CS') AND ($chardata[($i-1)]['type'] == 'EN') AND ($chardata[($i+1)]['type'] == 'EN')) {
09431 $chardata[$i]['type'] = 'EN';
09432 } elseif (($chardata[$i]['type'] == 'CS') AND ($chardata[($i-1)]['type'] == 'AN') AND ($chardata[($i+1)]['type'] == 'AN')) {
09433 $chardata[$i]['type'] = 'AN';
09434 }
09435 }
09436 if ($chardata[$i]['level'] != $prevlevel) {
09437 $levcount = 0;
09438 } else {
09439 ++$levcount;
09440 }
09441 $prevlevel = $chardata[$i]['level'];
09442 }
09443
09444
09445 $prevlevel = -1;
09446 $levcount = 0;
09447 for ($i=0; $i < $numchars; ++$i) {
09448 if ($chardata[$i]['type'] == 'ET') {
09449 if (($levcount > 0) AND ($chardata[($i-1)]['type'] == 'EN')) {
09450 $chardata[$i]['type'] = 'EN';
09451 } else {
09452 $j = $i+1;
09453 while (($j < $numchars) AND ($chardata[$j]['level'] == $prevlevel)) {
09454 if ($chardata[$j]['type'] == 'EN') {
09455 $chardata[$i]['type'] = 'EN';
09456 break;
09457 } elseif ($chardata[$j]['type'] != 'ET') {
09458 break;
09459 }
09460 ++$j;
09461 }
09462 }
09463 }
09464 if ($chardata[$i]['level'] != $prevlevel) {
09465 $levcount = 0;
09466 } else {
09467 ++$levcount;
09468 }
09469 $prevlevel = $chardata[$i]['level'];
09470 }
09471
09472
09473 $prevlevel = -1;
09474 $levcount = 0;
09475 for ($i=0; $i < $numchars; ++$i) {
09476 if (($chardata[$i]['type'] == 'ET') OR ($chardata[$i]['type'] == 'ES') OR ($chardata[$i]['type'] == 'CS')) {
09477 $chardata[$i]['type'] = 'ON';
09478 }
09479 if ($chardata[$i]['level'] != $prevlevel) {
09480 $levcount = 0;
09481 } else {
09482 ++$levcount;
09483 }
09484 $prevlevel = $chardata[$i]['level'];
09485 }
09486
09487
09488 $prevlevel = -1;
09489 $levcount = 0;
09490 for ($i=0; $i < $numchars; ++$i) {
09491 if ($chardata[$i]['char'] == 'EN') {
09492 for ($j=$levcount; $j >= 0; $j--) {
09493 if ($chardata[$j]['type'] == 'L') {
09494 $chardata[$i]['type'] = 'L';
09495 } elseif ($chardata[$j]['type'] == 'R') {
09496 break;
09497 }
09498 }
09499 }
09500 if ($chardata[$i]['level'] != $prevlevel) {
09501 $levcount = 0;
09502 } else {
09503 ++$levcount;
09504 }
09505 $prevlevel = $chardata[$i]['level'];
09506 }
09507
09508
09509 $prevlevel = -1;
09510 $levcount = 0;
09511 for ($i=0; $i < $numchars; ++$i) {
09512 if (($levcount > 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) {
09513 if (($chardata[$i]['type'] == 'N') AND ($chardata[($i-1)]['type'] == 'L') AND ($chardata[($i+1)]['type'] == 'L')) {
09514 $chardata[$i]['type'] = 'L';
09515 } elseif (($chardata[$i]['type'] == 'N') AND
09516 (($chardata[($i-1)]['type'] == 'R') OR ($chardata[($i-1)]['type'] == 'EN') OR ($chardata[($i-1)]['type'] == 'AN')) AND
09517 (($chardata[($i+1)]['type'] == 'R') OR ($chardata[($i+1)]['type'] == 'EN') OR ($chardata[($i+1)]['type'] == 'AN'))) {
09518 $chardata[$i]['type'] = 'R';
09519 } elseif ($chardata[$i]['type'] == 'N') {
09520
09521 $chardata[$i]['type'] = $chardata[$i]['sor'];
09522 }
09523 } elseif (($levcount == 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) {
09524
09525 if (($chardata[$i]['type'] == 'N') AND ($chardata[$i]['sor'] == 'L') AND ($chardata[($i+1)]['type'] == 'L')) {
09526 $chardata[$i]['type'] = 'L';
09527 } elseif (($chardata[$i]['type'] == 'N') AND
09528 (($chardata[$i]['sor'] == 'R') OR ($chardata[$i]['sor'] == 'EN') OR ($chardata[$i]['sor'] == 'AN')) AND
09529 (($chardata[($i+1)]['type'] == 'R') OR ($chardata[($i+1)]['type'] == 'EN') OR ($chardata[($i+1)]['type'] == 'AN'))) {
09530 $chardata[$i]['type'] = 'R';
09531 } elseif ($chardata[$i]['type'] == 'N') {
09532
09533 $chardata[$i]['type'] = $chardata[$i]['sor'];
09534 }
09535 } elseif (($levcount > 0) AND ((($i+1) == $numchars) OR (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] != $prevlevel))) {
09536
09537 if (($chardata[$i]['type'] == 'N') AND ($chardata[($i-1)]['type'] == 'L') AND ($chardata[$i]['eor'] == 'L')) {
09538 $chardata[$i]['type'] = 'L';
09539 } elseif (($chardata[$i]['type'] == 'N') AND
09540 (($chardata[($i-1)]['type'] == 'R') OR ($chardata[($i-1)]['type'] == 'EN') OR ($chardata[($i-1)]['type'] == 'AN')) AND
09541 (($chardata[$i]['eor'] == 'R') OR ($chardata[$i]['eor'] == 'EN') OR ($chardata[$i]['eor'] == 'AN'))) {
09542 $chardata[$i]['type'] = 'R';
09543 } elseif ($chardata[$i]['type'] == 'N') {
09544
09545 $chardata[$i]['type'] = $chardata[$i]['sor'];
09546 }
09547 } elseif ($chardata[$i]['type'] == 'N') {
09548
09549 $chardata[$i]['type'] = $chardata[$i]['sor'];
09550 }
09551 if ($chardata[$i]['level'] != $prevlevel) {
09552 $levcount = 0;
09553 } else {
09554 ++$levcount;
09555 }
09556 $prevlevel = $chardata[$i]['level'];
09557 }
09558
09559
09560
09561 for ($i=0; $i < $numchars; ++$i) {
09562 $odd = $chardata[$i]['level'] % 2;
09563 if ($odd) {
09564 if (($chardata[$i]['type'] == 'L') OR ($chardata[$i]['type'] == 'AN') OR ($chardata[$i]['type'] == 'EN')) {
09565 $chardata[$i]['level'] += 1;
09566 }
09567 } else {
09568 if ($chardata[$i]['type'] == 'R') {
09569 $chardata[$i]['level'] += 1;
09570 } elseif (($chardata[$i]['type'] == 'AN') OR ($chardata[$i]['type'] == 'EN')) {
09571 $chardata[$i]['level'] += 2;
09572 }
09573 }
09574 $maxlevel = max($chardata[$i]['level'],$maxlevel);
09575 }
09576
09577
09578
09579
09580
09581
09582 for ($i=0; $i < $numchars; ++$i) {
09583 if (($chardata[$i]['type'] == 'B') OR ($chardata[$i]['type'] == 'S')) {
09584 $chardata[$i]['level'] = $pel;
09585 } elseif ($chardata[$i]['type'] == 'WS') {
09586 $j = $i+1;
09587 while ($j < $numchars) {
09588 if ((($chardata[$j]['type'] == 'B') OR ($chardata[$j]['type'] == 'S')) OR
09589 (($j == ($numchars-1)) AND ($chardata[$j]['type'] == 'WS'))) {
09590 $chardata[$i]['level'] = $pel;
09591 break;
09592 } elseif ($chardata[$j]['type'] != 'WS') {
09593 break;
09594 }
09595 ++$j;
09596 }
09597 }
09598 }
09599
09600
09601
09602 if ($arabic) {
09603 $endedletter = array(1569,1570,1571,1572,1573,1575,1577,1583,1584,1585,1586,1608,1688);
09604 $alfletter = array(1570,1571,1573,1575);
09605 $chardata2 = $chardata;
09606 $laaletter = false;
09607 $charAL = array();
09608 $x = 0;
09609 for ($i=0; $i < $numchars; ++$i) {
09610 if (($unicode[$chardata[$i]['char']] == 'AL') OR ($chardata[$i]['char'] == 32) OR ($chardata[$i]['char'] == 8204)) {
09611 $charAL[$x] = $chardata[$i];
09612 $charAL[$x]['i'] = $i;
09613 $chardata[$i]['x'] = $x;
09614 ++$x;
09615 }
09616 }
09617 $numAL = $x;
09618 for ($i=0; $i < $numchars; ++$i) {
09619 $thischar = $chardata[$i];
09620 if ($i > 0) {
09621 $prevchar = $chardata[($i-1)];
09622 } else {
09623 $prevchar = false;
09624 }
09625 if (($i+1) < $numchars) {
09626 $nextchar = $chardata[($i+1)];
09627 } else {
09628 $nextchar = false;
09629 }
09630 if ($unicode[$thischar['char']] == 'AL') {
09631 $x = $thischar['x'];
09632 if ($x > 0) {
09633 $prevchar = $charAL[($x-1)];
09634 } else {
09635 $prevchar = false;
09636 }
09637 if (($x+1) < $numAL) {
09638 $nextchar = $charAL[($x+1)];
09639 } else {
09640 $nextchar = false;
09641 }
09642
09643 if (($prevchar !== false) AND ($prevchar['char'] == 1604) AND (in_array($thischar['char'], $alfletter))) {
09644 $arabicarr = $laa_array;
09645 $laaletter = true;
09646 if ($x > 1) {
09647 $prevchar = $charAL[($x-2)];
09648 } else {
09649 $prevchar = false;
09650 }
09651 } else {
09652 $arabicarr = $unicode_arlet;
09653 $laaletter = false;
09654 }
09655 if (($prevchar !== false) AND ($nextchar !== false) AND
09656 (($unicode[$prevchar['char']] == 'AL') OR ($unicode[$prevchar['char']] == 'NSM')) AND
09657 (($unicode[$nextchar['char']] == 'AL') OR ($unicode[$nextchar['char']] == 'NSM')) AND
09658 ($prevchar['type'] == $thischar['type']) AND
09659 ($nextchar['type'] == $thischar['type']) AND
09660 ($nextchar['char'] != 1567)) {
09661 if (in_array($prevchar['char'], $endedletter)) {
09662 if (isset($arabicarr[$thischar['char']][2])) {
09663
09664 $chardata2[$i]['char'] = $arabicarr[$thischar['char']][2];
09665 }
09666 } else {
09667 if (isset($arabicarr[$thischar['char']][3])) {
09668
09669 $chardata2[$i]['char'] = $arabicarr[$thischar['char']][3];
09670 }
09671 }
09672 } elseif (($nextchar !== false) AND
09673 (($unicode[$nextchar['char']] == 'AL') OR ($unicode[$nextchar['char']] == 'NSM')) AND
09674 ($nextchar['type'] == $thischar['type']) AND
09675 ($nextchar['char'] != 1567)) {
09676 if (isset($arabicarr[$chardata[$i]['char']][2])) {
09677
09678 $chardata2[$i]['char'] = $arabicarr[$thischar['char']][2];
09679 }
09680 } elseif ((($prevchar !== false) AND
09681 (($unicode[$prevchar['char']] == 'AL') OR ($unicode[$prevchar['char']] == 'NSM')) AND
09682 ($prevchar['type'] == $thischar['type'])) OR
09683 (($nextchar !== false) AND ($nextchar['char'] == 1567))) {
09684
09685 if (($i > 1) AND ($thischar['char'] == 1607) AND
09686 ($chardata[$i-1]['char'] == 1604) AND
09687 ($chardata[$i-2]['char'] == 1604)) {
09688
09689
09690 $chardata2[$i-2]['char'] = false;
09691 $chardata2[$i-1]['char'] = false;
09692 $chardata2[$i]['char'] = 65010;
09693 } else {
09694 if (($prevchar !== false) AND in_array($prevchar['char'], $endedletter)) {
09695 if (isset($arabicarr[$thischar['char']][0])) {
09696
09697 $chardata2[$i]['char'] = $arabicarr[$thischar['char']][0];
09698 }
09699 } else {
09700 if (isset($arabicarr[$thischar['char']][1])) {
09701
09702 $chardata2[$i]['char'] = $arabicarr[$thischar['char']][1];
09703 }
09704 }
09705 }
09706 } elseif (isset($arabicarr[$thischar['char']][0])) {
09707
09708 $chardata2[$i]['char'] = $arabicarr[$thischar['char']][0];
09709 }
09710
09711 if ($laaletter) {
09712
09713 $chardata2[($charAL[($x-1)]['i'])]['char'] = false;
09714 }
09715 }
09716 }
09717
09718
09719
09720
09721 $cw = &$this->CurrentFont['cw'];
09722 for ($i = 0; $i < ($numchars-1); ++$i) {
09723 if (($chardata2[$i]['char'] == 1617) AND (isset($diacritics[($chardata2[$i+1]['char'])]))) {
09724
09725 if (isset($cw[($diacritics[($chardata2[$i+1]['char'])])])) {
09726 $chardata2[$i]['char'] = false;
09727 $chardata2[$i+1]['char'] = $diacritics[($chardata2[$i+1]['char'])];
09728 }
09729 }
09730 }
09731
09732 foreach ($chardata2 as $key => $value) {
09733 if ($value['char'] === false) {
09734 unset($chardata2[$key]);
09735 }
09736 }
09737 $chardata = array_values($chardata2);
09738 $numchars = count($chardata);
09739 unset($chardata2);
09740 unset($arabicarr);
09741 unset($laaletter);
09742 unset($charAL);
09743 }
09744
09745
09746 for ($j=$maxlevel; $j > 0; $j--) {
09747 $ordarray = Array();
09748 $revarr = Array();
09749 $onlevel = false;
09750 for ($i=0; $i < $numchars; ++$i) {
09751 if ($chardata[$i]['level'] >= $j) {
09752 $onlevel = true;
09753 if (isset($unicode_mirror[$chardata[$i]['char']])) {
09754
09755 $chardata[$i]['char'] = $unicode_mirror[$chardata[$i]['char']];
09756 }
09757 $revarr[] = $chardata[$i];
09758 } else {
09759 if ($onlevel) {
09760 $revarr = array_reverse($revarr);
09761 $ordarray = array_merge($ordarray, $revarr);
09762 $revarr = Array();
09763 $onlevel = false;
09764 }
09765 $ordarray[] = $chardata[$i];
09766 }
09767 }
09768 if ($onlevel) {
09769 $revarr = array_reverse($revarr);
09770 $ordarray = array_merge($ordarray, $revarr);
09771 }
09772 $chardata = $ordarray;
09773 }
09774
09775 $ordarray = array();
09776 for ($i=0; $i < $numchars; ++$i) {
09777 $ordarray[] = $chardata[$i]['char'];
09778 }
09779
09780 return $ordarray;
09781 }
09782
09783
09784
09785
09786
09787
09788
09789
09790
09791
09792
09793
09794
09795 public function Bookmark($txt, $level=0, $y=-1, $page='') {
09796 if ($level < 0) {
09797 $level = 0;
09798 }
09799 if (isset($this->outlines[0])) {
09800 $lastoutline = end($this->outlines);
09801 $maxlevel = $lastoutline['l'] + 1;
09802 } else {
09803 $maxlevel = 0;
09804 }
09805 if ($level > $maxlevel) {
09806 $level = $maxlevel;
09807 }
09808 if ($y == -1) {
09809 $y = $this->GetY();
09810 }
09811 if (empty($page)) {
09812 $page = $this->PageNo();
09813 }
09814 $this->outlines[] = array('t' => $txt, 'l' => $level, 'y' => $y, 'p' => $page);
09815 }
09816
09817
09818
09819
09820
09821
09822
09823 protected function _putbookmarks() {
09824 $nb = count($this->outlines);
09825 if ($nb == 0) {
09826 return;
09827 }
09828 $lru = array();
09829 $level = 0;
09830 foreach ($this->outlines as $i => $o) {
09831 if ($o['l'] > 0) {
09832 $parent = $lru[($o['l'] - 1)];
09833
09834 $this->outlines[$i]['parent'] = $parent;
09835 $this->outlines[$parent]['last'] = $i;
09836 if ($o['l'] > $level) {
09837
09838 $this->outlines[$parent]['first'] = $i;
09839 }
09840 } else {
09841 $this->outlines[$i]['parent'] = $nb;
09842 }
09843 if (($o['l'] <= $level) AND ($i > 0)) {
09844
09845 $prev = $lru[$o['l']];
09846 $this->outlines[$prev]['next'] = $i;
09847 $this->outlines[$i]['prev'] = $prev;
09848 }
09849 $lru[$o['l']] = $i;
09850 $level = $o['l'];
09851 }
09852
09853 $n = $this->n + 1;
09854 foreach ($this->outlines as $i => $o) {
09855 $this->_newobj();
09856 $this->_out('<</Title '.$this->_textstring($o['t']));
09857 $this->_out('/Parent '.($n + $o['parent']).' 0 R');
09858 if (isset($o['prev']))
09859 $this->_out('/Prev '.($n + $o['prev']).' 0 R');
09860 if (isset($o['next']))
09861 $this->_out('/Next '.($n + $o['next']).' 0 R');
09862 if (isset($o['first']))
09863 $this->_out('/First '.($n + $o['first']).' 0 R');
09864 if (isset($o['last']))
09865 $this->_out('/Last '.($n + $o['last']).' 0 R');
09866 $this->_out(sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]', (1 + (2 * $o['p'])), ($this->pagedim[$o['p']]['h'] - ($o['y'] * $this->k))));
09867 $this->_out('/Count 0>>');
09868 $this->_out('endobj');
09869 }
09870
09871 $this->_newobj();
09872 $this->OutlineRoot = $this->n;
09873 $this->_out('<</Type /Outlines /First '.$n.' 0 R');
09874 $this->_out('/Last '.($n + $lru[0]).' 0 R>>');
09875 $this->_out('endobj');
09876 }
09877
09878
09879
09880
09881
09882
09883
09884
09885
09886
09887
09888 public function IncludeJS($script) {
09889 $this->javascript .= $script;
09890 }
09891
09892
09893
09894
09895
09896
09897
09898
09899
09900
09901 public function addJavascriptObject($script, $onload=false) {
09902 ++$this->js_obj_id;
09903 $this->js_objects[$this->js_obj_id] = array('js' => $script, 'onload' => $onload);
09904 return $this->js_obj_id;
09905 }
09906
09907
09908
09909
09910
09911
09912
09913 protected function _putjavascript() {
09914 if (empty($this->javascript) AND empty($this->js_objects)) {
09915 return;
09916 }
09917 if (strpos($this->javascript, 'this.addField') > 0) {
09918 if (!$this->ur) {
09919
09920 }
09921
09922
09923 $jsa = sprintf("ftcpdfdocsaved=this.addField('%s','%s',%d,[%.2F,%.2F,%.2F,%.2F]);", 'tcpdfdocsaved', 'text', 0, 0, 1, 0, 1);
09924 $jsb = "getField('tcpdfdocsaved').value='saved';";
09925 $this->javascript = $jsa."\n".$this->javascript."\n".$jsb;
09926 }
09927 $this->n_js = $this->_newobj();
09928 $this->_out('<<');
09929 $this->_out('/Names [');
09930 if (!empty($this->javascript)) {
09931 $this->_out('(EmbeddedJS) '.($this->n + 1).' 0 R');
09932 }
09933 if (!empty($this->js_objects)) {
09934 foreach ($this->js_objects as $key => $val) {
09935 if ($val['onload']) {
09936 $this->_out('(JS'.$key.') '.$key.' 0 R');
09937 }
09938 }
09939 }
09940 $this->_out(']');
09941 $this->_out('>>');
09942 $this->_out('endobj');
09943
09944 if (!empty($this->javascript)) {
09945 $this->_newobj();
09946 $this->_out('<<');
09947 $this->_out('/S /JavaScript');
09948 $this->_out('/JS '.$this->_textstring($this->javascript));
09949 $this->_out('>>');
09950 $this->_out('endobj');
09951 }
09952
09953 if (!empty($this->js_objects)) {
09954 foreach ($this->js_objects as $key => $val) {
09955 $this->offsets[$key] = $this->bufferlen;
09956 $this->_out($key.' 0 obj');
09957 $this->_out('<<');
09958 $this->_out('/S /JavaScript');
09959 $this->_out('/JS '.$this->_textstring($val['js']));
09960 $this->_out('>>');
09961 $this->_out('endobj');
09962 }
09963 }
09964 }
09965
09966
09967
09968
09969
09970
09971
09972
09973 protected function _JScolor($color) {
09974 static $aColors = array('transparent', 'black', 'white', 'red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'dkGray', 'gray', 'ltGray');
09975 if (substr($color,0,1) == '#') {
09976 return sprintf("['RGB',%.3F,%.3F,%.3F]", hexdec(substr($color,1,2))/255, hexdec(substr($color,3,2))/255, hexdec(substr($color,5,2))/255);
09977 }
09978 if (!in_array($color,$aColors)) {
09979 $this->Error('Invalid color: '.$color);
09980 }
09981 return 'color.'.$color;
09982 }
09983
09984
09985
09986
09987
09988
09989
09990
09991
09992
09993
09994
09995
09996
09997 protected function _addfield($type, $name, $x, $y, $w, $h, $prop) {
09998 if ($this->rtl) {
09999 $x = $x - $w;
10000 }
10001
10002 $this->javascript .= "if(getField('tcpdfdocsaved').value != 'saved') {";
10003 $k = $this->k;
10004 $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";
10005 $this->javascript .= 'f'.$name.'.textSize='.$this->FontSizePt.";\n";
10006 while (list($key, $val) = each($prop)) {
10007 if (strcmp(substr($key, -5), 'Color') == 0) {
10008 $val = $this->_JScolor($val);
10009 } else {
10010 $val = "'".$val."'";
10011 }
10012 $this->javascript .= 'f'.$name.'.'.$key.'='.$val.";\n";
10013 }
10014 if ($this->rtl) {
10015 $this->x -= $w;
10016 } else {
10017 $this->x += $w;
10018 }
10019 $this->javascript .= '}';
10020 }
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032 protected function getAnnotOptFromJSProp($prop) {
10033 if (isset($prop['aopt']) AND is_array($prop['aopt'])) {
10034
10035 return $prop['aopt'];
10036 }
10037 $opt = array();
10038
10039 if (isset($prop['alignment'])) {
10040 switch ($prop['alignment']) {
10041 case 'left': {
10042 $opt['q'] = 0;
10043 break;
10044 }
10045 case 'center': {
10046 $opt['q'] = 1;
10047 break;
10048 }
10049 case 'right': {
10050 $opt['q'] = 2;
10051 break;
10052 }
10053 default: {
10054 $opt['q'] = ($this->rtl)?2:0;
10055 break;
10056 }
10057 }
10058 }
10059
10060 if (isset($prop['lineWidth'])) {
10061 $linewidth = intval($prop['lineWidth']);
10062 } else {
10063 $linewidth = 1;
10064 }
10065
10066 if (isset($prop['borderStyle'])) {
10067 switch ($prop['borderStyle']) {
10068 case 'border.d':
10069 case 'dashed': {
10070 $opt['border'] = array(0, 0, $linewidth, array(3, 2));
10071 $opt['bs'] = array('w'=>$linewidth, 's'=>'D', 'd'=>array(3, 2));
10072 break;
10073 }
10074 case 'border.b':
10075 case 'beveled': {
10076 $opt['border'] = array(0, 0, $linewidth);
10077 $opt['bs'] = array('w'=>$linewidth, 's'=>'B');
10078 break;
10079 }
10080 case 'border.i':
10081 case 'inset': {
10082 $opt['border'] = array(0, 0, $linewidth);
10083 $opt['bs'] = array('w'=>$linewidth, 's'=>'I');
10084 break;
10085 }
10086 case 'border.u':
10087 case 'underline': {
10088 $opt['border'] = array(0, 0, $linewidth);
10089 $opt['bs'] = array('w'=>$linewidth, 's'=>'U');
10090 break;
10091 }
10092 default:
10093 case 'border.s':
10094 case 'solid': {
10095 $opt['border'] = array(0, 0, $linewidth);
10096 $opt['bs'] = array('w'=>$linewidth, 's'=>'S');
10097 break;
10098 }
10099 }
10100 }
10101 if (isset($prop['border']) AND is_array($prop['border'])) {
10102 $opt['border'] = $prop['border'];
10103 }
10104 if (!isset($opt['mk'])) {
10105 $opt['mk'] = array();
10106 }
10107 if (!isset($opt['mk']['if'])) {
10108 $opt['mk']['if'] = array();
10109 }
10110 $opt['mk']['if']['a'] = array(0.5, 0.5);
10111
10112 if (isset($prop['buttonAlignX'])) {
10113 $opt['mk']['if']['a'][0] = $prop['buttonAlignX'];
10114 }
10115
10116 if (isset($prop['buttonAlignY'])) {
10117 $opt['mk']['if']['a'][1] = $prop['buttonAlignY'];
10118 }
10119
10120 if (isset($prop['buttonFitBounds']) AND ($prop['buttonFitBounds'] == 'true')) {
10121 $opt['mk']['if']['fb'] = true;
10122 }
10123
10124 if (isset($prop['buttonScaleHow'])) {
10125 switch ($prop['buttonScaleHow']) {
10126 case 'scaleHow.proportional': {
10127 $opt['mk']['if']['s'] = 'P';
10128 break;
10129 }
10130 case 'scaleHow.anamorphic': {
10131 $opt['mk']['if']['s'] = 'A';
10132 break;
10133 }
10134 }
10135 }
10136
10137 if (isset($prop['buttonScaleWhen'])) {
10138 switch ($prop['buttonScaleWhen']) {
10139 case 'scaleWhen.always': {
10140 $opt['mk']['if']['sw'] = 'A';
10141 break;
10142 }
10143 case 'scaleWhen.never': {
10144 $opt['mk']['if']['sw'] = 'N';
10145 break;
10146 }
10147 case 'scaleWhen.tooBig': {
10148 $opt['mk']['if']['sw'] = 'B';
10149 break;
10150 }
10151 case 'scaleWhen.tooSmall': {
10152 $opt['mk']['if']['sw'] = 'S';
10153 break;
10154 }
10155 }
10156 }
10157
10158 if (isset($prop['buttonPosition'])) {
10159 switch ($prop['buttonPosition']) {
10160 case 0:
10161 case 'position.textOnly': {
10162 $opt['mk']['tp'] = 0;
10163 break;
10164 }
10165 case 1:
10166 case 'position.iconOnly': {
10167 $opt['mk']['tp'] = 1;
10168 break;
10169 }
10170 case 2:
10171 case 'position.iconTextV': {
10172 $opt['mk']['tp'] = 2;
10173 break;
10174 }
10175 case 3:
10176 case 'position.textIconV': {
10177 $opt['mk']['tp'] = 3;
10178 break;
10179 }
10180 case 4:
10181 case 'position.iconTextH': {
10182 $opt['mk']['tp'] = 4;
10183 break;
10184 }
10185 case 5:
10186 case 'position.textIconH': {
10187 $opt['mk']['tp'] = 5;
10188 break;
10189 }
10190 case 6:
10191 case 'position.overlay': {
10192 $opt['mk']['tp'] = 6;
10193 break;
10194 }
10195 }
10196 }
10197
10198 if (isset($prop['fillColor'])) {
10199 if (is_array($prop['fillColor'])) {
10200 $opt['mk']['bg'] = $prop['fillColor'];
10201 } else {
10202 $opt['mk']['bg'] = $this->convertHTMLColorToDec($prop['fillColor']);
10203 }
10204 }
10205
10206 if (isset($prop['strokeColor'])) {
10207 if (is_array($prop['strokeColor'])) {
10208 $opt['mk']['bc'] = $prop['strokeColor'];
10209 } else {
10210 $opt['mk']['bc'] = $this->convertHTMLColorToDec($prop['strokeColor']);
10211 }
10212 }
10213
10214 if (isset($prop['rotation'])) {
10215 $opt['mk']['r'] = $prop['rotation'];
10216 }
10217
10218 if (isset($prop['charLimit'])) {
10219 $opt['maxlen'] = intval($prop['charLimit']);
10220 }
10221 if (!isset($ff)) {
10222 $ff = 0;
10223 }
10224
10225 if (isset($prop['readonly']) AND ($prop['readonly'] == 'true')) {
10226 $ff += 1 << 0;
10227 }
10228
10229 if (isset($prop['required']) AND ($prop['required'] == 'true')) {
10230 $ff += 1 << 1;
10231 }
10232
10233 if (isset($prop['multiline']) AND ($prop['multiline'] == 'true')) {
10234 $ff += 1 << 12;
10235 }
10236
10237 if (isset($prop['password']) AND ($prop['password'] == 'true')) {
10238 $ff += 1 << 13;
10239 }
10240
10241 if (isset($prop['NoToggleToOff']) AND ($prop['NoToggleToOff'] == 'true')) {
10242 $ff += 1 << 14;
10243 }
10244
10245 if (isset($prop['Radio']) AND ($prop['Radio'] == 'true')) {
10246 $ff += 1 << 15;
10247 }
10248
10249 if (isset($prop['Pushbutton']) AND ($prop['Pushbutton'] == 'true')) {
10250 $ff += 1 << 16;
10251 }
10252
10253 if (isset($prop['Combo']) AND ($prop['Combo'] == 'true')) {
10254 $ff += 1 << 17;
10255 }
10256
10257 if (isset($prop['editable']) AND ($prop['editable'] == 'true')) {
10258 $ff += 1 << 18;
10259 }
10260
10261 if (isset($prop['Sort']) AND ($prop['Sort'] == 'true')) {
10262 $ff += 1 << 19;
10263 }
10264
10265 if (isset($prop['fileSelect']) AND ($prop['fileSelect'] == 'true')) {
10266 $ff += 1 << 20;
10267 }
10268
10269 if (isset($prop['multipleSelection']) AND ($prop['multipleSelection'] == 'true')) {
10270 $ff += 1 << 21;
10271 }
10272
10273 if (isset($prop['doNotSpellCheck']) AND ($prop['doNotSpellCheck'] == 'true')) {
10274 $ff += 1 << 22;
10275 }
10276
10277 if (isset($prop['doNotScroll']) AND ($prop['doNotScroll'] == 'true')) {
10278 $ff += 1 << 23;
10279 }
10280
10281 if (isset($prop['comb']) AND ($prop['comb'] == 'true')) {
10282 $ff += 1 << 24;
10283 }
10284
10285 if (isset($prop['radiosInUnison']) AND ($prop['radiosInUnison'] == 'true')) {
10286 $ff += 1 << 25;
10287 }
10288
10289 if (isset($prop['richText']) AND ($prop['richText'] == 'true')) {
10290 $ff += 1 << 25;
10291 }
10292
10293 if (isset($prop['commitOnSelChange']) AND ($prop['commitOnSelChange'] == 'true')) {
10294 $ff += 1 << 26;
10295 }
10296 $opt['ff'] = $ff;
10297
10298 if (isset($prop['defaultValue'])) {
10299 $opt['dv'] = $prop['defaultValue'];
10300 }
10301 $f = 4;
10302
10303 if (isset($prop['readonly']) AND ($prop['readonly'] == 'true')) {
10304 $f += 1 << 6;
10305 }
10306
10307 if (isset($prop['display'])) {
10308 if ($prop['display'] == 'display.visible') {
10309
10310 } elseif ($prop['display'] == 'display.hidden') {
10311 $f += 1 << 1;
10312 } elseif ($prop['display'] == 'display.noPrint') {
10313 $f -= 1 << 2;
10314 } elseif ($prop['display'] == 'display.noView') {
10315 $f += 1 << 5;
10316 }
10317 }
10318 $opt['f'] = $f;
10319
10320 if (isset($prop['currentValueIndices']) AND is_array($prop['currentValueIndices'])) {
10321 $opt['i'] = $prop['currentValueIndices'];
10322 }
10323
10324 if (isset($prop['value'])) {
10325 if (is_array($prop['value'])) {
10326 $opt['opt'] = array();
10327 foreach ($prop['value'] AS $key => $optval) {
10328
10329 if (isset($prop['exportValues'][$key])) {
10330 $opt['opt'][$key] = array($prop['exportValues'][$key], $prop['value'][$key]);
10331 } else {
10332 $opt['opt'][$key] = $prop['value'][$key];
10333 }
10334 }
10335 } else {
10336 $opt['v'] = $prop['value'];
10337 }
10338 }
10339
10340 if (isset($prop['richValue'])) {
10341 $opt['rv'] = $prop['richValue'];
10342 }
10343
10344 if (isset($prop['submitName'])) {
10345 $opt['tm'] = $prop['submitName'];
10346 }
10347
10348 if (isset($prop['name'])) {
10349 $opt['t'] = $prop['name'];
10350 }
10351
10352 if (isset($prop['userName'])) {
10353 $opt['tu'] = $prop['userName'];
10354 }
10355
10356 if (isset($prop['highlight'])) {
10357 switch ($prop['highlight']) {
10358 case 'none':
10359 case 'highlight.n': {
10360 $opt['h'] = 'N';
10361 break;
10362 }
10363 case 'invert':
10364 case 'highlight.i': {
10365 $opt['h'] = 'i';
10366 break;
10367 }
10368 case 'push':
10369 case 'highlight.p': {
10370 $opt['h'] = 'P';
10371 break;
10372 }
10373 case 'outline':
10374 case 'highlight.o': {
10375 $opt['h'] = 'O';
10376 break;
10377 }
10378 }
10379 }
10380
10381
10382
10383
10384
10385
10386 return $opt;
10387 }
10388
10389
10390
10391
10392
10393
10394
10395
10396 public function setFormDefaultProp($prop=array()) {
10397 $this->default_form_prop = $prop;
10398 }
10399
10400
10401
10402
10403
10404
10405
10406
10407 public function getFormDefaultProp() {
10408 return $this->default_form_prop;
10409 }
10410
10411
10412
10413
10414
10415
10416
10417
10418
10419
10420
10421
10422
10423
10424
10425 public function TextField($name, $w, $h, $prop=array(), $opt=array(), $x='', $y='', $js=false) {
10426 if ($x === '') {
10427 $x = $this->x;
10428 }
10429 if ($y === '') {
10430 $y = $this->y;
10431 }
10432 if ($js) {
10433 $this->_addfield('text', $name, $x, $y, $w, $h, $prop);
10434 return;
10435 }
10436
10437 $prop = array_merge($this->getFormDefaultProp(), $prop);
10438
10439 $popt = $this->getAnnotOptFromJSProp($prop);
10440
10441 $font = $this->FontFamily;
10442 $fontkey = array_search($font, $this->fontkeys);
10443 if (!in_array($fontkey, $this->annotation_fonts)) {
10444 $this->annotation_fonts[$font] = $fontkey;
10445 }
10446 $fontstyle = sprintf('/F%d %.2F Tf %s', ($fontkey + 1), $this->FontSizePt, $this->TextColor);
10447 $popt['da'] = $fontstyle;
10448 $popt['ap'] = array();
10449 $popt['ap']['n'] = 'q BT '.$fontstyle.' ET Q';
10450
10451 $opt = array_merge($popt, $opt);
10452
10453 unset($opt['bs']);
10454
10455 $opt['Subtype'] = 'Widget';
10456 $opt['ft'] = 'Tx';
10457 $opt['t'] = $name;
10458
10459
10460
10461
10462
10463
10464
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493 $this->Annotation($x, $y, $w, $h, $name, $opt, 0);
10494 if ($this->rtl) {
10495 $this->x -= $w;
10496 } else {
10497 $this->x += $w;
10498 }
10499 }
10500
10501
10502
10503
10504
10505
10506
10507
10508
10509
10510
10511
10512
10513
10514
10515
10516 public function RadioButton($name, $w, $prop=array(), $opt=array(), $onvalue='On', $checked=false, $x='', $y='', $js=false) {
10517 if ($x === '') {
10518 $x = $this->x;
10519 }
10520 if ($y === '') {
10521 $y = $this->y;
10522 }
10523 if ($js) {
10524 $this->_addfield('radiobutton', $name, $x, $y, $w, $w, $prop);
10525 return;
10526 }
10527 if ($this->empty_string($onvalue)) {
10528 $onvalue = 'On';
10529 }
10530 if ($checked) {
10531 $defval = $onvalue;
10532 } else {
10533 $defval = 'Off';
10534 }
10535
10536 if (!isset($this->radiobutton_groups[$this->page])) {
10537 $this->radiobutton_groups[$this->page] = array();
10538 }
10539 if (!isset($this->radiobutton_groups[$this->page][$name])) {
10540 $this->radiobutton_groups[$this->page][$name] = array();
10541 ++$this->annot_obj_id;
10542 $this->radio_groups[] = $this->annot_obj_id;
10543 }
10544
10545 $this->radiobutton_groups[$this->page][$name][] = array('kid' => ($this->annot_obj_id + 1), 'def' => $defval);
10546
10547 $prop = array_merge($this->getFormDefaultProp(), $prop);
10548 $prop['NoToggleToOff'] = 'true';
10549 $prop['Radio'] = 'true';
10550 $prop['borderStyle'] = 'inset';
10551
10552 $popt = $this->getAnnotOptFromJSProp($prop);
10553
10554 $font = 'zapfdingbats';
10555 $this->AddFont($font);
10556 $fontkey = array_search($font, $this->fontkeys);
10557 if (!in_array($fontkey, $this->annotation_fonts)) {
10558 $this->annotation_fonts[$font] = $fontkey;
10559 }
10560 $fontstyle = sprintf('/F%d %.2F Tf %s', ($fontkey + 1), $this->FontSizePt, $this->TextColor);
10561 $popt['da'] = $fontstyle;
10562 $popt['ap'] = array();
10563 $popt['ap']['n'] = array();
10564 $popt['ap']['n'][$onvalue] = 'q BT '.$fontstyle.' 0 0 Td (8) Tj ET Q';
10565 $popt['ap']['n']['Off'] = 'q BT '.$fontstyle.' 0 0 Td (8) Tj ET Q';
10566 if (!isset($popt['mk'])) {
10567 $popt['mk'] = array();
10568 }
10569 $popt['mk']['ca'] = '(l)';
10570
10571 $opt = array_merge($popt, $opt);
10572
10573 $opt['Subtype'] = 'Widget';
10574 $opt['ft'] = 'Btn';
10575 if ($checked) {
10576 $opt['v'] = array('/'.$onvalue);
10577 $opt['as'] = $onvalue;
10578 } else {
10579 $opt['as'] = 'Off';
10580 }
10581 $this->Annotation($x, $y, $w, $w, $name, $opt, 0);
10582 if ($this->rtl) {
10583 $this->x -= $w;
10584 } else {
10585 $this->x += $w;
10586 }
10587 }
10588
10589
10590
10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604 public function ListBox($name, $w, $h, $values, $prop=array(), $opt=array(), $x='', $y='', $js=false) {
10605 if ($x === '') {
10606 $x = $this->x;
10607 }
10608 if ($y === '') {
10609 $y = $this->y;
10610 }
10611 if ($js) {
10612 $this->_addfield('listbox', $name, $x, $y, $w, $h, $prop);
10613 $s = '';
10614 foreach ($values as $value) {
10615 $s .= "'".addslashes($value)."',";
10616 }
10617 $this->javascript .= 'f'.$name.'.setItems(['.substr($s, 0, -1)."]);\n";
10618 return;
10619 }
10620
10621 $prop = array_merge($this->getFormDefaultProp(), $prop);
10622
10623 $popt = $this->getAnnotOptFromJSProp($prop);
10624
10625 $font = $this->FontFamily;
10626 $fontkey = array_search($font, $this->fontkeys);
10627 if (!in_array($fontkey, $this->annotation_fonts)) {
10628 $this->annotation_fonts[$font] = $fontkey;
10629 }
10630 $fontstyle = sprintf('/F%d %.2F Tf %s', ($fontkey + 1), $this->FontSizePt, $this->TextColor);
10631 $popt['da'] = $fontstyle;
10632 $popt['ap'] = array();
10633 $popt['ap']['n'] = 'q BT '.$fontstyle.' ET Q';
10634
10635 $opt = array_merge($popt, $opt);
10636
10637 $opt['Subtype'] = 'Widget';
10638 $opt['ft'] = 'Ch';
10639 $opt['t'] = $name;
10640 $opt['opt'] = $values;
10641 $this->Annotation($x, $y, $w, $h, $name, $opt, 0);
10642 if ($this->rtl) {
10643 $this->x -= $w;
10644 } else {
10645 $this->x += $w;
10646 }
10647 }
10648
10649
10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664 public function ComboBox($name, $w, $h, $values, $prop=array(), $opt=array(), $x='', $y='', $js=false) {
10665 if ($x === '') {
10666 $x = $this->x;
10667 }
10668 if ($y === '') {
10669 $y = $this->y;
10670 }
10671 if ($js) {
10672 $this->_addfield('combobox', $name, $x, $y, $w, $h, $prop);
10673 $s = '';
10674 foreach ($values as $value) {
10675 $s .= "'".addslashes($value)."',";
10676 }
10677 $this->javascript .= 'f'.$name.'.setItems(['.substr($s, 0, -1)."]);\n";
10678 return;
10679 }
10680
10681 $prop = array_merge($this->getFormDefaultProp(), $prop);
10682 $prop['Combo'] = true;
10683
10684 $popt = $this->getAnnotOptFromJSProp($prop);
10685
10686 $font = $this->FontFamily;
10687 $fontkey = array_search($font, $this->fontkeys);
10688 if (!in_array($fontkey, $this->annotation_fonts)) {
10689 $this->annotation_fonts[$font] = $fontkey;
10690 }
10691 $fontstyle = sprintf('/F%d %.2F Tf %s', ($fontkey + 1), $this->FontSizePt, $this->TextColor);
10692 $popt['da'] = $fontstyle;
10693 $popt['ap'] = array();
10694 $popt['ap']['n'] = 'q BT '.$fontstyle.' ET Q';
10695
10696 $opt = array_merge($popt, $opt);
10697
10698 $opt['Subtype'] = 'Widget';
10699 $opt['ft'] = 'Ch';
10700 $opt['t'] = $name;
10701 $opt['opt'] = $values;
10702 $this->Annotation($x, $y, $w, $h, $name, $opt, 0);
10703 if ($this->rtl) {
10704 $this->x -= $w;
10705 } else {
10706 $this->x += $w;
10707 }
10708 }
10709
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720
10721
10722
10723
10724
10725 public function CheckBox($name, $w, $checked=false, $prop=array(), $opt=array(), $onvalue='Yes', $x='', $y='', $js=false) {
10726 if ($x === '') {
10727 $x = $this->x;
10728 }
10729 if ($y === '') {
10730 $y = $this->y;
10731 }
10732 if ($js) {
10733 $this->_addfield('checkbox', $name, $x, $y, $w, $w, $prop);
10734 return;
10735 }
10736 if (!isset($prop['value'])) {
10737 $prop['value'] = array('Yes');
10738 }
10739
10740 $prop = array_merge($this->getFormDefaultProp(), $prop);
10741 $prop['borderStyle'] = 'inset';
10742
10743 $popt = $this->getAnnotOptFromJSProp($prop);
10744
10745 $font = 'zapfdingbats';
10746 $this->AddFont($font);
10747 $fontkey = array_search($font, $this->fontkeys);
10748 if (!in_array($fontkey, $this->annotation_fonts)) {
10749 $this->annotation_fonts[$font] = $fontkey;
10750 }
10751 $fontstyle = sprintf('/F%d %.2F Tf %s', ($fontkey + 1), $this->FontSizePt, $this->TextColor);
10752 $popt['da'] = $fontstyle;
10753 $popt['ap'] = array();
10754 $popt['ap']['n'] = array();
10755 $popt['ap']['n']['Yes'] = 'q BT '.$fontstyle.' 0 0 Td (8) Tj ET Q';
10756 $popt['ap']['n']['Off'] = 'q BT '.$fontstyle.' 0 0 Td (8) Tj ET Q';
10757
10758 $opt = array_merge($popt, $opt);
10759
10760 $opt['Subtype'] = 'Widget';
10761 $opt['ft'] = 'Btn';
10762 $opt['t'] = $name;
10763 $opt['opt'] = array($onvalue);
10764 if ($checked) {
10765 $opt['v'] = array('/0');
10766 $opt['as'] = 'Yes';
10767 } else {
10768 $opt['v'] = array('/Off');
10769 $opt['as'] = 'Off';
10770 }
10771 $this->Annotation($x, $y, $w, $w, $name, $opt, 0);
10772 if ($this->rtl) {
10773 $this->x -= $w;
10774 } else {
10775 $this->x += $w;
10776 }
10777 }
10778
10779
10780
10781
10782
10783
10784
10785
10786
10787
10788
10789
10790
10791
10792
10793
10794
10795 public function Button($name, $w, $h, $caption, $action, $prop=array(), $opt=array(), $x='', $y='', $js=false) {
10796 if ($x === '') {
10797 $x = $this->x;
10798 }
10799 if ($y === '') {
10800 $y = $this->y;
10801 }
10802 if ($js) {
10803 $this->_addfield('button', $name, $this->x, $this->y, $w, $h, $prop);
10804 $this->javascript .= 'f'.$name.".buttonSetCaption('".addslashes($caption)."');\n";
10805 $this->javascript .= 'f'.$name.".setAction('MouseUp','".addslashes($action)."');\n";
10806 $this->javascript .= 'f'.$name.".highlight='push';\n";
10807 $this->javascript .= 'f'.$name.".print=false;\n";
10808 return;
10809 }
10810
10811 $prop = array_merge($this->getFormDefaultProp(), $prop);
10812 $prop['Pushbutton'] = 'true';
10813 $prop['highlight'] = 'push';
10814 $prop['display'] = 'display.noPrint';
10815
10816 $popt = $this->getAnnotOptFromJSProp($prop);
10817
10818 if (!isset($popt['mk'])) {
10819 $popt['mk'] = array();
10820 }
10821 $popt['mk']['ca'] = $this->_textstring($caption);
10822 $popt['mk']['rc'] = $this->_textstring($caption);
10823 $popt['mk']['ac'] = $this->_textstring($caption);
10824 $font = $this->FontFamily;
10825 $fontkey = array_search($font, $this->fontkeys);
10826 if (!in_array($fontkey, $this->annotation_fonts)) {
10827 $this->annotation_fonts[$font] = $fontkey;
10828 }
10829 $fontstyle = sprintf('/F%d %.2F Tf %s', ($fontkey + 1), $this->FontSizePt, $this->TextColor);
10830 $popt['da'] = $fontstyle;
10831 $popt['ap'] = array();
10832 $popt['ap']['n'] = 'q BT '.$fontstyle.' ET Q';
10833
10834 $opt = array_merge($popt, $opt);
10835
10836 $opt['Subtype'] = 'Widget';
10837 $opt['ft'] = 'Btn';
10838 $opt['t'] = $caption;
10839 $opt['v'] = $name;
10840 if (!empty($action)) {
10841 if (is_array($action)) {
10842
10843 $opt['aa'] = '/D <<';
10844 $bmode = array('SubmitForm', 'ResetForm', 'ImportData');
10845 foreach ($action AS $key => $val) {
10846 if (($key == 'S') AND in_array($val, $bmode)) {
10847 $opt['aa'] .= ' /S /'.$val;
10848 } elseif (($key == 'F') AND (!empty($val))) {
10849 $opt['aa'] .= ' /F '.$this->_datastring($val);
10850 } elseif (($key == 'Fields') AND is_array($val) AND !empty($val)) {
10851 $opt['aa'] .= ' /Fields [';
10852 foreach ($val AS $field) {
10853 $opt['aa'] .= ' '.$this->_textstring($field);
10854 }
10855 $opt['aa'] .= ']';
10856 } elseif (($key == 'Flags')) {
10857 $ff = 0;
10858 if (is_array($val)) {
10859 foreach ($val AS $flag) {
10860 switch ($flag) {
10861 case 'Include/Exclude': {
10862 $ff += 1 << 0;
10863 break;
10864 }
10865 case 'IncludeNoValueFields': {
10866 $ff += 1 << 1;
10867 break;
10868 }
10869 case 'ExportFormat': {
10870 $ff += 1 << 2;
10871 break;
10872 }
10873 case 'GetMethod': {
10874 $ff += 1 << 3;
10875 break;
10876 }
10877 case 'SubmitCoordinates': {
10878 $ff += 1 << 4;
10879 break;
10880 }
10881 case 'XFDF': {
10882 $ff += 1 << 5;
10883 break;
10884 }
10885 case 'IncludeAppendSaves': {
10886 $ff += 1 << 6;
10887 break;
10888 }
10889 case 'IncludeAnnotations': {
10890 $ff += 1 << 7;
10891 break;
10892 }
10893 case 'SubmitPDF': {
10894 $ff += 1 << 8;
10895 break;
10896 }
10897 case 'CanonicalFormat': {
10898 $ff += 1 << 9;
10899 break;
10900 }
10901 case 'ExclNonUserAnnots': {
10902 $ff += 1 << 10;
10903 break;
10904 }
10905 case 'ExclFKey': {
10906 $ff += 1 << 11;
10907 break;
10908 }
10909 case 'EmbedForm': {
10910 $ff += 1 << 13;
10911 break;
10912 }
10913 }
10914 }
10915 } else {
10916 $ff = intval($val);
10917 }
10918 $opt['aa'] .= ' /Flags '.$ff;
10919 }
10920 }
10921 $opt['aa'] .= ' >>';
10922 } else {
10923
10924 $js_obj_id = $this->addJavascriptObject($action);
10925 $opt['aa'] = '/D '.$js_obj_id.' 0 R';
10926 }
10927 }
10928 $this->Annotation($x, $y, $w, $h, $name, $opt, 0);
10929 if ($this->rtl) {
10930 $this->x -= $w;
10931 } else {
10932 $this->x += $w;
10933 }
10934 }
10935
10936
10937
10938
10939
10940
10941
10942
10943
10944
10945 protected function _putsignature() {
10946 if ((!$this->sign) OR (!isset($this->signature_data['cert_type']))) {
10947 return;
10948 }
10949 $this->_out('/Type /Sig');
10950 $this->_out('/Filter /Adobe.PPKLite');
10951 $this->_out('/SubFilter /adbe.pkcs7.detached');
10952 $this->_out($this->byterange_string);
10953 $this->_out('/Contents<>'.str_repeat(' ', $this->signature_max_lenght));
10954 $this->_out('/Reference');
10955 $this->_out('[');
10956 $this->_out('<<');
10957 $this->_out('/Type /SigRef');
10958 if ($this->signature_data['cert_type'] > 0) {
10959 $this->_out('/TransformMethod /DocMDP');
10960 $this->_out('/TransformParams');
10961 $this->_out('<<');
10962 $this->_out('/Type /TransformParams');
10963 $this->_out('/V /1.2');
10964 $this->_out('/P '.$this->signature_data['cert_type'].'');
10965 } else {
10966 $this->_out('/TransformMethod /UR3');
10967 $this->_out('/TransformParams');
10968 $this->_out('<<');
10969 $this->_out('/Type /TransformParams');
10970 $this->_out('/V /2.2');
10971 if (!$this->empty_string($this->ur_document)) {
10972 $this->_out('/Document['.$this->ur_document.']');
10973 }
10974 if (!$this->empty_string($this->ur_annots)) {
10975 $this->_out('/Annots['.$this->ur_annots.']');
10976 }
10977 if (!$this->empty_string($this->ur_form)) {
10978 $this->_out('/Form['.$this->ur_form.']');
10979 }
10980 if (!$this->empty_string($this->ur_signature)) {
10981 $this->_out('/Signature['.$this->ur_signature.']');
10982 }
10983 }
10984 $this->_out('>>');
10985 $this->_out('>>');
10986 $this->_out(']');
10987 if (isset($this->signature_data['info']['Name']) AND !$this->empty_string($this->signature_data['info']['Name'])) {
10988 $this->_out('/Name '.$this->_textstring($this->signature_data['info']['Name']).'');
10989 }
10990 if (isset($this->signature_data['info']['Location']) AND !$this->empty_string($this->signature_data['info']['Location'])) {
10991 $this->_out('/Location '.$this->_textstring($this->signature_data['info']['Location']).'');
10992 }
10993 if (isset($this->signature_data['info']['Reason']) AND !$this->empty_string($this->signature_data['info']['Reason'])) {
10994 $this->_out('/Reason '.$this->_textstring($this->signature_data['info']['Reason']).'');
10995 }
10996 if (isset($this->signature_data['info']['ContactInfo']) AND !$this->empty_string($this->signature_data['info']['ContactInfo'])) {
10997 $this->_out('/ContactInfo '.$this->_textstring($this->signature_data['info']['ContactInfo']).'');
10998 }
10999 $this->_out('/M '.$this->_datestring());
11000 }
11001
11002
11003
11004
11005
11006
11007
11008
11009
11010
11011
11012
11013
11014
11015
11016 public function setUserRights(
11017 $enable=true,
11018 $document='/FullSave',
11019 $annots='/Create/Delete/Modify/Copy/Import/Export',
11020 $form='/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate',
11021 $signature='/Modify') {
11022 $this->ur = $enable;
11023 $this->ur_document = $document;
11024 $this->ur_annots = $annots;
11025 $this->ur_form = $form;
11026 $this->ur_signature = $signature;
11027 if (!$this->sign) {
11028
11029 $this->setSignature('', '', '', '', 0, array());
11030 }
11031 }
11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
11045
11046 public function setSignature($signing_cert='', $private_key='', $private_key_password='', $extracerts='', $cert_type=2, $info=array()) {
11047
11048
11049
11050 $this->sign = true;
11051 $this->signature_data = array();
11052 if (strlen($signing_cert) == 0) {
11053 $signing_cert = 'file://'.dirname(__FILE__).'/tcpdf.crt';
11054 $private_key_password = 'tcpdfdemo';
11055 }
11056 if (strlen($private_key) == 0) {
11057 $private_key = $signing_cert;
11058 }
11059 $this->signature_data['signcert'] = $signing_cert;
11060 $this->signature_data['privkey'] = $private_key;
11061 $this->signature_data['password'] = $private_key_password;
11062 $this->signature_data['extracerts'] = $extracerts;
11063 $this->signature_data['cert_type'] = $cert_type;
11064 $this->signature_data['info'] = $info;
11065 }
11066
11067
11068
11069
11070
11071
11072
11073
11074 public function startPageGroup($page='') {
11075 if (empty($page)) {
11076 $page = $this->page + 1;
11077 }
11078 $this->newpagegroup[$page] = true;
11079 }
11080
11089 public function AliasNbPages($alias='{nb}') {
11090 $this->AliasNbPages = $alias;
11091 }
11092
11101 public function getAliasNbPages() {
11102 if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
11103 return '{'.$this->AliasNbPages.'}';
11104 }
11105 return $this->AliasNbPages;
11106 }
11107
11116 public function AliasNumPage($alias='{pnb}') {
11117
11118 $this->AliasNumPage = $alias;
11119 }
11120
11129 public function getAliasNumPage() {
11130 if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
11131 return '{'.$this->AliasNumPage.'}';
11132 }
11133 return $this->AliasNumPage;
11134 }
11135
11136
11137
11138
11139
11140
11141
11142 public function getGroupPageNo() {
11143 return $this->pagegroups[$this->currpagegroup];
11144 }
11145
11152 public function getGroupPageNoFormatted() {
11153 return $this->formatPageNumber($this->getGroupPageNo());
11154 }
11155
11156
11157
11158
11159
11160
11161
11162
11163
11164 public function getPageGroupAlias() {
11165 if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
11166 return '{'.$this->currpagegroup.'}';
11167 }
11168 return $this->currpagegroup;
11169 }
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179 public function getPageNumGroupAlias() {
11180 if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
11181 return '{'.str_replace('{nb', '{pnb', $this->currpagegroup).'}';
11182 }
11183 return str_replace('{nb', '{pnb', $this->currpagegroup);
11184 }
11185
11193 protected function formatPageNumber($num) {
11194 return number_format((float)$num, 0, '', '.');
11195 }
11196
11205 protected function formatTOCPageNumber($num) {
11206 return number_format((float)$num, 0, '', '.');
11207 }
11208
11215 public function PageNoFormatted() {
11216 return $this->formatPageNumber($this->PageNo());
11217 }
11218
11219
11220
11221
11222
11223
11224 protected function _putocg() {
11225 $this->_newobj();
11226 $this->n_ocg_print = $this->n;
11227 $this->_out('<</Type /OCG /Name '.$this->_textstring('print'));
11228 $this->_out('/Usage <</Print <</PrintState /ON>> /View <</ViewState /OFF>>>>>>');
11229 $this->_out('endobj');
11230 $this->_newobj();
11231 $this->n_ocg_view = $this->n;
11232 $this->_out('<</Type /OCG /Name '.$this->_textstring('view'));
11233 $this->_out('/Usage <</Print <</PrintState /OFF>> /View <</ViewState /ON>>>>>>');
11234 $this->_out('endobj');
11235 }
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245 public function setVisibility($v) {
11246 if ($this->openMarkedContent) {
11247
11248 $this->_out('EMC');
11249 $this->openMarkedContent = false;
11250 }
11251 switch($v) {
11252 case 'print': {
11253 $this->_out('/OC /OC1 BDC');
11254 $this->openMarkedContent = true;
11255 break;
11256 }
11257 case 'screen': {
11258 $this->_out('/OC /OC2 BDC');
11259 $this->openMarkedContent = true;
11260 break;
11261 }
11262 case 'all': {
11263 $this->_out('');
11264 break;
11265 }
11266 default: {
11267 $this->Error('Incorrect visibility: '.$v);
11268 break;
11269 }
11270 }
11271 $this->visibility = $v;
11272 }
11273
11274
11275
11276
11277
11278
11279
11280
11281 protected function addExtGState($parms) {
11282 $n = count($this->extgstates) + 1;
11283 $this->extgstates[$n]['parms'] = $parms;
11284 return $n;
11285 }
11286
11287
11288
11289
11290
11291
11292
11293 protected function setExtGState($gs) {
11294 $this->_out(sprintf('/GS%d gs', $gs));
11295 }
11296
11297
11298
11299
11300
11301
11302
11303 protected function _putextgstates() {
11304 $ne = count($this->extgstates);
11305 for ($i = 1; $i <= $ne; ++$i) {
11306 $this->_newobj();
11307 $this->extgstates[$i]['n'] = $this->n;
11308 $this->_out('<</Type /ExtGState');
11309 foreach ($this->extgstates[$i]['parms'] as $k => $v) {
11310 $this->_out('/'.$k.' '.$v);
11311 }
11312 $this->_out('>>');
11313 $this->_out('endobj');
11314 }
11315 }
11316
11317
11318
11319
11320
11321
11322
11323
11324 public function setAlpha($alpha, $bm='Normal') {
11325 $gs = $this->addExtGState(array('ca' => $alpha, 'CA' => $alpha, 'BM' => '/'.$bm));
11326 $this->setExtGState($gs);
11327 }
11328
11329
11330
11331
11332
11333
11334
11335 public function setJPEGQuality($quality) {
11336 if (($quality < 1) OR ($quality > 100)) {
11337 $quality = 75;
11338 }
11339 $this->jpeg_quality = intval($quality);
11340 }
11341
11342
11343
11344
11345
11346
11347
11348 public function setDefaultTableColumns($cols=4) {
11349 $this->default_table_columns = intval($cols);
11350 }
11351
11352
11353
11354
11355
11356
11357
11358 public function setCellHeightRatio($h) {
11359 $this->cell_height_ratio = $h;
11360 }
11361
11362
11363
11364
11365
11366
11367 public function getCellHeightRatio() {
11368 return $this->cell_height_ratio;
11369 }
11370
11371
11372
11373
11374
11375
11376
11377 public function setPDFVersion($version='1.7') {
11378 $this->PDFVersion = $version;
11379 }
11380
11381
11382
11383
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407 public function setViewerPreferences($preferences) {
11408 $this->viewer_preferences = $preferences;
11409 }
11410
11424 public function LinearGradient($x, $y, $w, $h, $col1=array(), $col2=array(), $coords=array(0,0,1,0)) {
11425 $this->Clip($x, $y, $w, $h);
11426 $this->Gradient(2, $col1, $col2, $coords);
11427 }
11428
11442 public function RadialGradient($x, $y, $w, $h, $col1=array(), $col2=array(), $coords=array(0.5,0.5,0.5,0.5,1)) {
11443 $this->Clip($x, $y, $w, $h);
11444 $this->Gradient(3, $col1, $col2, $coords);
11445 }
11446
11464 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) {
11465 $this->Clip($x, $y, $w, $h);
11466 $n = count($this->gradients) + 1;
11467 $this->gradients[$n]['type'] = 6;
11468
11469 if (!isset($coords[0]['f'])) {
11470
11471 if (!isset($col1[1])) {
11472 $col1[1] = $col1[2] = $col1[0];
11473 }
11474 if (!isset($col2[1])) {
11475 $col2[1] = $col2[2] = $col2[0];
11476 }
11477 if (!isset($col3[1])) {
11478 $col3[1] = $col3[2] = $col3[0];
11479 }
11480 if (!isset($col4[1])) {
11481 $col4[1] = $col4[2] = $col4[0];
11482 }
11483 $patch_array[0]['f'] = 0;
11484 $patch_array[0]['points'] = $coords;
11485 $patch_array[0]['colors'][0]['r'] = $col1[0];
11486 $patch_array[0]['colors'][0]['g'] = $col1[1];
11487 $patch_array[0]['colors'][0]['b'] = $col1[2];
11488 $patch_array[0]['colors'][1]['r'] = $col2[0];
11489 $patch_array[0]['colors'][1]['g'] = $col2[1];
11490 $patch_array[0]['colors'][1]['b'] = $col2[2];
11491 $patch_array[0]['colors'][2]['r'] = $col3[0];
11492 $patch_array[0]['colors'][2]['g'] = $col3[1];
11493 $patch_array[0]['colors'][2]['b'] = $col3[2];
11494 $patch_array[0]['colors'][3]['r'] = $col4[0];
11495 $patch_array[0]['colors'][3]['g'] = $col4[1];
11496 $patch_array[0]['colors'][3]['b'] = $col4[2];
11497 } else {
11498
11499 $patch_array = $coords;
11500 }
11501 $bpcd = 65535;
11502
11503 $this->gradients[$n]['stream'] = '';
11504 $count_patch = count($patch_array);
11505 for ($i=0; $i < $count_patch; ++$i) {
11506 $this->gradients[$n]['stream'] .= chr($patch_array[$i]['f']);
11507 $count_points = count($patch_array[$i]['points']);
11508 for ($j=0; $j < $count_points; ++$j) {
11509
11510 $patch_array[$i]['points'][$j] = (($patch_array[$i]['points'][$j] - $coords_min) / ($coords_max - $coords_min)) * $bpcd;
11511 if ($patch_array[$i]['points'][$j] < 0) {
11512 $patch_array[$i]['points'][$j] = 0;
11513 }
11514 if ($patch_array[$i]['points'][$j] > $bpcd) {
11515 $patch_array[$i]['points'][$j] = $bpcd;
11516 }
11517 $this->gradients[$n]['stream'] .= chr(floor($patch_array[$i]['points'][$j] / 256));
11518 $this->gradients[$n]['stream'] .= chr(floor($patch_array[$i]['points'][$j] % 256));
11519 }
11520 $count_cols = count($patch_array[$i]['colors']);
11521 for ($j=0; $j < $count_cols; ++$j) {
11522
11523 $this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['r']);
11524 $this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['g']);
11525 $this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['b']);
11526 }
11527 }
11528
11529 $this->_out('/Sh'.$n.' sh');
11530
11531 $this->_out('Q');
11532 }
11533
11544 protected function Clip($x, $y, $w, $h) {
11545 if ($this->rtl) {
11546 $x = $this->w - $x - $w;
11547 }
11548
11549 $s = 'q';
11550
11551 $s .= sprintf(' %.2F %.2F %.2F %.2F re W n', $x*$this->k, ($this->h-$y)*$this->k, $w*$this->k, -$h*$this->k);
11552
11553 $s .= sprintf(' %.3F 0 0 %.3F %.3F %.3F cm', $w*$this->k, $h*$this->k, $x*$this->k, ($this->h-($y+$h))*$this->k);
11554 $this->_out($s);
11555 }
11556
11567 protected function Gradient($type, $col1, $col2, $coords) {
11568 $n = count($this->gradients) + 1;
11569 $this->gradients[$n]['type'] = $type;
11570 if (!isset($col1[1])) {
11571 $col1[1]=$col1[2]=$col1[0];
11572 }
11573 $this->gradients[$n]['col1'] = sprintf('%.3F %.3F %.3F', ($col1[0]/255), ($col1[1]/255), ($col1[2]/255));
11574 if (!isset($col2[1])) {
11575 $col2[1] = $col2[2] = $col2[0];
11576 }
11577 $this->gradients[$n]['col2'] = sprintf('%.3F %.3F %.3F', ($col2[0]/255), ($col2[1]/255), ($col2[2]/255));
11578 $this->gradients[$n]['coords'] = $coords;
11579
11580 $this->_out('/Sh'.$n.' sh');
11581
11582 $this->_out('Q');
11583 }
11584
11591 function _putshaders() {
11592 foreach ($this->gradients as $id => $grad) {
11593 if (($grad['type'] == 2) OR ($grad['type'] == 3)) {
11594 $this->_newobj();
11595 $this->_out('<<');
11596 $this->_out('/FunctionType 2');
11597 $this->_out('/Domain [0.0 1.0]');
11598 $this->_out('/C0 ['.$grad['col1'].']');
11599 $this->_out('/C1 ['.$grad['col2'].']');
11600 $this->_out('/N 1');
11601 $this->_out('>>');
11602 $this->_out('endobj');
11603 $f1 = $this->n;
11604 }
11605 $this->_newobj();
11606 $this->_out('<<');
11607 $this->_out('/ShadingType '.$grad['type']);
11608 $this->_out('/ColorSpace /DeviceRGB');
11609 if ($grad['type'] == 2) {
11610 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]));
11611 $this->_out('/Function '.$f1.' 0 R');
11612 $this->_out('/Extend [true true] ');
11613 $this->_out('>>');
11614 } elseif ($grad['type'] == 3) {
11615
11616
11617 $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]));
11618 $this->_out('/Function '.$f1.' 0 R');
11619 $this->_out('/Extend [true true] ');
11620 $this->_out('>>');
11621 } elseif ($grad['type'] == 6) {
11622 $this->_out('/BitsPerCoordinate 16');
11623 $this->_out('/BitsPerComponent 8');
11624 $this->_out('/Decode[0 1 0 1 0 1 0 1 0 1]');
11625 $this->_out('/BitsPerFlag 8');
11626 $this->_out('/Length '.strlen($grad['stream']));
11627 $this->_out('>>');
11628 $this->_putstream($grad['stream']);
11629 }
11630 $this->_out('endobj');
11631 $this->gradients[$id]['id'] = $this->n;
11632 }
11633 }
11634
11641 protected function _outarc($x1, $y1, $x2, $y2, $x3, $y3 ) {
11642 $h = $this->h;
11643 $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));
11644 }
11645
11661 public function PieSector($xc, $yc, $r, $a, $b, $style='FD', $cw=true, $o=90) {
11662 if ($this->rtl) {
11663 $xc = $this->w - $xc;
11664 }
11665 if ($cw) {
11666 $d = $b;
11667 $b = $o - $a;
11668 $a = $o - $d;
11669 } else {
11670 $b += $o;
11671 $a += $o;
11672 }
11673 $a = ($a % 360) + 360;
11674 $b = ($b % 360) + 360;
11675 if ($a > $b) {
11676 $b +=360;
11677 }
11678 $b = $b / 360 * 2 * M_PI;
11679 $a = $a / 360 * 2 * M_PI;
11680 $d = $b - $a;
11681 if ($d == 0 ) {
11682 $d = 2 * M_PI;
11683 }
11684 $k = $this->k;
11685 $hp = $this->h;
11686 if ($style=='F') {
11687 $op = 'f';
11688 } elseif ($style=='FD' or $style=='DF') {
11689 $op = 'b';
11690 } else {
11691 $op = 's';
11692 }
11693 if (sin($d/2)) {
11694 $MyArc = 4/3 * (1 - cos($d/2)) / sin($d/2) * $r;
11695 }
11696
11697 $this->_out(sprintf('%.2F %.2F m', ($xc)*$k, ($hp-$yc)*$k));
11698
11699 $this->_out(sprintf('%.2F %.2F l', ($xc+$r*cos($a))*$k, (($hp-($yc-$r*sin($a)))*$k)));
11700
11701 if ($d < (M_PI/2)) {
11702 $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));
11703 } else {
11704 $b = $a + $d/4;
11705 $MyArc = 4/3*(1-cos($d/8))/sin($d/8)*$r;
11706 $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));
11707 $a = $b;
11708 $b = $a + $d/4;
11709 $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));
11710 $a = $b;
11711 $b = $a + $d/4;
11712 $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) );
11713 $a = $b;
11714 $b = $a + $d/4;
11715 $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));
11716 }
11717
11718 $this->_out($op);
11719 }
11720
11739 public function ImageEps($file, $x='', $y='', $w=0, $h=0, $link='', $useBoundingBox=true, $align='', $palign='', $border=0) {
11740 if ($x === '') {
11741 $x = $this->x;
11742 }
11743 if ($y === '') {
11744 $y = $this->y;
11745 }
11746 $k = $this->k;
11747 $data = file_get_contents($file);
11748 if ($data === false) {
11749 $this->Error('EPS file not found: '.$file);
11750 }
11751 $regs = array();
11752
11753 preg_match("/%%Creator:([^\r\n]+)/", $data, $regs); # find Creator
11754 if (count($regs) > 1) {
11755 $version_str = trim($regs[1]); # e.g. "Adobe Illustrator(R) 8.0"
11756 if (strpos($version_str, 'Adobe Illustrator') !== false) {
11757 $versexp = explode(' ', $version_str);
11758 $version = (float)array_pop($versexp);
11759 if ($version >= 9) {
11760 $this->Error('This version of Adobe Illustrator file is not supported: '.$file);
11761 }
11762 }
11763 }
11764
11765 $start = strpos($data, '%!PS-Adobe');
11766 if ($start > 0) {
11767 $data = substr($data, $start);
11768 }
11769
11770 preg_match("/%%BoundingBox:([^\r\n]+)/", $data, $regs);
11771 if (count($regs) > 1) {
11772 list($x1, $y1, $x2, $y2) = explode(' ', trim($regs[1]));
11773 } else {
11774 $this->Error('No BoundingBox found in EPS file: '.$file);
11775 }
11776 $start = strpos($data, '%%EndSetup');
11777 if ($start === false) {
11778 $start = strpos($data, '%%EndProlog');
11779 }
11780 if ($start === false) {
11781 $start = strpos($data, '%%BoundingBox');
11782 }
11783 $data = substr($data, $start);
11784 $end = strpos($data, '%%PageTrailer');
11785 if ($end===false) {
11786 $end = strpos($data, 'showpage');
11787 }
11788 if ($end) {
11789 $data = substr($data, 0, $end);
11790 }
11791 if ($w > 0) {
11792 $scale_x = $w / (($x2 - $x1) / $k);
11793 if ($h > 0) {
11794 $scale_y = $h / (($y2 - $y1) / $k);
11795 } else {
11796 $scale_y = $scale_x;
11797 $h = ($y2 - $y1) / $k * $scale_y;
11798 }
11799 } else {
11800 if ($h > 0) {
11801 $scale_y = $h / (($y2 - $y1) / $k);
11802 $scale_x = $scale_y;
11803 $w = ($x2-$x1) / $k * $scale_x;
11804 } else {
11805 $w = ($x2 - $x1) / $k;
11806 $h = ($y2 - $y1) / $k;
11807 }
11808 }
11809
11810 if ($this->checkPageBreak($h, $y)) {
11811 $y = $this->GetY() + $this->cMargin;
11812 }
11813
11814 $this->img_rb_y = $y + $h;
11815
11816 if ($this->rtl) {
11817 if ($palign == 'L') {
11818 $ximg = $this->lMargin;
11819
11820 $this->img_rb_x = $ximg + $w;
11821 } elseif ($palign == 'C') {
11822 $ximg = ($this->w - $x - $w) / 2;
11823
11824 $this->img_rb_x = $ximg + $w;
11825 } else {
11826 $ximg = $this->w - $x - $w;
11827
11828 $this->img_rb_x = $ximg;
11829 }
11830 } else {
11831 if ($palign == 'R') {
11832 $ximg = $this->w - $this->rMargin - $w;
11833
11834 $this->img_rb_x = $ximg;
11835 } elseif ($palign == 'C') {
11836 $ximg = ($this->w - $x - $w) / 2;
11837
11838 $this->img_rb_x = $ximg + $w;
11839 } else {
11840 $ximg = $x;
11841
11842 $this->img_rb_x = $ximg + $w;
11843 }
11844 }
11845 if ($useBoundingBox) {
11846 $dx = $ximg * $k - $x1;
11847 $dy = $y * $k - $y1;
11848 } else {
11849 $dx = $ximg * $k;
11850 $dy = $y * $k;
11851 }
11852
11853 $this->_out('q'.$this->epsmarker);
11854
11855 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', 1, 0, 0, 1, $dx, $dy + ($this->hPt - (2 * $y * $k) - ($y2 - $y1))));
11856
11857 if (isset($scale_x)) {
11858 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', $scale_x, 0, 0, $scale_y, $x1 * (1 - $scale_x), $y2 * (1 - $scale_y)));
11859 }
11860
11861 preg_match('/[\r\n]+/s', $data, $regs);
11862 $lines = explode($regs[0], $data);
11863 $u=0;
11864 $cnt = count($lines);
11865 for ($i=0; $i < $cnt; ++$i) {
11866 $line = $lines[$i];
11867 if (($line == '') OR ($line{0} == '%')) {
11868 continue;
11869 }
11870 $len = strlen($line);
11871 $chunks = explode(' ', $line);
11872 $cmd = array_pop($chunks);
11873
11874 if (($cmd == 'Xa') OR ($cmd == 'XA')) {
11875 $b = array_pop($chunks);
11876 $g = array_pop($chunks);
11877 $r = array_pop($chunks);
11878 $this->_out(''.$r.' '.$g.' '.$b.' '.($cmd=='Xa'?'rg':'RG'));
11879 continue;
11880 }
11881 switch ($cmd) {
11882 case 'm':
11883 case 'l':
11884 case 'v':
11885 case 'y':
11886 case 'c':
11887 case 'k':
11888 case 'K':
11889 case 'g':
11890 case 'G':
11891 case 's':
11892 case 'S':
11893 case 'J':
11894 case 'j':
11895 case 'w':
11896 case 'M':
11897 case 'd':
11898 case 'n':
11899 case 'v': {
11900 $this->_out($line);
11901 break;
11902 }
11903 case 'x': {
11904 list($c,$m,$y,$k) = $chunks;
11905 $this->_out(''.$c.' '.$m.' '.$y.' '.$k.' k');
11906 break;
11907 }
11908 case 'X': {
11909 list($c,$m,$y,$k) = $chunks;
11910 $this->_out(''.$c.' '.$m.' '.$y.' '.$k.' K');
11911 break;
11912 }
11913 case 'Y':
11914 case 'N':
11915 case 'V':
11916 case 'L':
11917 case 'C': {
11918 $line{$len-1} = strtolower($cmd);
11919 $this->_out($line);
11920 break;
11921 }
11922 case 'b':
11923 case 'B': {
11924 $this->_out($cmd . '*');
11925 break;
11926 }
11927 case 'f':
11928 case 'F': {
11929 if ($u > 0) {
11930 $isU = false;
11931 $max = min($i+5, $cnt);
11932 for ($j=$i+1; $j < $max; ++$j)
11933 $isU = ($isU OR (($lines[$j] == 'U') OR ($lines[$j] == '*U')));
11934 if ($isU) {
11935 $this->_out('f*');
11936 }
11937 } else {
11938 $this->_out('f*');
11939 }
11940 break;
11941 }
11942 case '*u': {
11943 ++$u;
11944 break;
11945 }
11946 case '*U': {
11947 --$u;
11948 break;
11949 }
11950 }
11951 }
11952
11953 $this->_out($this->epsmarker.'Q');
11954 if (!empty($border)) {
11955 $bx = $x;
11956 $by = $y;
11957 $this->x = $x;
11958 $this->y = $y;
11959 $this->Cell($w, $h, '', $border, 0, '', 0, '', 0);
11960 $this->x = $bx;
11961 $this->y = $by;
11962 }
11963 if ($link) {
11964 $this->Link($ximg, $y, $w, $h, $link, 0);
11965 }
11966
11967 switch($align) {
11968 case 'T':{
11969 $this->y = $y;
11970 $this->x = $this->img_rb_x;
11971 break;
11972 }
11973 case 'M':{
11974 $this->y = $y + round($h/2);
11975 $this->x = $this->img_rb_x;
11976 break;
11977 }
11978 case 'B':{
11979 $this->y = $this->img_rb_y;
11980 $this->x = $this->img_rb_x;
11981 break;
11982 }
11983 case 'N':{
11984 $this->SetY($this->img_rb_y);
11985 break;
11986 }
11987 default:{
11988 break;
11989 }
11990 }
11991 $this->endlinex = $this->img_rb_x;
11992 }
11993
11999 public function setBarcode($bc='') {
12000 $this->barcode = $bc;
12001 }
12002
12009 public function getBarcode() {
12010 return $this->barcode;
12011 }
12012
12028 public function write1DBarcode($code, $type, $x='', $y='', $w='', $h='', $xres=0.4, $style='', $align='') {
12029 if ($this->empty_string($code)) {
12030 return;
12031 }
12032 require_once(dirname(__FILE__).'/barcodes.php');
12033
12034 $gvars = $this->getGraphicVars();
12035
12036 $barcodeobj = new TCPDFBarcode($code, $type);
12037 $arrcode = $barcodeobj->getBarcodeArray();
12038 if ($arrcode === false) {
12039 $this->Error('Error in 1D barcode string');
12040 }
12041
12042 if (!isset($style['position'])) {
12043 if ($this->rtl) {
12044 $style['position'] = 'R';
12045 } else {
12046 $style['position'] = 'L';
12047 }
12048 }
12049 if (!isset($style['padding'])) {
12050 $style['padding'] = 0;
12051 }
12052 if (!isset($style['fgcolor'])) {
12053 $style['fgcolor'] = array(0,0,0);
12054 }
12055 if (!isset($style['bgcolor'])) {
12056 $style['bgcolor'] = false;
12057 }
12058 if (!isset($style['border'])) {
12059 $style['border'] = false;
12060 }
12061 $fontsize = 0;
12062 if (!isset($style['text'])) {
12063 $style['text'] = false;
12064 }
12065 if ($style['text'] AND isset($style['font'])) {
12066 if (isset($style['fontsize'])) {
12067 $fontsize = $style['fontsize'];
12068 }
12069 $this->SetFont($style['font'], '', $fontsize);
12070 }
12071 if (!isset($style['stretchtext'])) {
12072 $style['stretchtext'] = 4;
12073 }
12074
12075 $this->SetDrawColorArray($style['fgcolor']);
12076 $this->SetTextColorArray($style['fgcolor']);
12077 if ($this->empty_string($w) OR ($w <= 0)) {
12078 if ($this->rtl) {
12079 $w = $this->x - $this->lMargin;
12080 } else {
12081 $w = $this->w - $this->rMargin - $this->x;
12082 }
12083 }
12084 if ($this->empty_string($x)) {
12085 $x = $this->GetX();
12086 }
12087 if ($this->rtl) {
12088 $x = $this->w - $x;
12089 }
12090 if ($this->empty_string($y)) {
12091 $y = $this->GetY();
12092 }
12093 if ($this->empty_string($xres)) {
12094 $xres = 0.4;
12095 }
12096 $fbw = ($arrcode['maxw'] * $xres) + (2 * $style['padding']);
12097 $extraspace = ($this->cell_height_ratio * $fontsize / $this->k) + (2 * $style['padding']);
12098 if ($this->empty_string($h) OR ($h <= 0)) {
12099 $h = 10 + $extraspace;
12100 }
12101 if ($this->checkPageBreak($h)) {
12102 $y = $this->y;
12103 }
12104
12105 $barh = $h - $extraspace;
12106 switch ($style['position']) {
12107 case 'L': {
12108 if ($this->rtl) {
12109 $xpos = $x - $w;
12110 } else {
12111 $xpos = $x;
12112 }
12113 break;
12114 }
12115 case 'C': {
12116 $xdiff = (($w - $fbw) / 2);
12117 if ($this->rtl) {
12118 $xpos = $x - $w + $xdiff;
12119 } else {
12120 $xpos = $x + $xdiff;
12121 }
12122 break;
12123 }
12124 case 'R': {
12125 if ($this->rtl) {
12126 $xpos = $x - $fbw;
12127 } else {
12128 $xpos = $x + $w - $fbw;
12129 }
12130 break;
12131 }
12132 case 'S': {
12133 $fbw = $w;
12134 $xres = ($w - (2 * $style['padding'])) / $arrcode['maxw'];
12135 if ($this->rtl) {
12136 $xpos = $x - $w;
12137 } else {
12138 $xpos = $x;
12139 }
12140 break;
12141 }
12142 }
12143 $xpos_rect = $xpos;
12144 $xpos = $xpos_rect + $style['padding'];
12145 $xpos_text = $xpos;
12146
12147 $tempRTL = $this->rtl;
12148 $this->rtl = false;
12149
12150 if ($style['bgcolor']) {
12151 $this->Rect($xpos_rect, $y, $fbw, $h, $style['border'] ? 'DF' : 'F', '', $style['bgcolor']);
12152 } elseif ($style['border']) {
12153 $this->Rect($xpos_rect, $y, $fbw, $h, 'D');
12154 }
12155
12156 if ($arrcode !== false) {
12157 foreach ($arrcode['bcode'] as $k => $v) {
12158 $bw = ($v['w'] * $xres);
12159 if ($v['t']) {
12160
12161 $ypos = $y + $style['padding'] + ($v['p'] * $barh / $arrcode['maxh']);
12162 $this->Rect($xpos, $ypos, $bw, ($v['h'] * $barh / $arrcode['maxh']), 'F', array(), $style['fgcolor']);
12163 }
12164 $xpos += $bw;
12165 }
12166 }
12167
12168 if ($style['text']) {
12169
12170 $this->x = $xpos_text;
12171 $this->y = $y + $style['padding'] + $barh;
12172 $this->Cell(($arrcode['maxw'] * $xres), ($this->cell_height_ratio * $fontsize / $this->k), $code, 0, 0, 'C', 0, '', $style['stretchtext']);
12173 }
12174
12175 $this->rtl = $tempRTL;
12176
12177 $this->setGraphicVars($gvars);
12178
12179 $this->img_rb_y = $y + $h;
12180 if ($this->rtl) {
12181
12182 $this->img_rb_x = ($this->w - $x - $w);
12183 } else {
12184
12185 $this->img_rb_x = $x + $w;
12186 }
12187
12188 switch($align) {
12189 case 'T':{
12190 $this->y = $y;
12191 $this->x = $this->img_rb_x;
12192 break;
12193 }
12194 case 'M':{
12195 $this->y = $y + round($h/2);
12196 $this->x = $this->img_rb_x;
12197 break;
12198 }
12199 case 'B':{
12200 $this->y = $this->img_rb_y;
12201 $this->x = $this->img_rb_x;
12202 break;
12203 }
12204 case 'N':{
12205 $this->SetY($this->img_rb_y);
12206 break;
12207 }
12208 default:{
12209 break;
12210 }
12211 }
12212 }
12213
12229 public function writeBarcode($x, $y, $w, $h, $type, $style, $font, $xres, $code) {
12230
12231 $xres = 1 / $xres;
12232 $newstyle = array(
12233 'position' => 'L',
12234 'border' => false,
12235 'padding' => 0,
12236 'fgcolor' => array(0,0,0),
12237 'bgcolor' => false,
12238 'text' => true,
12239 'font' => $font,
12240 'fontsize' => 8,
12241 'stretchtext' => 4
12242 );
12243 if ($style & 1) {
12244 $newstyle['border'] = true;
12245 }
12246 if ($style & 2) {
12247 $newstyle['bgcolor'] = false;
12248 }
12249 if ($style & 4) {
12250 $newstyle['position'] = 'C';
12251 } elseif ($style & 8) {
12252 $newstyle['position'] = 'L';
12253 } elseif ($style & 16) {
12254 $newstyle['position'] = 'R';
12255 }
12256 if ($style & 128) {
12257 $newstyle['text'] = true;
12258 }
12259 if ($style & 256) {
12260 $newstyle['stretchtext'] = 4;
12261 }
12262 $this->write1DBarcode($code, $type, $x, $y, $w, $h, $xres, $newstyle, '');
12263 }
12264
12279 public function write2DBarcode($code, $type, $x='', $y='', $w='', $h='', $style='', $align='') {
12280 if ($this->empty_string($code)) {
12281 return;
12282 }
12283 require_once(dirname(__FILE__).'/2dbarcodes.php');
12284
12285 $gvars = $this->getGraphicVars();
12286
12287 $barcodeobj = new TCPDF2DBarcode($code, $type);
12288 $arrcode = $barcodeobj->getBarcodeArray();
12289 if ($arrcode === false) {
12290 $this->Error('Error in 2D barcode string');
12291 }
12292
12293 if (!isset($style['padding'])) {
12294 $style['padding'] = 0;
12295 }
12296 if (!isset($style['fgcolor'])) {
12297 $style['fgcolor'] = array(0,0,0);
12298 }
12299 if (!isset($style['bgcolor'])) {
12300 $style['bgcolor'] = false;
12301 }
12302 if (!isset($style['border'])) {
12303 $style['border'] = false;
12304 }
12305
12306 $this->SetDrawColorArray($style['fgcolor']);
12307 if ($this->empty_string($x)) {
12308 $x = $this->GetX();
12309 }
12310 if ($this->rtl) {
12311 $x = $this->w - $x;
12312 }
12313 if ($this->empty_string($y)) {
12314 $y = $this->GetY();
12315 }
12316 if ($this->empty_string($w) OR ($w <= 0)) {
12317 if ($this->rtl) {
12318 $w = $x - $this->lMargin;
12319 } else {
12320 $w = $this->w - $this->rMargin - $x;
12321 }
12322 }
12323 if ($this->empty_string($h) OR ($h <= 0)) {
12324
12325 $h = $w;
12326 }
12327 if ($this->checkPageBreak($h)) {
12328 $y = $this->y;
12329 }
12330
12331 $bw = $w - (2 * $style['padding']);
12332 $bh = $h - (2 * $style['padding']);
12333
12334 if ($this->rtl) {
12335 $xpos = $x - $w;
12336 } else {
12337 $xpos = $x;
12338 }
12339 $xpos += $style['padding'];
12340 $ypos = $y + $style['padding'];
12341
12342 $tempRTL = $this->rtl;
12343 $this->rtl = false;
12344
12345 if ($style['bgcolor']) {
12346 $this->Rect($x, $y, $w, $h, $style['border'] ? 'DF' : 'F', '', $style['bgcolor']);
12347 } elseif ($style['border']) {
12348 $this->Rect($x, $y, $w, $h, 'D');
12349 }
12350
12351 if ($arrcode !== false) {
12352 $rows = $arrcode['num_rows'];
12353 $cols = $arrcode['num_cols'];
12354
12355 $cw = $bw / $cols;
12356 $ch = $bh / $rows;
12357
12358 for ($r = 0; $r < $rows; ++$r) {
12359 $xr = $xpos;
12360
12361 for ($c = 0; $c < $cols; ++$c) {
12362 if ($arrcode['bcode'][$r][$c] == 1) {
12363
12364 $this->Rect($xr, $ypos, $cw, $ch, 'F', array(), $style['fgcolor']);
12365 }
12366 $xr += $cw;
12367 }
12368 $ypos += $ch;
12369 }
12370 }
12371
12372 $this->rtl = $tempRTL;
12373
12374 $this->setGraphicVars($gvars);
12375
12376 $this->img_rb_y = $y + $h;
12377 if ($this->rtl) {
12378
12379 $this->img_rb_x = ($this->w - $x - $w);
12380 } else {
12381
12382 $this->img_rb_x = $x + $w;
12383 }
12384
12385 switch($align) {
12386 case 'T':{
12387 $this->y = $y;
12388 $this->x = $this->img_rb_x;
12389 break;
12390 }
12391 case 'M':{
12392 $this->y = $y + round($h/2);
12393 $this->x = $this->img_rb_x;
12394 break;
12395 }
12396 case 'B':{
12397 $this->y = $this->img_rb_y;
12398 $this->x = $this->img_rb_x;
12399 break;
12400 }
12401 case 'N':{
12402 $this->SetY($this->img_rb_y);
12403 break;
12404 }
12405 default:{
12406 break;
12407 }
12408 }
12409 }
12410
12426 public function getMargins() {
12427 $ret = array(
12428 'left' => $this->lMargin,
12429 'right' => $this->rMargin,
12430 'top' => $this->tMargin,
12431 'bottom' => $this->bMargin,
12432 'header' => $this->header_margin,
12433 'footer' => $this->footer_margin,
12434 'cell' => $this->cMargin,
12435 );
12436 return $ret;
12437 }
12438
12449 public function getOriginalMargins() {
12450 $ret = array(
12451 'left' => $this->original_lMargin,
12452 'right' => $this->original_rMargin
12453 );
12454 return $ret;
12455 }
12456
12463 public function getFontSize() {
12464 return $this->FontSize;
12465 }
12466
12473 public function getFontSizePt() {
12474 return $this->FontSizePt;
12475 }
12476
12483 public function getFontFamily() {
12484 return $this->FontFamily;
12485 }
12486
12493 public function getFontStyle() {
12494 return $this->FontStyle;
12495 }
12496
12517 public function writeHTMLCell($w, $h, $x, $y, $html='', $border=0, $ln=0, $fill=0, $reseth=true, $align='', $autopadding=true) {
12518 return $this->MultiCell($w, $h, $html, $border, $align, $fill, $ln, $x, $y, $reseth, 0, true, $autopadding, 0);
12519 }
12520
12529 protected function getHtmlDomArray($html) {
12530
12531 $html = strip_tags($html, '<marker/><a><b><blockquote><br><br/><dd><del><div><dl><dt><em><font><form><h1><h2><h3><h4><h5><h6><hr><i><img><input><label><li><ol><option><p><pre><select><small><span><strong><sub><sup><table><tablehead><tcpdf><td><textarea><th><thead><tr><tt><u><ul>');
12532
12533 $html = preg_replace('/<pre/', '<xre', $html);
12534 $html = preg_replace('/<(table|tr|td|th|tcpdf|blockquote|dd|div|dt|form|h1|h2|h3|h4|h5|h6|br|hr|li|ol|ul|p)([^>]*)>[\n\r\t]+/', '<\\1\\2>', $html);
12535 $html = preg_replace('@(\r\n|\r)@', "\n", $html);
12536 $repTable = array("\t" => ' ', "\0" => ' ', "\x0B" => ' ', "\\" => "\\\\");
12537 $html = strtr($html, $repTable);
12538 $offset = 0;
12539 while (($offset < strlen($html)) AND ($pos = strpos($html, '</pre>', $offset)) !== false) {
12540 $html_a = substr($html, 0, $offset);
12541 $html_b = substr($html, $offset, ($pos - $offset + 6));
12542 while (preg_match("'<xre([^>]*)>(.*?)\n(.*?)</pre>'si", $html_b)) {
12543
12544 $html_b = preg_replace("'<xre([^>]*)>(.*?)\n(.*?)</pre>'si", "<xre\\1>\\2<br />\\3</pre>", $html_b);
12545 }
12546 $html = $html_a.$html_b.substr($html, $pos + 6);
12547 $offset = strlen($html_a.$html_b);
12548 }
12549 $offset = 0;
12550 while (($offset < strlen($html)) AND ($pos = strpos($html, '</textarea>', $offset)) !== false) {
12551 $html_a = substr($html, 0, $offset);
12552 $html_b = substr($html, $offset, ($pos - $offset + 11));
12553 while (preg_match("'<textarea([^>]*)>(.*?)\n(.*?)</textarea>'si", $html_b)) {
12554
12555 $html_b = preg_replace("'<textarea([^>]*)>(.*?)\n(.*?)</textarea>'si", "<textarea\\1>\\2<TBR>\\3</textarea>", $html_b);
12556 $html_b = preg_replace("'<textarea([^>]*)>(.*?)[\"](.*?)</textarea>'si", "<textarea\\1>\\2''\\3</textarea>", $html_b);
12557 }
12558 $html = $html_a.$html_b.substr($html, $pos + 11);
12559 $offset = strlen($html_a.$html_b);
12560 }
12561 $html = preg_replace("'([\s]*)<option'si", "<option", $html);
12562 $html = preg_replace("'</option>([\s]*)'si", "</option>", $html);
12563 $offset = 0;
12564 while (($offset < strlen($html)) AND ($pos = strpos($html, '</option>', $offset)) !== false) {
12565 $html_a = substr($html, 0, $offset);
12566 $html_b = substr($html, $offset, ($pos - $offset + 9));
12567 while (preg_match("'<option([^>]*)>(.*?)</option>'si", $html_b)) {
12568 $html_b = preg_replace("'<option([\s]+)value=\"([^\"]*)\"([^>]*)>(.*?)</option>'si", "\\2\t\\4\r", $html_b);
12569 $html_b = preg_replace("'<option([^>]*)>(.*?)</option>'si", "\\2\r", $html_b);
12570 }
12571 $html = $html_a.$html_b.substr($html, $pos + 9);
12572 $offset = strlen($html_a.$html_b);
12573 }
12574 $html = preg_replace("'<select([^>]*)>'si", "<select\\1 opt=\"", $html);
12575 $html = preg_replace("'([\s]+)</select>'si", "\" />", $html);
12576 $html = str_replace("\n", ' ', $html);
12577
12578 $html = str_replace('<TBR>', "\n", $html);
12579
12580 $html = preg_replace('/[\s]+<\/(table|tr|td|th|ul|ol|li)>/', '</\\1>', $html);
12581 $html = preg_replace('/[\s]+<(tr|td|th|ul|ol|li|br)/', '<\\1', $html);
12582 $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);
12583 $html = preg_replace('/<\/(td|th)>/', '<marker style="font-size:0"/></\\1>', $html);
12584 $html = preg_replace('/<\/table>([\s]*)<marker style="font-size:0"\/>/', '</table>', $html);
12585 $html = preg_replace('/<img/', ' <img', $html);
12586 $html = preg_replace('/<img([^>]*)>/xi', '<img\\1><span></span>', $html);
12587 $html = preg_replace('/<xre/', '<pre', $html);
12588 $html = preg_replace('/<textarea([^>]*)>/xi', '<textarea\\1 value="', $html);
12589 $html = preg_replace('/<\/textarea>/', '" />', $html);
12590
12591 $html = preg_replace('/^[\s]+/', '', $html);
12592 $html = preg_replace('/[\s]+$/', '', $html);
12593
12594 $tagpattern = '/(<[^>]+>)/';
12595
12596 $a = preg_split($tagpattern, $html, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
12597
12598 $maxel = count($a);
12599 $elkey = 0;
12600 $key = 0;
12601
12602 $dom = array();
12603 $dom[$key] = array();
12604
12605 $dom[$key]['tag'] = false;
12606 $dom[$key]['value'] = '';
12607 $dom[$key]['parent'] = 0;
12608 $dom[$key]['fontname'] = $this->FontFamily;
12609 $dom[$key]['fontstyle'] = $this->FontStyle;
12610 $dom[$key]['fontsize'] = $this->FontSizePt;
12611 $dom[$key]['bgcolor'] = false;
12612 $dom[$key]['fgcolor'] = $this->fgcolor;
12613 $dom[$key]['align'] = '';
12614 $dom[$key]['listtype'] = '';
12615 $dom[$key]['text-indent'] = 0;
12616 $thead = false;
12617 ++$key;
12618 $level = array();
12619 array_push($level, 0);
12620 while ($elkey < $maxel) {
12621 $dom[$key] = array();
12622 $element = $a[$elkey];
12623 $dom[$key]['elkey'] = $elkey;
12624 if (preg_match($tagpattern, $element)) {
12625
12626 $element = substr($element, 1, -1);
12627
12628 preg_match('/[\/]?([a-zA-Z0-9]*)/', $element, $tag);
12629 $tagname = strtolower($tag[1]);
12630
12631 if ($tagname == 'thead') {
12632 if ($element{0} == '/') {
12633 $thead = false;
12634 } else {
12635 $thead = true;
12636 }
12637 ++$elkey;
12638 continue;
12639 }
12640 $dom[$key]['tag'] = true;
12641 $dom[$key]['value'] = $tagname;
12642 if ($element{0} == '/') {
12643
12644 $dom[$key]['opening'] = false;
12645 $dom[$key]['parent'] = end($level);
12646 array_pop($level);
12647 $dom[$key]['fontname'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontname'];
12648 $dom[$key]['fontstyle'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontstyle'];
12649 $dom[$key]['fontsize'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontsize'];
12650 $dom[$key]['bgcolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['bgcolor'];
12651 $dom[$key]['fgcolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fgcolor'];
12652 $dom[$key]['align'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['align'];
12653 if (isset($dom[($dom[($dom[$key]['parent'])]['parent'])]['listtype'])) {
12654 $dom[$key]['listtype'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['listtype'];
12655 }
12656
12657 if (($dom[$key]['value'] == 'tr') AND (!isset($dom[($dom[($dom[$key]['parent'])]['parent'])]['cols']))) {
12658 $dom[($dom[($dom[$key]['parent'])]['parent'])]['cols'] = $dom[($dom[$key]['parent'])]['cols'];
12659 }
12660 if (($dom[$key]['value'] == 'td') OR ($dom[$key]['value'] == 'th')) {
12661 $dom[($dom[$key]['parent'])]['content'] = '';
12662 for ($i = ($dom[$key]['parent'] + 1); $i < $key; ++$i) {
12663 $dom[($dom[$key]['parent'])]['content'] .= $a[$dom[$i]['elkey']];
12664 }
12665 $key = $i;
12666 }
12667
12668 if (($dom[$key]['value'] == 'tr') AND ($dom[($dom[$key]['parent'])]['thead'] === true)) {
12669 if ($this->empty_string($dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'])) {
12670 $dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'] = $a[$dom[($dom[($dom[$key]['parent'])]['parent'])]['elkey']];
12671 }
12672 for ($i = $dom[$key]['parent']; $i <= $key; ++$i) {
12673 $dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'] .= $a[$dom[$i]['elkey']];
12674 }
12675 }
12676 if (($dom[$key]['value'] == 'table') AND (!$this->empty_string($dom[($dom[$key]['parent'])]['thead']))) {
12677 $dom[($dom[$key]['parent'])]['thead'] .= '</tablehead>';
12678 }
12679 } else {
12680
12681 $dom[$key]['opening'] = true;
12682 $dom[$key]['parent'] = end($level);
12683 if (substr($element, -1, 1) != '/') {
12684
12685 array_push($level, $key);
12686 $dom[$key]['self'] = false;
12687 } else {
12688 $dom[$key]['self'] = true;
12689 }
12690
12691 $parentkey = 0;
12692 if ($key > 0) {
12693 $parentkey = $dom[$key]['parent'];
12694 $dom[$key]['fontname'] = $dom[$parentkey]['fontname'];
12695 $dom[$key]['fontstyle'] = $dom[$parentkey]['fontstyle'];
12696 $dom[$key]['fontsize'] = $dom[$parentkey]['fontsize'];
12697 $dom[$key]['bgcolor'] = $dom[$parentkey]['bgcolor'];
12698 $dom[$key]['fgcolor'] = $dom[$parentkey]['fgcolor'];
12699 $dom[$key]['align'] = $dom[$parentkey]['align'];
12700 $dom[$key]['listtype'] = $dom[$parentkey]['listtype'];
12701 $dom[$key]['text-indent'] = $dom[$parentkey]['text-indent'];
12702 }
12703
12704 preg_match_all('/([^=\s]*)=["]?([^"]*)["]?/', $element, $attr_array, PREG_PATTERN_ORDER);
12705 $dom[$key]['attribute'] = array();
12706 while (list($id, $name) = each($attr_array[1])) {
12707 $dom[$key]['attribute'][strtolower($name)] = $attr_array[2][$id];
12708 }
12709
12710 if (isset($dom[$key]['attribute']['style'])) {
12711
12712 preg_match_all('/([^;:\s]*):([^;]*)/', $dom[$key]['attribute']['style'], $style_array, PREG_PATTERN_ORDER);
12713 $dom[$key]['style'] = array();
12714 while (list($id, $name) = each($style_array[1])) {
12715 $dom[$key]['style'][strtolower($name)] = trim($style_array[2][$id]);
12716 }
12717
12718 if (isset($dom[$key]['style']['font-family'])) {
12719
12720 if (isset($dom[$key]['style']['font-family'])) {
12721 $fontslist = preg_split('/[,]/', strtolower($dom[$key]['style']['font-family']));
12722 foreach ($fontslist as $font) {
12723 $font = trim(strtolower($font));
12724 if (in_array($font, $this->fontlist) OR in_array($font, $this->fontkeys)) {
12725 $dom[$key]['fontname'] = $font;
12726 break;
12727 }
12728 }
12729 }
12730 }
12731
12732 if (isset($dom[$key]['style']['list-style-type'])) {
12733 $dom[$key]['listtype'] = trim(strtolower($dom[$key]['style']['list-style-type']));
12734 if ($dom[$key]['listtype'] == 'inherit') {
12735 $dom[$key]['listtype'] = $dom[$parentkey]['listtype'];
12736 }
12737 }
12738
12739 if (isset($dom[$key]['style']['text-indent'])) {
12740 $dom[$key]['text-indent'] = $this->getHTMLUnitToUnits($dom[$key]['style']['text-indent']);
12741 if ($dom[$key]['text-indent'] == 'inherit') {
12742 $dom[$key]['text-indent'] = $dom[$parentkey]['text-indent'];
12743 }
12744 }
12745
12746 if (isset($dom[$key]['style']['font-size'])) {
12747 $fsize = trim($dom[$key]['style']['font-size']);
12748 switch ($fsize) {
12749
12750 case 'xx-small': {
12751 $dom[$key]['fontsize'] = $dom[0]['fontsize'] - 4;
12752 break;
12753 }
12754 case 'x-small': {
12755 $dom[$key]['fontsize'] = $dom[0]['fontsize'] - 3;
12756 break;
12757 }
12758 case 'small': {
12759 $dom[$key]['fontsize'] = $dom[0]['fontsize'] - 2;
12760 break;
12761 }
12762 case 'medium': {
12763 $dom[$key]['fontsize'] = $dom[0]['fontsize'];
12764 break;
12765 }
12766 case 'large': {
12767 $dom[$key]['fontsize'] = $dom[0]['fontsize'] + 2;
12768 break;
12769 }
12770 case 'x-large': {
12771 $dom[$key]['fontsize'] = $dom[0]['fontsize'] + 4;
12772 break;
12773 }
12774 case 'xx-large': {
12775 $dom[$key]['fontsize'] = $dom[0]['fontsize'] + 6;
12776 break;
12777 }
12778
12779 case 'smaller': {
12780 $dom[$key]['fontsize'] = $dom[$parentkey]['fontsize'] - 3;
12781 break;
12782 }
12783 case 'larger': {
12784 $dom[$key]['fontsize'] = $dom[$parentkey]['fontsize'] + 3;
12785 break;
12786 }
12787 default: {
12788 $dom[$key]['fontsize'] = $this->getHTMLUnitToUnits($fsize, $dom[$parentkey]['fontsize'], 'pt', true);
12789 }
12790 }
12791 }
12792
12793 if (isset($dom[$key]['style']['font-weight']) AND (strtolower($dom[$key]['style']['font-weight']{0}) == 'b')) {
12794 $dom[$key]['fontstyle'] .= 'B';
12795 }
12796 if (isset($dom[$key]['style']['font-style']) AND (strtolower($dom[$key]['style']['font-style']{0}) == 'i')) {
12797 $dom[$key]['fontstyle'] .= '"I';
12798 }
12799
12800 if (isset($dom[$key]['style']['color']) AND (!$this->empty_string($dom[$key]['style']['color']))) {
12801 $dom[$key]['fgcolor'] = $this->convertHTMLColorToDec($dom[$key]['style']['color']);
12802 }
12803
12804 if (isset($dom[$key]['style']['background-color']) AND (!$this->empty_string($dom[$key]['style']['background-color']))) {
12805 $dom[$key]['bgcolor'] = $this->convertHTMLColorToDec($dom[$key]['style']['background-color']);
12806 }
12807
12808 if (isset($dom[$key]['style']['text-decoration'])) {
12809 $decors = explode(' ', strtolower($dom[$key]['style']['text-decoration']));
12810 foreach ($decors as $dec) {
12811 $dec = trim($dec);
12812 if (!$this->empty_string($dec)) {
12813 if ($dec{0} == 'u') {
12814 $dom[$key]['fontstyle'] .= 'U';
12815 } elseif ($dec{0} == 'l') {
12816 $dom[$key]['fontstyle'] .= 'D';
12817 }
12818 }
12819 }
12820 }
12821
12822 if (isset($dom[$key]['style']['width'])) {
12823 $dom[$key]['width'] = $dom[$key]['style']['width'];
12824 }
12825
12826 if (isset($dom[$key]['style']['height'])) {
12827 $dom[$key]['height'] = $dom[$key]['style']['height'];
12828 }
12829
12830 if (isset($dom[$key]['style']['text-align'])) {
12831 $dom[$key]['align'] = strtoupper($dom[$key]['style']['text-align']{0});
12832 }
12833
12834 if (isset($dom[$key]['style']['border'])) {
12835 $dom[$key]['attribute']['border'] = $dom[$key]['style']['border'];
12836 }
12837 }
12838
12839 if ($dom[$key]['value'] == 'font') {
12840
12841 if (isset($dom[$key]['attribute']['face'])) {
12842 $fontslist = preg_split('/[,]/', strtolower($dom[$key]['attribute']['face']));
12843 foreach ($fontslist as $font) {
12844 $font = trim(strtolower($font));
12845 if (in_array($font, $this->fontlist) OR in_array($font, $this->fontkeys)) {
12846 $dom[$key]['fontname'] = $font;
12847 break;
12848 }
12849 }
12850 }
12851
12852 if (isset($dom[$key]['attribute']['size'])) {
12853 if ($key > 0) {
12854 if ($dom[$key]['attribute']['size']{0} == '+') {
12855 $dom[$key]['fontsize'] = $dom[($dom[$key]['parent'])]['fontsize'] + intval(substr($dom[$key]['attribute']['size'], 1));
12856 } elseif ($dom[$key]['attribute']['size']{0} == '-') {
12857 $dom[$key]['fontsize'] = $dom[($dom[$key]['parent'])]['fontsize'] - intval(substr($dom[$key]['attribute']['size'], 1));
12858 } else {
12859 $dom[$key]['fontsize'] = intval($dom[$key]['attribute']['size']);
12860 }
12861 } else {
12862 $dom[$key]['fontsize'] = intval($dom[$key]['attribute']['size']);
12863 }
12864 }
12865 }
12866
12867 if ((($dom[$key]['value'] == 'ul') OR ($dom[$key]['value'] == 'ol') OR ($dom[$key]['value'] == 'dl'))
12868 AND (!isset($dom[$key]['align']) OR $this->empty_string($dom[$key]['align']) OR ($dom[$key]['align'] != 'J'))) {
12869 if ($this->rtl) {
12870 $dom[$key]['align'] = 'R';
12871 } else {
12872 $dom[$key]['align'] = 'L';
12873 }
12874 }
12875 if (($dom[$key]['value'] == 'small') OR ($dom[$key]['value'] == 'sup') OR ($dom[$key]['value'] == 'sub')) {
12876 $dom[$key]['fontsize'] = $dom[$key]['fontsize'] * K_SMALL_RATIO;
12877 }
12878 if (($dom[$key]['value'] == 'strong') OR ($dom[$key]['value'] == 'b')) {
12879 $dom[$key]['fontstyle'] .= 'B';
12880 }
12881 if (($dom[$key]['value'] == 'em') OR ($dom[$key]['value'] == 'i')) {
12882 $dom[$key]['fontstyle'] .= 'I';
12883 }
12884 if ($dom[$key]['value'] == 'u') {
12885 $dom[$key]['fontstyle'] .= 'U';
12886 }
12887 if ($dom[$key]['value'] == 'del') {
12888 $dom[$key]['fontstyle'] .= 'D';
12889 }
12890 if (($dom[$key]['value'] == 'pre') OR ($dom[$key]['value'] == 'tt')) {
12891 $dom[$key]['fontname'] = $this->default_monospaced_font;
12892 }
12893 if (($dom[$key]['value']{0} == 'h') AND (intval($dom[$key]['value']{1}) > 0) AND (intval($dom[$key]['value']{1}) < 7)) {
12894 $headsize = (4 - intval($dom[$key]['value']{1})) * 2;
12895 $dom[$key]['fontsize'] = $dom[0]['fontsize'] + $headsize;
12896 $dom[$key]['fontstyle'] .= 'B';
12897 }
12898 if (($dom[$key]['value'] == 'table')) {
12899 $dom[$key]['rows'] = 0;
12900 $dom[$key]['trids'] = array();
12901 $dom[$key]['thead'] = '';
12902 }
12903 if (($dom[$key]['value'] == 'tr')) {
12904 $dom[$key]['cols'] = 0;
12905
12906 ++$dom[($dom[$key]['parent'])]['rows'];
12907
12908 array_push($dom[($dom[$key]['parent'])]['trids'], $key);
12909 if ($thead) {
12910 $dom[$key]['thead'] = true;
12911 } else {
12912 $dom[$key]['thead'] = false;
12913 }
12914 }
12915 if (($dom[$key]['value'] == 'th') OR ($dom[$key]['value'] == 'td')) {
12916 if (isset($dom[$key]['attribute']['colspan'])) {
12917 $colspan = intval($dom[$key]['attribute']['colspan']);
12918 } else {
12919 $colspan = 1;
12920 }
12921 $dom[$key]['attribute']['colspan'] = $colspan;
12922 $dom[($dom[$key]['parent'])]['cols'] += $colspan;
12923 }
12924
12925 if (isset($dom[$key]['attribute']['color']) AND (!$this->empty_string($dom[$key]['attribute']['color']))) {
12926 $dom[$key]['fgcolor'] = $this->convertHTMLColorToDec($dom[$key]['attribute']['color']);
12927 }
12928
12929 if (isset($dom[$key]['attribute']['bgcolor']) AND (!$this->empty_string($dom[$key]['attribute']['bgcolor']))) {
12930 $dom[$key]['bgcolor'] = $this->convertHTMLColorToDec($dom[$key]['attribute']['bgcolor']);
12931 }
12932
12933 if (isset($dom[$key]['attribute']['width'])) {
12934 $dom[$key]['width'] = $dom[$key]['attribute']['width'];
12935 }
12936
12937 if (isset($dom[$key]['attribute']['height'])) {
12938 $dom[$key]['height'] = $dom[$key]['attribute']['height'];
12939 }
12940
12941 if (isset($dom[$key]['attribute']['align']) AND (!$this->empty_string($dom[$key]['attribute']['align'])) AND ($dom[$key]['value'] !== 'img')) {
12942 $dom[$key]['align'] = strtoupper($dom[$key]['attribute']['align']{0});
12943 }
12944 }
12945 } else {
12946
12947 $dom[$key]['tag'] = false;
12948 $dom[$key]['value'] = stripslashes($this->unhtmlentities($element));
12949 $dom[$key]['parent'] = end($level);
12950 }
12951 ++$elkey;
12952 ++$key;
12953 }
12954 return $dom;
12955 }
12956
12969 public function writeHTML($html, $ln=true, $fill=false, $reseth=false, $cell=false, $align='') {
12970 $gvars = $this->getGraphicVars();
12971
12972 $prevPage = $this->page;
12973 $prevlMargin = $this->lMargin;
12974 $prevrMargin = $this->rMargin;
12975 $curfontname = $this->FontFamily;
12976 $curfontstyle = $this->FontStyle;
12977 $curfontsize = $this->FontSizePt;
12978 $this->newline = true;
12979 $startlinepage = $this->page;
12980 $minstartliney = $this->y;
12981 $startlinex = $this->x;
12982 $startliney = $this->y;
12983 $yshift = 0;
12984 $newline = true;
12985 $loop = 0;
12986 $curpos = 0;
12987 $this_method_vars = array();
12988 $undo = false;
12989 $blocktags = array('blockquote','br','dd','div','dt','h1','h2','h3','h4','h5','h6','hr','li','ol','p','ul','tcpdf');
12990 $this->premode = false;
12991 if (isset($this->PageAnnots[$this->page])) {
12992 $pask = count($this->PageAnnots[$this->page]);
12993 } else {
12994 $pask = 0;
12995 }
12996 if (isset($this->footerlen[$this->page])) {
12997 $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page];
12998 } else {
12999 $this->footerpos[$this->page] = $this->pagelen[$this->page];
13000 }
13001 $startlinepos = $this->footerpos[$this->page];
13002 $lalign = $align;
13003 $plalign = $align;
13004 if ($this->rtl) {
13005 $w = $this->x - $this->lMargin;
13006 } else {
13007 $w = $this->w - $this->rMargin - $this->x;
13008 }
13009 $w -= (2 * $this->cMargin);
13010 if ($cell) {
13011 if ($this->rtl) {
13012 $this->x -= $this->cMargin;
13013 } else {
13014 $this->x += $this->cMargin;
13015 }
13016 }
13017 if ($this->customlistindent >= 0) {
13018 $this->listindent = $this->customlistindent;
13019 } else {
13020 $this->listindent = $this->GetStringWidth('0000');
13021 }
13022
13023 $prev_listnum = $this->listnum;
13024 $prev_listordered = $this->listordered;
13025 $prev_listcount = $this->listcount;
13026 $prev_lispacer = $this->lispacer;
13027 $this->listnum = 0;
13028 $this->listordered = array();
13029 $this->listcount = array();
13030 $this->lispacer = '';
13031 if (($this->empty_string($this->lasth)) OR ($reseth)) {
13032
13033 $this->lasth = $this->FontSize * $this->cell_height_ratio;
13034 }
13035 $dom = $this->getHtmlDomArray($html);
13036 $maxel = count($dom);
13037 $key = 0;
13038 while ($key < $maxel) {
13039 if ($dom[$key]['tag'] AND $dom[$key]['opening'] AND isset($dom[$key]['attribute']['nobr']) AND ($dom[$key]['attribute']['nobr'] == 'true')) {
13040 if (isset($dom[($dom[$key]['parent'])]['attribute']['nobr']) AND ($dom[($dom[$key]['parent'])]['attribute']['nobr'] == 'true')) {
13041 $dom[$key]['attribute']['nobr'] = false;
13042 } else {
13043
13044 $this->startTransaction();
13045
13046 $this_method_vars['html'] = $html;
13047 $this_method_vars['ln'] = $ln;
13048 $this_method_vars['fill'] = $fill;
13049 $this_method_vars['reseth'] = $reseth;
13050 $this_method_vars['cell'] = $cell;
13051 $this_method_vars['align'] = $align;
13052 $this_method_vars['gvars'] = $gvars;
13053 $this_method_vars['prevPage'] = $prevPage;
13054 $this_method_vars['prevlMargin'] = $prevlMargin;
13055 $this_method_vars['prevrMargin'] = $prevrMargin;
13056 $this_method_vars['curfontname'] = $curfontname;
13057 $this_method_vars['curfontstyle'] = $curfontstyle;
13058 $this_method_vars['curfontsize'] = $curfontsize;
13059 $this_method_vars['minstartliney'] = $minstartliney;
13060 $this_method_vars['yshift'] = $yshift;
13061 $this_method_vars['startlinepage'] = $startlinepage;
13062 $this_method_vars['startlinepos'] = $startlinepos;
13063 $this_method_vars['startlinex'] = $startlinex;
13064 $this_method_vars['startliney'] = $startliney;
13065 $this_method_vars['newline'] = $newline;
13066 $this_method_vars['loop'] = $loop;
13067 $this_method_vars['curpos'] = $curpos;
13068 $this_method_vars['pask'] = $pask;
13069 $this_method_vars['lalign'] = $lalign;
13070 $this_method_vars['plalign'] = $plalign;
13071 $this_method_vars['w'] = $w;
13072 $this_method_vars['prev_listnum'] = $prev_listnum;
13073 $this_method_vars['prev_listordered'] = $prev_listordered;
13074 $this_method_vars['prev_listcount'] = $prev_listcount;
13075 $this_method_vars['prev_lispacer'] = $prev_lispacer;
13076 $this_method_vars['key'] = $key;
13077 $this_method_vars['dom'] = $dom;
13078 }
13079 }
13080 if ($dom[$key]['tag'] OR ($key == 0)) {
13081 if ((($dom[$key]['value'] == 'table') OR ($dom[$key]['value'] == 'tr')) AND (isset($dom[$key]['align']))) {
13082 $dom[$key]['align'] = ($this->rtl) ? 'R' : 'L';
13083 }
13084
13085 if ((!$this->newline)
13086 AND ($dom[$key]['value'] == 'img')
13087 AND (isset($dom[$key]['attribute']['height']))
13088 AND ($dom[$key]['attribute']['height'] > 0)) {
13089
13090
13091 $imgh = $this->getHTMLUnitToUnits($dom[$key]['attribute']['height'], $this->lasth, 'px');
13092 if (!$this->InFooter) {
13093
13094 $this->checkPageBreak($imgh);
13095 }
13096 if ($this->page > $startlinepage) {
13097
13098 if (isset($this->footerlen[$startlinepage])) {
13099 $curpos = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
13100 }
13101
13102 $pagebuff = $this->getPageBuffer($startlinepage);
13103 $linebeg = substr($pagebuff, $startlinepos, ($curpos - $startlinepos));
13104 $tstart = substr($pagebuff, 0, $startlinepos);
13105 $tend = substr($this->getPageBuffer($startlinepage), $curpos);
13106
13107 $this->setPageBuffer($startlinepage, $tstart.''.$tend);
13108 $pagebuff = $this->getPageBuffer($this->page);
13109 $tstart = substr($pagebuff, 0, $this->cntmrk[$this->page]);
13110 $tend = substr($pagebuff, $this->cntmrk[$this->page]);
13111
13112 $yshift = $minstartliney - $this->y;
13113 $try = sprintf('1 0 0 1 0 %.3F cm', ($yshift * $this->k));
13114 $this->setPageBuffer($this->page, $tstart."\nq\n".$try."\n".$linebeg."\nQ\n".$tend);
13115
13116 if (isset($this->PageAnnots[$this->page])) {
13117 $next_pask = count($this->PageAnnots[$this->page]);
13118 } else {
13119 $next_pask = 0;
13120 }
13121 if (isset($this->PageAnnots[$startlinepage])) {
13122 foreach ($this->PageAnnots[$startlinepage] as $pak => $pac) {
13123 if ($pak >= $pask) {
13124 $this->PageAnnots[$this->page][] = $pac;
13125 unset($this->PageAnnots[$startlinepage][$pak]);
13126 $npak = count($this->PageAnnots[$this->page]) - 1;
13127 $this->PageAnnots[$this->page][$npak]['y'] -= $yshift;
13128 }
13129 }
13130
13131 }
13132 $pask = $next_pask;
13133 $startlinepos = $this->cntmrk[$this->page];
13134 $startlinepage = $this->page;
13135 $startliney = $this->y;
13136 }
13137 $this->y += (($curfontsize / $this->k) - $imgh);
13138 $minstartliney = min($this->y, $minstartliney);
13139 } elseif (isset($dom[$key]['fontname']) OR isset($dom[$key]['fontstyle']) OR isset($dom[$key]['fontsize'])) {
13140
13141 $pfontname = $curfontname;
13142 $pfontstyle = $curfontstyle;
13143 $pfontsize = $curfontsize;
13144 $fontname = isset($dom[$key]['fontname']) ? $dom[$key]['fontname'] : $curfontname;
13145 $fontstyle = isset($dom[$key]['fontstyle']) ? $dom[$key]['fontstyle'] : $curfontstyle;
13146 $fontsize = isset($dom[$key]['fontsize']) ? $dom[$key]['fontsize'] : $curfontsize;
13147 if (($fontname != $curfontname) OR ($fontstyle != $curfontstyle) OR ($fontsize != $curfontsize)) {
13148 $this->SetFont($fontname, $fontstyle, $fontsize);
13149 $this->lasth = $this->FontSize * $this->cell_height_ratio;
13150 if (is_numeric($fontsize) AND ($fontsize > 0)
13151 AND is_numeric($curfontsize) AND ($curfontsize > 0)
13152 AND ($fontsize != $curfontsize) AND (!$this->newline)
13153 AND ($key < ($maxel - 1))
13154 ) {
13155 if ((!$this->newline) AND ($this->page > $startlinepage)) {
13156
13157 if (isset($this->footerlen[$startlinepage])) {
13158 $curpos = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
13159 }
13160
13161 $pagebuff = $this->getPageBuffer($startlinepage);
13162 $linebeg = substr($pagebuff, $startlinepos, ($curpos - $startlinepos));
13163 $tstart = substr($pagebuff, 0, $startlinepos);
13164 $tend = substr($this->getPageBuffer($startlinepage), $curpos);
13165
13166 $this->setPageBuffer($startlinepage, $tstart.''.$tend);
13167 $pagebuff = $this->getPageBuffer($this->page);
13168 $tstart = substr($pagebuff, 0, $this->cntmrk[$this->page]);
13169 $tend = substr($pagebuff, $this->cntmrk[$this->page]);
13170
13171 $yshift = $minstartliney - $this->y;
13172 $try = sprintf('1 0 0 1 0 %.3F cm', ($yshift * $this->k));
13173 $this->setPageBuffer($this->page, $tstart."\nq\n".$try."\n".$linebeg."\nQ\n".$tend);
13174
13175 if (isset($this->PageAnnots[$this->page])) {
13176 $next_pask = count($this->PageAnnots[$this->page]);
13177 } else {
13178 $next_pask = 0;
13179 }
13180 if (isset($this->PageAnnots[$startlinepage])) {
13181 foreach ($this->PageAnnots[$startlinepage] as $pak => $pac) {
13182 if ($pak >= $pask) {
13183 $this->PageAnnots[$this->page][] = $pac;
13184 unset($this->PageAnnots[$startlinepage][$pak]);
13185 $npak = count($this->PageAnnots[$this->page]) - 1;
13186 $this->PageAnnots[$this->page][$npak]['y'] -= $yshift;
13187 }
13188 }
13189 }
13190 $pask = $next_pask;
13191 }
13192 if (($dom[$key]['value'] != 'td') AND ($dom[$key]['value'] != 'th')) {
13193 $this->y += (($curfontsize - $fontsize) / $this->k);
13194 }
13195 $minstartliney = min($this->y, $minstartliney);
13196 }
13197 $curfontname = $fontname;
13198 $curfontstyle = $fontstyle;
13199 $curfontsize = $fontsize;
13200 }
13201 }
13202 if (($plalign == 'J') AND (in_array($dom[$key]['value'], $blocktags))) {
13203 $plalign = '';
13204 }
13205
13206 $curpos = $this->pagelen[$startlinepage];
13207 if (isset($dom[$key]['bgcolor']) AND ($dom[$key]['bgcolor'] !== false)) {
13208 $this->SetFillColorArray($dom[$key]['bgcolor']);
13209 $wfill = true;
13210 } else {
13211 $wfill = $fill | false;
13212 }
13213 if (isset($dom[$key]['fgcolor']) AND ($dom[$key]['fgcolor'] !== false)) {
13214 $this->SetTextColorArray($dom[$key]['fgcolor']);
13215 }
13216 if (isset($dom[$key]['align'])) {
13217 $lalign = $dom[$key]['align'];
13218 }
13219 if ($this->empty_string($lalign)) {
13220 $lalign = $align;
13221 }
13222 }
13223
13224 if ($this->newline AND (strlen($dom[$key]['value']) > 0) AND ($dom[$key]['value'] != 'td') AND ($dom[$key]['value'] != 'th')) {
13225 $newline = true;
13226
13227 if (isset($startlinex)) {
13228 $yshift = $minstartliney - $startliney;
13229 if (($yshift > 0) OR ($this->page > $startlinepage)) {
13230 $yshift = 0;
13231 }
13232 if ((isset($plalign) AND ((($plalign == 'C') OR ($plalign == 'J') OR (($plalign == 'R') AND (!$this->rtl)) OR (($plalign == 'L') AND ($this->rtl))))) OR ($yshift < 0)) {
13233
13234 $linew = abs($this->endlinex - $startlinex);
13235 $pstart = substr($this->getPageBuffer($startlinepage), 0, $startlinepos);
13236 if (isset($opentagpos) AND isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
13237 $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
13238 $midpos = min($opentagpos, $this->footerpos[$startlinepage]);
13239 } elseif (isset($opentagpos)) {
13240 $midpos = $opentagpos;
13241 } elseif (isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
13242 $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
13243 $midpos = $this->footerpos[$startlinepage];
13244 } else {
13245 $midpos = 0;
13246 }
13247 if ($midpos > 0) {
13248 $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos, ($midpos - $startlinepos));
13249 $pend = substr($this->getPageBuffer($startlinepage), $midpos);
13250 } else {
13251 $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos);
13252 $pend = '';
13253 }
13254
13255 $tw = $w;
13256 if ($this->lMargin != $prevlMargin) {
13257 $tw += ($prevlMargin - $this->lMargin);
13258 }
13259 if ($this->rMargin != $prevrMargin) {
13260 $tw += ($prevrMargin - $this->rMargin);
13261 }
13262 $mdiff = abs($tw - $linew);
13263 $t_x = 0;
13264 if ($plalign == 'C') {
13265 if ($this->rtl) {
13266 $t_x = -($mdiff / 2);
13267 } else {
13268 $t_x = ($mdiff / 2);
13269 }
13270 } elseif (($plalign == 'R') AND (!$this->rtl)) {
13271
13272 $t_x = $mdiff;
13273 } elseif (($plalign == 'L') AND ($this->rtl)) {
13274
13275 $t_x = -$mdiff;
13276 } elseif (($plalign == 'J') AND ($plalign == $lalign)) {
13277
13278 if ($this->rtl OR $this->tmprtl) {
13279 $t_x = $this->lMargin - $this->endlinex;
13280 }
13281 $no = 0;
13282 $ns = 0;
13283 $pmidtemp = $pmid;
13284
13285 $pmidtemp = preg_replace('/[\\\][\(]/x', '\\#!#OP#!#', $pmidtemp);
13286 $pmidtemp = preg_replace('/[\\\][\)]/x', '\\#!#CP#!#', $pmidtemp);
13287
13288 if (preg_match_all('/\[\(([^\)]*)\)\]/x', $pmidtemp, $lnstring, PREG_PATTERN_ORDER)) {
13289 $maxkk = count($lnstring[1]) - 1;
13290 for ($kk=0; $kk <= $maxkk; ++$kk) {
13291
13292 $lnstring[1][$kk] = str_replace('#!#OP#!#', '(', $lnstring[1][$kk]);
13293 $lnstring[1][$kk] = str_replace('#!#CP#!#', ')', $lnstring[1][$kk]);
13294 if ($kk == $maxkk) {
13295 if ($this->rtl OR $this->tmprtl) {
13296 $tvalue = ltrim($lnstring[1][$kk]);
13297 } else {
13298 $tvalue = rtrim($lnstring[1][$kk]);
13299 }
13300 } else {
13301 $tvalue = $lnstring[1][$kk];
13302 }
13303
13304 $no += substr_count($lnstring[1][$kk], chr(32));
13305 $ns += substr_count($tvalue, chr(32));
13306 }
13307 if ($this->rtl OR $this->tmprtl) {
13308 $t_x = $this->lMargin - $this->endlinex - (($no - $ns - 1) * $this->GetStringWidth(chr(32)));
13309 }
13310
13311 $spacelen = $this->GetStringWidth(chr(32));
13312 $spacewidth = (($tw - $linew + (($no - $ns) * $spacelen)) / ($ns?$ns:1)) * $this->k;
13313 $spacewidthu = -1000 * ($tw - $linew + ($no * $spacelen)) / ($ns?$ns:1) / $this->FontSize;
13314 $nsmax = $ns;
13315 $ns = 0;
13316 reset($lnstring);
13317 $offset = 0;
13318 $strcount = 0;
13319 $prev_epsposbeg = 0;
13320 global $spacew;
13321 while (preg_match('/([0-9\.\+\-]*)[\s](Td|cm|m|l|c|re)[\s]/x', $pmid, $strpiece, PREG_OFFSET_CAPTURE, $offset) == 1) {
13322
13323 $stroffset = strpos($pmid, '[(', $offset);
13324 if (($stroffset !== false) AND ($stroffset <= $strpiece[2][1])) {
13325
13326 $offset = strpos($pmid, ')]', $stroffset);
13327 while (($offset !== false) AND ($pmid{($offset - 1)} == '\\')) {
13328 $offset = strpos($pmid, ')]', ($offset + 1));
13329 }
13330 if ($offset === false) {
13331 $this->Error('HTML Justification: malformed PDF code.');
13332 }
13333 continue;
13334 }
13335 if ($this->rtl OR $this->tmprtl) {
13336 $spacew = ($spacewidth * ($nsmax - $ns));
13337 } else {
13338 $spacew = ($spacewidth * $ns);
13339 }
13340 $offset = $strpiece[2][1] + strlen($strpiece[2][0]);
13341 $epsposbeg = strpos($pmid, 'q'.$this->epsmarker, $offset);
13342 $epsposend = strpos($pmid, $this->epsmarker.'Q', $offset) + strlen($this->epsmarker.'Q');
13343 if ((($epsposbeg > 0) AND ($epsposend > 0) AND ($offset > $epsposbeg) AND ($offset < $epsposend))
13344 OR (($epsposbeg === false) AND ($epsposend > 0) AND ($offset < $epsposend))) {
13345
13346 $trx = sprintf('1 0 0 1 %.3F 0 cm', $spacew);
13347 $epsposbeg = strpos($pmid, 'q'.$this->epsmarker, ($prev_epsposbeg - 6));
13348 $pmid_b = substr($pmid, 0, $epsposbeg);
13349 $pmid_m = substr($pmid, $epsposbeg, ($epsposend - $epsposbeg));
13350 $pmid_e = substr($pmid, $epsposend);
13351 $pmid = $pmid_b."\nq\n".$trx."\n".$pmid_m."\nQ\n".$pmid_e;
13352 $offset = $epsposend;
13353 continue;
13354 }
13355 $prev_epsposbeg = $epsposbeg;
13356 $currentxpos = 0;
13357
13358 switch ($strpiece[2][0]) {
13359 case 'Td':
13360 case 'cm':
13361 case 'm':
13362 case 'l': {
13363
13364 preg_match('/([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', $pmid, $xmatches);
13365 $currentxpos = $xmatches[1];
13366 if (($strcount <= $maxkk) AND ($strpiece[2][0] == 'Td')) {
13367 if ($strcount == $maxkk) {
13368 if ($this->rtl OR $this->tmprtl) {
13369 $tvalue = $lnstring[1][$strcount];
13370 } else {
13371 $tvalue = rtrim($lnstring[1][$strcount]);
13372 }
13373 } else {
13374 $tvalue = $lnstring[1][$strcount];
13375 }
13376 $ns += substr_count($tvalue, chr(32));
13377 ++$strcount;
13378 }
13379 if ($this->rtl OR $this->tmprtl) {
13380 $spacew = ($spacewidth * ($nsmax - $ns));
13381 }
13382
13383 $pmid = preg_replace_callback('/([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x',
13384 create_function('$matches', 'global $spacew;
13385 $newx = sprintf("%.2F",(floatval($matches[1]) + $spacew));
13386 return "".$newx." ".$matches[2]." x*#!#*x".$matches[3].$matches[4];'), $pmid, 1);
13387 break;
13388 }
13389 case 're': {
13390
13391 preg_match('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', $pmid, $xmatches);
13392 $currentxpos = $xmatches[1];
13393
13394 $pmid = preg_replace_callback('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x',
13395 create_function('$matches', 'global $spacew;
13396 $newx = sprintf("%.2F",(floatval($matches[1]) + $spacew));
13397 return "".$newx." ".$matches[2]." ".$matches[3]." ".$matches[4]." x*#!#*x".$matches[5].$matches[6];'), $pmid, 1);
13398 break;
13399 }
13400 case 'c': {
13401
13402 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);
13403 $currentxpos = $xmatches[1];
13404
13405 $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',
13406 create_function('$matches', 'global $spacew;
13407 $newx1 = sprintf("%.3F",(floatval($matches[1]) + $spacew));
13408 $newx2 = sprintf("%.3F",(floatval($matches[3]) + $spacew));
13409 $newx3 = sprintf("%.3F",(floatval($matches[5]) + $spacew));
13410 return "".$newx1." ".$matches[2]." ".$newx2." ".$matches[4]." ".$newx3." ".$matches[6]." x*#!#*x".$matches[7].$matches[8];'), $pmid, 1);
13411 break;
13412 }
13413 }
13414
13415 if (isset($this->PageAnnots[$this->page])) {
13416 foreach ($this->PageAnnots[$this->page] as $pak => $pac) {
13417 if (($pac['y'] >= $minstartliney) AND (($pac['x'] * $this->k) >= ($currentxpos - $this->feps)) AND (($pac['x'] * $this->k) <= ($currentxpos + $this->feps))) {
13418 $this->PageAnnots[$this->page][$pak]['x'] += ($spacew / $this->k);
13419 $this->PageAnnots[$this->page][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k);
13420 break;
13421 }
13422 }
13423 }
13424 }
13425
13426 $pmid = str_replace('x*#!#*x', '', $pmid);
13427 if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
13428
13429 $spacew = $spacewidthu;
13430 $pmidtemp = $pmid;
13431
13432 $pmidtemp = preg_replace('/[\\\][\(]/x', '\\#!#OP#!#', $pmidtemp);
13433 $pmidtemp = preg_replace('/[\\\][\)]/x', '\\#!#CP#!#', $pmidtemp);
13434 $pmid = preg_replace_callback("/\[\(([^\)]*)\)\]/x",
13435 create_function('$matches', 'global $spacew;
13436 $matches[1] = str_replace("#!#OP#!#", "(", $matches[1]);
13437 $matches[1] = str_replace("#!#CP#!#", ")", $matches[1]);
13438 return "[(".str_replace(chr(0).chr(32), ") ".($spacew)." (", $matches[1]).")]";'), $pmidtemp);
13439 $this->setPageBuffer($startlinepage, $pstart."\n".$pmid."\n".$pend);
13440 $endlinepos = strlen($pstart."\n".$pmid."\n");
13441 } else {
13442
13443 $rs = sprintf("%.3F Tw", $spacewidth);
13444 $pmid = preg_replace("/\[\(/x", $rs.' [(', $pmid);
13445 $this->setPageBuffer($startlinepage, $pstart."\n".$pmid."\nBT 0 Tw ET\n".$pend);
13446 $endlinepos = strlen($pstart."\n".$pmid."\nBT 0 Tw ET\n");
13447 }
13448 }
13449 }
13450 if (($t_x != 0) OR ($yshift < 0)) {
13451
13452 $trx = sprintf('1 0 0 1 %.3F %.3F cm', ($t_x * $this->k), ($yshift * $this->k));
13453 $this->setPageBuffer($startlinepage, $pstart."\nq\n".$trx."\n".$pmid."\nQ\n".$pend);
13454 $endlinepos = strlen($pstart."\nq\n".$trx."\n".$pmid."\nQ\n");
13455
13456 if (isset($this->PageAnnots[$this->page])) {
13457 foreach ($this->PageAnnots[$this->page] as $pak => $pac) {
13458 if ($pak >= $pask) {
13459 $this->PageAnnots[$this->page][$pak]['x'] += $t_x;
13460 $this->PageAnnots[$this->page][$pak]['y'] -= $yshift;
13461 }
13462 }
13463 }
13464 $this->y -= $yshift;
13465 }
13466 }
13467 }
13468 $this->newline = false;
13469 $pbrk = $this->checkPageBreak($this->lasth);
13470 $this->SetFont($fontname, $fontstyle, $fontsize);
13471 if ($wfill) {
13472 $this->SetFillColorArray($this->bgcolor);
13473 }
13474 $startlinex = $this->x;
13475 $startliney = $this->y;
13476 $minstartliney = $this->y;
13477 $startlinepage = $this->page;
13478 if (isset($endlinepos) AND (!$pbrk)) {
13479 $startlinepos = $endlinepos;
13480 unset($endlinepos);
13481 } else {
13482 if (isset($this->footerlen[$this->page])) {
13483 $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page];
13484 } else {
13485 $this->footerpos[$this->page] = $this->pagelen[$this->page];
13486 }
13487 $startlinepos = $this->footerpos[$this->page];
13488 }
13489 $plalign = $lalign;
13490 if (isset($this->PageAnnots[$this->page])) {
13491 $pask = count($this->PageAnnots[$this->page]);
13492 } else {
13493 $pask = 0;
13494 }
13495 }
13496 if (isset($opentagpos)) {
13497 unset($opentagpos);
13498 }
13499 if ($dom[$key]['tag']) {
13500 if ($dom[$key]['opening']) {
13501
13502 if (isset($dom[$key]['text-indent']) AND in_array($dom[$key]['value'], array('blockquote','dd','div','dt','h1','h2','h3','h4','h5','h6','li','ol','p','ul','table','tr','td'))) {
13503 $this->textindent = $dom[$key]['text-indent'];
13504 }
13505 if ($dom[$key]['value'] == 'table') {
13506 if ($this->rtl) {
13507 $wtmp = $this->x - $this->lMargin;
13508 } else {
13509 $wtmp = $this->w - $this->rMargin - $this->x;
13510 }
13511 $wtmp -= (2 * $this->cMargin);
13512
13513 if (isset($dom[$key]['width'])) {
13514 $table_width = $this->getHTMLUnitToUnits($dom[$key]['width'], $wtmp, 'px');
13515 } else {
13516 $table_width = $wtmp;
13517 }
13518 }
13519
13520 if (($dom[$key]['value'] == 'td') OR ($dom[$key]['value'] == 'th')) {
13521 $trid = $dom[$key]['parent'];
13522 $table_el = $dom[$trid]['parent'];
13523 if (!isset($dom[$table_el]['cols'])) {
13524 $dom[$table_el]['cols'] = $trid['cols'];
13525 }
13526 $oldmargin = $this->cMargin;
13527 if (isset($dom[($dom[$trid]['parent'])]['attribute']['cellpadding'])) {
13528 $currentcmargin = $this->getHTMLUnitToUnits($dom[($dom[$trid]['parent'])]['attribute']['cellpadding'], 1, 'px');
13529 } else {
13530 $currentcmargin = 0;
13531 }
13532 $this->cMargin = $currentcmargin;
13533 if (isset($dom[($dom[$trid]['parent'])]['attribute']['cellspacing'])) {
13534 $cellspacing = $this->getHTMLUnitToUnits($dom[($dom[$trid]['parent'])]['attribute']['cellspacing'], 1, 'px');
13535 } else {
13536 $cellspacing = 0;
13537 }
13538 if ($this->rtl) {
13539 $cellspacingx = -$cellspacing;
13540 } else {
13541 $cellspacingx = $cellspacing;
13542 }
13543 $colspan = $dom[$key]['attribute']['colspan'];
13544 $wtmp = ($colspan * ($table_width / $dom[$table_el]['cols']));
13545 if (isset($dom[$key]['width'])) {
13546 $cellw = $this->getHTMLUnitToUnits($dom[$key]['width'], $table_width, 'px');
13547 } else {
13548 $cellw = $wtmp;
13549 }
13550 if (isset($dom[$key]['height'])) {
13551
13552 $cellh = $this->getHTMLUnitToUnits($dom[$key]['height'], 0, 'px');
13553 } else {
13554 $cellh = 0;
13555 }
13556 $cellw -= $cellspacing;
13557 if (isset($dom[$key]['content'])) {
13558 $cell_content = $dom[$key]['content'];
13559 } else {
13560 $cell_content = ' ';
13561 }
13562 $tagtype = $dom[$key]['value'];
13563 $parentid = $key;
13564 while (($key < $maxel) AND (!(($dom[$key]['tag']) AND (!$dom[$key]['opening']) AND ($dom[$key]['value'] == $tagtype) AND ($dom[$key]['parent'] == $parentid)))) {
13565
13566 ++$key;
13567 }
13568 if (!isset($dom[$trid]['startpage'])) {
13569 $dom[$trid]['startpage'] = $this->page;
13570 } else {
13571 $this->setPage($dom[$trid]['startpage']);
13572 }
13573 if (!isset($dom[$trid]['starty'])) {
13574 $dom[$trid]['starty'] = $this->y;
13575 } else {
13576 $this->y = $dom[$trid]['starty'];
13577 }
13578 if (!isset($dom[$trid]['startx'])) {
13579 $dom[$trid]['startx'] = $this->x;
13580 }
13581 $this->x += ($cellspacingx / 2);
13582 if (isset($dom[$parentid]['attribute']['rowspan'])) {
13583 $rowspan = intval($dom[$parentid]['attribute']['rowspan']);
13584 } else {
13585 $rowspan = 1;
13586 }
13587
13588 if (isset($dom[$table_el]['rowspans'])) {
13589 $rsk = 0;
13590 $rskmax = count($dom[$table_el]['rowspans']);
13591 while ($rsk < $rskmax) {
13592 $trwsp = $dom[$table_el]['rowspans'][$rsk];
13593 $rsstartx = $trwsp['startx'];
13594 $rsendx = $trwsp['endx'];
13595
13596 if ($trwsp['startpage'] < $this->page) {
13597 if (($this->rtl) AND ($this->pagedim[$this->page]['orm'] != $this->pagedim[$trwsp['startpage']]['orm'])) {
13598 $dl = ($this->pagedim[$this->page]['orm'] - $this->pagedim[$trwsp['startpage']]['orm']);
13599 $rsstartx -= $dl;
13600 $rsendx -= $dl;
13601 } elseif ((!$this->rtl) AND ($this->pagedim[$this->page]['olm'] != $this->pagedim[$trwsp['startpage']]['olm'])) {
13602 $dl = ($this->pagedim[$this->page]['olm'] - $this->pagedim[$trwsp['startpage']]['olm']);
13603 $rsstartx += $dl;
13604 $rsendx += $dl;
13605 }
13606 }
13607 if (($trwsp['rowspan'] > 0)
13608 AND ($rsstartx > ($this->x - $cellspacing - $currentcmargin - $this->feps))
13609 AND ($rsstartx < ($this->x + $cellspacing + $currentcmargin + $this->feps))
13610 AND (($trwsp['starty'] < ($this->y - $this->feps)) OR ($trwsp['startpage'] < $this->page))) {
13611
13612 $this->x = $rsendx + $cellspacingx;
13613 if (($trwsp['rowspan'] == 1)
13614 AND (isset($dom[$trid]['endy']))
13615 AND (isset($dom[$trid]['endpage']))
13616 AND ($trwsp['endpage'] == $dom[$trid]['endpage'])) {
13617
13618 $dom[$table_el]['rowspans'][$rsk]['endy'] = max($dom[$trid]['endy'], $trwsp['endy']);
13619 $dom[$trid]['endy'] = $dom[$table_el]['rowspans'][$rsk]['endy'];
13620 }
13621 $rsk = 0;
13622 } else {
13623 ++$rsk;
13624 }
13625 }
13626 }
13627
13628 if ($rowspan > 1) {
13629 if (isset($this->footerlen[$this->page])) {
13630 $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page];
13631 } else {
13632 $this->footerpos[$this->page] = $this->pagelen[$this->page];
13633 }
13634 $trintmrkpos = $this->footerpos[$this->page];
13635 $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));
13636 }
13637 $cellid = array_push($dom[$trid]['cellpos'], array('startx' => $this->x));
13638 if ($rowspan > 1) {
13639 $dom[$trid]['cellpos'][($cellid - 1)]['rowspanid'] = ($trsid - 1);
13640 }
13641
13642 if (isset($dom[$parentid]['bgcolor']) AND ($dom[$parentid]['bgcolor'] !== false)) {
13643 $dom[$trid]['cellpos'][($cellid - 1)]['bgcolor'] = $dom[$parentid]['bgcolor'];
13644 }
13645 $prevLastH = $this->lasth;
13646
13647 $this->MultiCell($cellw, $cellh, $cell_content, false, $lalign, false, 2, '', '', true, 0, true);
13648 $this->lasth = $prevLastH;
13649 $this->cMargin = $oldmargin;
13650 $dom[$trid]['cellpos'][($cellid - 1)]['endx'] = $this->x;
13651
13652 if ($rowspan <= 1) {
13653 if (isset($dom[$trid]['endy'])) {
13654 if ($this->page == $dom[$trid]['endpage']) {
13655 $dom[$trid]['endy'] = max($this->y, $dom[$trid]['endy']);
13656 } elseif ($this->page > $dom[$trid]['endpage']) {
13657 $dom[$trid]['endy'] = $this->y;
13658 }
13659 } else {
13660 $dom[$trid]['endy'] = $this->y;
13661 }
13662 if (isset($dom[$trid]['endpage'])) {
13663 $dom[$trid]['endpage'] = max($this->page, $dom[$trid]['endpage']);
13664 } else {
13665 $dom[$trid]['endpage'] = $this->page;
13666 }
13667 } else {
13668
13669 $dom[$table_el]['rowspans'][($trsid - 1)]['endx'] = $this->x;
13670 $dom[$table_el]['rowspans'][($trsid - 1)]['endy'] = $this->y;
13671 $dom[$table_el]['rowspans'][($trsid - 1)]['endpage'] = $this->page;
13672 }
13673 if (isset($dom[$table_el]['rowspans'])) {
13674
13675 foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
13676 if ($trwsp['rowspan'] > 0) {
13677 if (isset($dom[$trid]['endpage'])) {
13678 if ($trwsp['endpage'] == $dom[$trid]['endpage']) {
13679 $dom[$table_el]['rowspans'][$k]['endy'] = max($dom[$trid]['endy'], $trwsp['endy']);
13680 } elseif ($trwsp['endpage'] < $dom[$trid]['endpage']) {
13681 $dom[$table_el]['rowspans'][$k]['endy'] = $dom[$trid]['endy'];
13682 $dom[$table_el]['rowspans'][$k]['endpage'] = $dom[$trid]['endpage'];
13683 } else {
13684 $dom[$trid]['endy'] = $this->pagedim[$dom[$trid]['endpage']]['hk'] - $this->pagedim[$dom[$trid]['endpage']]['bm'];
13685 }
13686 }
13687 }
13688 }
13689 }
13690 $this->x += ($cellspacingx / 2);
13691 } else {
13692
13693 if (!isset($opentagpos)) {
13694 if (!$this->InFooter) {
13695 if (isset($this->footerlen[$this->page])) {
13696 $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page];
13697 } else {
13698 $this->footerpos[$this->page] = $this->pagelen[$this->page];
13699 }
13700 $opentagpos = $this->footerpos[$this->page];
13701 }
13702 }
13703 $this->openHTMLTagHandler($dom, $key, $cell);
13704 }
13705 } else {
13706
13707 $this->closeHTMLTagHandler($dom, $key, $cell);
13708 }
13709 } elseif (strlen($dom[$key]['value']) > 0) {
13710
13711 if (!$this->empty_string($this->lispacer)) {
13712 $this->SetFont($pfontname, $pfontstyle, $pfontsize);
13713 $this->lasth = $this->FontSize * $this->cell_height_ratio;
13714 $minstartliney = $this->y;
13715 $this->putHtmlListBullet($this->listnum, $this->lispacer, $pfontsize);
13716 $this->SetFont($curfontname, $curfontstyle, $curfontsize);
13717 $this->lasth = $this->FontSize * $this->cell_height_ratio;
13718 if (is_numeric($pfontsize) AND ($pfontsize > 0) AND is_numeric($curfontsize) AND ($curfontsize > 0) AND ($pfontsize != $curfontsize)) {
13719 $this->y += (($pfontsize - $curfontsize) / $this->k);
13720 $minstartliney = min($this->y, $minstartliney);
13721 }
13722 }
13723
13724 $this->htmlvspace = 0;
13725 if ((!$this->premode) AND ($this->rtl OR $this->tmprtl)) {
13726
13727 $len1 = strlen($dom[$key]['value']);
13728 $lsp = $len1 - strlen(ltrim($dom[$key]['value']));
13729 $rsp = $len1 - strlen(rtrim($dom[$key]['value']));
13730 $tmpstr = '';
13731 if ($rsp > 0) {
13732 $tmpstr .= substr($dom[$key]['value'], -$rsp);
13733 }
13734 $tmpstr .= trim($dom[$key]['value']);
13735 if ($lsp > 0) {
13736 $tmpstr .= substr($dom[$key]['value'], 0, $lsp);
13737 }
13738 $dom[$key]['value'] = $tmpstr;
13739 }
13740 if ($newline) {
13741 if (!$this->premode) {
13742 if (($this->rtl OR $this->tmprtl)) {
13743 $dom[$key]['value'] = rtrim($dom[$key]['value']);
13744 } else {
13745 $dom[$key]['value'] = ltrim($dom[$key]['value']);
13746 }
13747 }
13748 $newline = false;
13749 $firstblock = true;
13750 } else {
13751 $firstblock = false;
13752 }
13753 $strrest = '';
13754 if (!empty($this->HREF) AND (isset($this->HREF['url']))) {
13755
13756 $strrest = $this->addHtmlLink($this->HREF['url'], $dom[$key]['value'], $wfill, true, $this->HREF['color'], $this->HREF['style']);
13757 } else {
13758 $ctmpmargin = $this->cMargin;
13759 $this->cMargin = 0;
13760 if ($this->rtl) {
13761 $this->x -= $this->textindent;
13762 } else {
13763 $this->x += $this->textindent;
13764 }
13765
13766 $strrest = $this->Write($this->lasth, $dom[$key]['value'], '', $wfill, '', false, 0, true, $firstblock);
13767 $this->textindent = 0;
13768 $this->cMargin = $ctmpmargin;
13769 }
13770 if (strlen($strrest) > 0) {
13771
13772 $this->newline = true;
13773 if ($cell) {
13774 if ($this->rtl) {
13775 $this->x -= $this->cMargin;
13776 } else {
13777 $this->x += $this->cMargin;
13778 }
13779 }
13780 if ($strrest == $dom[$key]['value']) {
13781
13782 ++$loop;
13783 } else {
13784 $loop = 0;
13785 }
13786 $dom[$key]['value'] = ltrim($strrest);
13787 if ($loop < 3) {
13788 --$key;
13789 }
13790 } else {
13791 $loop = 0;
13792 }
13793 }
13794 ++$key;
13795 if (isset($dom[$key]['tag']) AND $dom[$key]['tag'] AND (!isset($dom[$key]['opening']) OR !$dom[$key]['opening']) AND isset($dom[($dom[$key]['parent'])]['attribute']['nobr']) AND ($dom[($dom[$key]['parent'])]['attribute']['nobr'] == 'true')) {
13796 if ((!$undo) AND ($this->start_transaction_page == ($this->numpages - 1))) {
13797
13798 $this->rollbackTransaction(true);
13799
13800 foreach ($this_method_vars as $vkey => $vval) {
13801 $$vkey = $vval;
13802 }
13803
13804 $this->AddPage();
13805 $undo = true;
13806 } else {
13807 $undo = false;
13808 }
13809 }
13810 }
13811
13812 if (isset($startlinex)) {
13813 $yshift = $minstartliney - $startliney;
13814 if (($yshift > 0) OR ($this->page > $startlinepage)) {
13815 $yshift = 0;
13816 }
13817 if ((isset($plalign) AND ((($plalign == 'C') OR ($plalign == 'J') OR (($plalign == 'R') AND (!$this->rtl)) OR (($plalign == 'L') AND ($this->rtl))))) OR ($yshift < 0)) {
13818
13819 $linew = abs($this->endlinex - $startlinex);
13820 $pstart = substr($this->getPageBuffer($startlinepage), 0, $startlinepos);
13821 if (isset($opentagpos) AND isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
13822 $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
13823 $midpos = min($opentagpos, $this->footerpos[$startlinepage]);
13824 } elseif (isset($opentagpos)) {
13825 $midpos = $opentagpos;
13826 } elseif (isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
13827 $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
13828 $midpos = $this->footerpos[$startlinepage];
13829 } else {
13830 $midpos = 0;
13831 }
13832 if ($midpos > 0) {
13833 $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos, ($midpos - $startlinepos));
13834 $pend = substr($this->getPageBuffer($startlinepage), $midpos);
13835 } else {
13836 $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos);
13837 $pend = '';
13838 }
13839
13840 $tw = $w;
13841 if ($this->lMargin != $prevlMargin) {
13842 $tw += ($prevlMargin - $this->lMargin);
13843 }
13844 if ($this->rMargin != $prevrMargin) {
13845 $tw += ($prevrMargin - $this->rMargin);
13846 }
13847 $mdiff = abs($tw - $linew);
13848 if ($plalign == 'C') {
13849 if ($this->rtl) {
13850 $t_x = -($mdiff / 2);
13851 } else {
13852 $t_x = ($mdiff / 2);
13853 }
13854 } elseif (($plalign == 'R') AND (!$this->rtl)) {
13855
13856 $t_x = $mdiff;
13857 } elseif (($plalign == 'L') AND ($this->rtl)) {
13858
13859 $t_x = -$mdiff;
13860 } else {
13861 $t_x = 0;
13862 }
13863 if (($t_x != 0) OR ($yshift < 0)) {
13864
13865 $trx = sprintf('1 0 0 1 %.3F %.3F cm', ($t_x * $this->k), ($yshift * $this->k));
13866 $this->setPageBuffer($startlinepage, $pstart."\nq\n".$trx."\n".$pmid."\nQ\n".$pend);
13867 $endlinepos = strlen($pstart."\nq\n".$trx."\n".$pmid."\nQ\n");
13868
13869 if (isset($this->PageAnnots[$this->page])) {
13870 foreach ($this->PageAnnots[$this->page] as $pak => $pac) {
13871 if ($pak >= $pask) {
13872 $this->PageAnnots[$this->page][$pak]['x'] += $t_x;
13873 $this->PageAnnots[$this->page][$pak]['y'] -= $yshift;
13874 }
13875 }
13876 }
13877 $this->y -= $yshift;
13878 }
13879 }
13880 }
13881 if ($ln AND (!($cell AND ($dom[$key-1]['value'] == 'table')))) {
13882 $this->Ln($this->lasth);
13883 }
13884
13885 $this->setGraphicVars($gvars);
13886 if ($this->page > $prevPage) {
13887 $this->lMargin = $this->pagedim[$this->page]['olm'];
13888 $this->rMargin = $this->pagedim[$this->page]['orm'];
13889 }
13890
13891 $this->listnum = $prev_listnum;
13892 $this->listordered = $prev_listordered;
13893 $this->listcount = $prev_listcount;
13894 $this->lispacer = $prev_lispacer;
13895 unset($dom);
13896 }
13897
13905 protected function openHTMLTagHandler(&$dom, $key, $cell=false) {
13906 $tag = $dom[$key];
13907 $parent = $dom[($dom[$key]['parent'])];
13908 $firstorlast = ($key == 1);
13909
13910 if (isset($tag['attribute']['dir'])) {
13911 $this->tmprtl = $tag['attribute']['dir'] == 'rtl' ? 'R' : 'L';
13912 } else {
13913 $this->tmprtl = false;
13914 }
13915
13916 switch($tag['value']) {
13917 case 'table': {
13918 $cp = 0;
13919 $cs = 0;
13920 $dom[$key]['rowspans'] = array();
13921 if (!$this->empty_string($dom[$key]['thead'])) {
13922
13923 $this->thead = $dom[$key]['thead'];
13924 if (!isset($this->theadMargins) OR (empty($this->theadMargins))) {
13925 $this->theadMargins = array();
13926 $this->theadMargins['cmargin'] = $this->cMargin;
13927 }
13928 }
13929 if (isset($tag['attribute']['cellpadding'])) {
13930 $cp = $this->getHTMLUnitToUnits($tag['attribute']['cellpadding'], 1, 'px');
13931 $this->oldcMargin = $this->cMargin;
13932 $this->cMargin = $cp;
13933 }
13934 if (isset($tag['attribute']['cellspacing'])) {
13935 $cs = $this->getHTMLUnitToUnits($tag['attribute']['cellspacing'], 1, 'px');
13936 }
13937 $this->checkPageBreak((2 * $cp) + (2 * $cs) + $this->lasth);
13938 break;
13939 }
13940 case 'tr': {
13941
13942 $dom[$key]['cellpos'] = array();
13943 break;
13944 }
13945 case 'hr': {
13946 $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
13947 $this->htmlvspace = 0;
13948 $wtmp = $this->w - $this->lMargin - $this->rMargin;
13949 if ((isset($tag['attribute']['width'])) AND ($tag['attribute']['width'] != '')) {
13950 $hrWidth = $this->getHTMLUnitToUnits($tag['attribute']['width'], $wtmp, 'px');
13951 } else {
13952 $hrWidth = $wtmp;
13953 }
13954 $x = $this->GetX();
13955 $y = $this->GetY();
13956 $prevlinewidth = $this->GetLineWidth();
13957 $this->Line($x, $y, $x + $hrWidth, $y);
13958 $this->SetLineWidth($prevlinewidth);
13959 $this->addHTMLVertSpace(1, $cell, '', !isset($dom[($key + 1)]), $tag['value'], false);
13960 break;
13961 }
13962 case 'a': {
13963 if (array_key_exists('href', $tag['attribute'])) {
13964 $this->HREF['url'] = $tag['attribute']['href'];
13965 }
13966 $this->HREF['color'] = $this->htmlLinkColorArray;
13967 $this->HREF['style'] = $this->htmlLinkFontStyle;
13968 if (array_key_exists('style', $tag['attribute'])) {
13969
13970 preg_match_all('/([^;:\s]*):([^;]*)/', $tag['attribute']['style'], $style_array, PREG_PATTERN_ORDER);
13971 $astyle = array();
13972 while (list($id, $name) = each($style_array[1])) {
13973 $name = strtolower($name);
13974 $astyle[$name] = trim($style_array[2][$id]);
13975 }
13976 if (isset($astyle['color'])) {
13977 $this->HREF['color'] = $this->convertHTMLColorToDec($astyle['color']);
13978 }
13979 if (isset($astyle['text-decoration'])) {
13980 $this->HREF['style'] = '';
13981 $decors = explode(' ', strtolower($astyle['text-decoration']));
13982 foreach ($decors as $dec) {
13983 $dec = trim($dec);
13984 if (!$this->empty_string($dec)) {
13985 if ($dec{0} == 'u') {
13986 $this->HREF['style'] .= 'U';
13987 } elseif ($dec{0} == 'l') {
13988 $this->HREF['style'] .= 'D';
13989 }
13990 }
13991 }
13992 }
13993 }
13994 break;
13995 }
13996 case 'img': {
13997 if (isset($tag['attribute']['src'])) {
13998
13999 if (($tag['attribute']['src'][0] == '/') AND ($_SERVER['DOCUMENT_ROOT'] != '/')) {
14000 $tag['attribute']['src'] = $_SERVER['DOCUMENT_ROOT'].$tag['attribute']['src'];
14001 }
14002 $tag['attribute']['src'] = urldecode($tag['attribute']['src']);
14003 $tag['attribute']['src'] = str_replace(K_PATH_URL, K_PATH_MAIN, $tag['attribute']['src']);
14004 if (!isset($tag['attribute']['width'])) {
14005 $tag['attribute']['width'] = 0;
14006 }
14007 if (!isset($tag['attribute']['height'])) {
14008 $tag['attribute']['height'] = 0;
14009 }
14010
14011
14012
14013 $tag['attribute']['align'] = 'bottom';
14014
14015 switch($tag['attribute']['align']) {
14016 case 'top': {
14017 $align = 'T';
14018 break;
14019 }
14020 case 'middle': {
14021 $align = 'M';
14022 break;
14023 }
14024 case 'bottom': {
14025 $align = 'B';
14026 break;
14027 }
14028 default: {
14029 $align = 'B';
14030 break;
14031 }
14032 }
14033 $fileinfo = pathinfo($tag['attribute']['src']);
14034 if (isset($fileinfo['extension']) AND (!$this->empty_string($fileinfo['extension']))) {
14035 $type = strtolower($fileinfo['extension']);
14036 }
14037 $prevy = $this->y;
14038 $xpos = $this->GetX();
14039 if (isset($dom[($key - 1)]) AND ($dom[($key - 1)]['value'] == ' ')) {
14040 if ($this->rtl) {
14041 $xpos += $this->GetStringWidth(' ');
14042 } else {
14043 $xpos -= $this->GetStringWidth(' ');
14044 }
14045 }
14046 $imglink = '';
14047 if (isset($this->HREF['url']) AND !$this->empty_string($this->HREF['url'])) {
14048 $imglink = $this->HREF['url'];
14049 if ($imglink{0} == '#') {
14050
14051 $page = intval(substr($imglink, 1));
14052 $imglink = $this->AddLink();
14053 $this->SetLink($imglink, 0, $page);
14054 }
14055 }
14056 $border = 0;
14057 if (isset($tag['attribute']['border']) AND !empty($tag['attribute']['border'])) {
14058
14059 $border = $tag['attribute']['border'];
14060 }
14061 $iw = '';
14062 if (isset($tag['attribute']['width'])) {
14063 $iw = $this->getHTMLUnitToUnits($tag['attribute']['width'], 1, 'px', false);
14064 }
14065 $ih = '';
14066 if (isset($tag['attribute']['height'])) {
14067 $ih = $this->getHTMLUnitToUnits($tag['attribute']['height'], 1, 'px', false);
14068 }
14069 if (($type == 'eps') OR ($type == 'ai')) {
14070 $this->ImageEps($tag['attribute']['src'], $xpos, $this->GetY(), $iw, $ih, $imglink, true, $align, '', $border);
14071 } else {
14072 $this->Image($tag['attribute']['src'], $xpos, $this->GetY(), $iw, $ih, '', $imglink, $align, false, 300, '', false, false, $border);
14073 }
14074 switch($align) {
14075 case 'T': {
14076 $this->y = $prevy;
14077 break;
14078 }
14079 case 'M': {
14080 $this->y = (($this->img_rb_y + $prevy - ($tag['fontsize'] / $this->k)) / 2) ;
14081 break;
14082 }
14083 case 'B': {
14084 $this->y = $this->img_rb_y - ($tag['fontsize'] / $this->k);
14085 break;
14086 }
14087 }
14088 }
14089 break;
14090 }
14091 case 'dl': {
14092 ++$this->listnum;
14093 $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], false);
14094 break;
14095 }
14096 case 'dt': {
14097 $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
14098 break;
14099 }
14100 case 'dd': {
14101 if ($this->rtl) {
14102 $this->rMargin += $this->listindent;
14103 } else {
14104 $this->lMargin += $this->listindent;
14105 }
14106 $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
14107 break;
14108 }
14109 case 'ul':
14110 case 'ol': {
14111 $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], false);
14112 $this->htmlvspace = 0;
14113 ++$this->listnum;
14114 if ($tag['value'] == 'ol') {
14115 $this->listordered[$this->listnum] = true;
14116 } else {
14117 $this->listordered[$this->listnum] = false;
14118 }
14119 if (isset($tag['attribute']['start'])) {
14120 $this->listcount[$this->listnum] = intval($tag['attribute']['start']) - 1;
14121 } else {
14122 $this->listcount[$this->listnum] = 0;
14123 }
14124 if ($this->rtl) {
14125 $this->rMargin += $this->listindent;
14126 } else {
14127 $this->lMargin += $this->listindent;
14128 }
14129 $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], false);
14130 $this->htmlvspace = 0;
14131 break;
14132 }
14133 case 'li': {
14134 $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
14135 if ($this->listordered[$this->listnum]) {
14136
14137 if (isset($parent['attribute']['type']) AND !$this->empty_string($parent['attribute']['type'])) {
14138 $this->lispacer = $parent['attribute']['type'];
14139 } elseif (isset($parent['listtype']) AND !$this->empty_string($parent['listtype'])) {
14140 $this->lispacer = $parent['listtype'];
14141 } elseif (isset($this->lisymbol) AND !$this->empty_string($this->lisymbol)) {
14142 $this->lispacer = $this->lisymbol;
14143 } else {
14144 $this->lispacer = '#';
14145 }
14146 ++$this->listcount[$this->listnum];
14147 if (isset($tag['attribute']['value'])) {
14148 $this->listcount[$this->listnum] = intval($tag['attribute']['value']);
14149 }
14150 } else {
14151
14152 if (isset($parent['attribute']['type']) AND !$this->empty_string($parent['attribute']['type'])) {
14153 $this->lispacer = $parent['attribute']['type'];
14154 } elseif (isset($parent['listtype']) AND !$this->empty_string($parent['listtype'])) {
14155 $this->lispacer = $parent['listtype'];
14156 } elseif (isset($this->lisymbol) AND !$this->empty_string($this->lisymbol)) {
14157 $this->lispacer = $this->lisymbol;
14158 } else {
14159 $this->lispacer = '!';
14160 }
14161 }
14162 break;
14163 }
14164 case 'blockquote': {
14165 if ($this->rtl) {
14166 $this->rMargin += $this->listindent;
14167 } else {
14168 $this->lMargin += $this->listindent;
14169 }
14170 $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], false);
14171 break;
14172 }
14173 case 'br': {
14174 $this->Ln('', $cell);
14175 break;
14176 }
14177 case 'div': {
14178 $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
14179 break;
14180 }
14181 case 'p': {
14182 $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], false);
14183 break;
14184 }
14185 case 'pre': {
14186 $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
14187 $this->premode = true;
14188 break;
14189 }
14190 case 'sup': {
14191 $this->SetXY($this->GetX(), $this->GetY() - ((0.7 * $this->FontSizePt) / $this->k));
14192 break;
14193 }
14194 case 'sub': {
14195 $this->SetXY($this->GetX(), $this->GetY() + ((0.3 * $this->FontSizePt) / $this->k));
14196 break;
14197 }
14198 case 'h1':
14199 case 'h2':
14200 case 'h3':
14201 case 'h4':
14202 case 'h5':
14203 case 'h6': {
14204 $this->addHTMLVertSpace(1, $cell, ($tag['fontsize'] * 1.5) / $this->k, $firstorlast, $tag['value'], false);
14205 break;
14206 }
14207
14208 case 'form': {
14209 if (isset($tag['attribute']['action'])) {
14210 $this->form_action = $tag['attribute']['action'];
14211 } else {
14212 $this->form_action = K_PATH_URL.$_SERVER['SCRIPT_NAME'];
14213 }
14214 if (isset($tag['attribute']['enctype'])) {
14215 $this->form_enctype = $tag['attribute']['enctype'];
14216 } else {
14217 $this->form_enctype = 'application/x-www-form-urlencoded';
14218 }
14219 if (isset($tag['attribute']['method'])) {
14220 $this->form_mode = $tag['attribute']['method'];
14221 } else {
14222 $this->form_mode = 'post';
14223 }
14224 break;
14225 }
14226 case 'input': {
14227 if (isset($tag['attribute']['name']) AND !$this->empty_string($tag['attribute']['name'])) {
14228 $name = $tag['attribute']['name'];
14229 } else {
14230 break;
14231 }
14232 $prop = array();
14233 $opt = array();
14234 if (isset($tag['attribute']['value']) AND !$this->empty_string($tag['attribute']['value'])) {
14235 $value = $tag['attribute']['value'];
14236 }
14237 if (isset($tag['attribute']['maxlength']) AND !$this->empty_string($tag['attribute']['maxlength'])) {
14238 $opt['maxlen'] = intval($tag['attribute']['value']);
14239 }
14240 $h = $this->FontSize * $this->cell_height_ratio;
14241 if (isset($tag['attribute']['size']) AND !$this->empty_string($tag['attribute']['size'])) {
14242 $w = intval($tag['attribute']['size']) * $this->GetStringWidth(chr(32)) * 2;
14243 } else {
14244 $w = $h;
14245 }
14246 if (isset($tag['attribute']['checked']) AND (($tag['attribute']['checked'] == 'checked') OR ($tag['attribute']['checked'] == 'true'))) {
14247 $checked = true;
14248 } else {
14249 $checked = false;
14250 }
14251 switch ($tag['attribute']['type']) {
14252 case 'text': {
14253 if (isset($value)) {
14254 $opt['v'] = $value;
14255 }
14256 $this->TextField($name, $w, $h, $prop, $opt, '', '', false);
14257 break;
14258 }
14259 case 'password': {
14260 if (isset($value)) {
14261 $opt['v'] = $value;
14262 }
14263 $prop['password'] = 'true';
14264 $this->TextField($name, $w, $h, $prop, $opt, '', '', false);
14265 break;
14266 }
14267 case 'checkbox': {
14268 $this->CheckBox($name, $w, $checked, $prop, $opt, $value, '', '', false);
14269 break;
14270 }
14271 case 'radio': {
14272 $this->RadioButton($name, $w, $prop, $opt, $value, $checked, '', '', false);
14273 break;
14274 }
14275 case 'submit': {
14276 $w = $this->GetStringWidth($value) * 1.5;
14277 $h *= 1.6;
14278 $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
14279 $action = array();
14280 $action['S'] = 'SubmitForm';
14281 $action['F'] = $this->form_action;
14282 if ($this->form_enctype != 'FDF') {
14283 $action['Flags'] = array('ExportFormat');
14284 }
14285 if ($this->form_mode == 'get') {
14286 $action['Flags'] = array('GetMethod');
14287 }
14288 $this->Button($name, $w, $h, $value, $action, $prop, $opt, '', '', false);
14289 break;
14290 }
14291 case 'reset': {
14292 $w = $this->GetStringWidth($value) * 1.5;
14293 $h *= 1.6;
14294 $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
14295 $this->Button($name, $w, $h, $value, array('S'=>'ResetForm'), $prop, $opt, '', '', false);
14296 break;
14297 }
14298 case 'file': {
14299 $prop['fileSelect'] = 'true';
14300 $this->TextField($name, $w, $h, $prop, $opt, '', '', false);
14301 if (!isset($value)) {
14302 $value = '*';
14303 }
14304 $w = $this->GetStringWidth($value) * 2;
14305 $h *= 1.2;
14306 $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
14307 $jsaction = 'var f=this.getField(\''.$name.'\'); f.browseForFileToSubmit();';
14308 $this->Button('FB_'.$name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false);
14309 break;
14310 }
14311 case 'hidden': {
14312 if (isset($value)) {
14313 $opt['v'] = $value;
14314 }
14315 $opt['f'] = array('invisible', 'hidden');
14316 $this->TextField($name, 0, 0, $prop, $opt, '', '', false);
14317 break;
14318 }
14319 case 'image': {
14320 // THIS TYPE MUST BE FIXED
14321 if (isset($tag['attribute']['src']) AND !$this->empty_string($tag['attribute']['src'])) {
14322 $img = $tag['attribute']['src'];
14323 } else {
14324 break;
14325 }
14326 $value = 'img';
14327 //$opt['mk'] = array('i'=>$img, 'tp'=>1, 'if'=>array('sw'=>'A', 's'=>'A', 'fb'=>false));
14328 if (isset($tag['attribute']['onclick']) AND !empty($tag['attribute']['onclick'])) {
14329 $jsaction = $tag['attribute']['onclick'];
14330 } else {
14331 $jsaction = '';
14332 }
14333 $this->Button($name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false);
14334 break;
14335 }
14336 case 'button': {
14337 $w = $this->GetStringWidth($value) * 1.5;
14338 $h *= 1.6;
14339 $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
14340 if (isset($tag['attribute']['onclick']) AND !empty($tag['attribute']['onclick'])) {
14341 $jsaction = $tag['attribute']['onclick'];
14342 } else {
14343 $jsaction = '';
14344 }
14345 $this->Button($name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false);
14346 break;
14347 }
14348 }
14349 break;
14350 }
14351 case 'textarea': {
14352 $prop = array();
14353 $opt = array();
14354 if (isset($tag['attribute']['name']) AND !$this->empty_string($tag['attribute']['name'])) {
14355 $name = $tag['attribute']['name'];
14356 } else {
14357 break;
14358 }
14359 if (isset($tag['attribute']['value']) AND !$this->empty_string($tag['attribute']['value'])) {
14360 $opt['v'] = $tag['attribute']['value'];
14361 }
14362 if (isset($tag['attribute']['cols']) AND !$this->empty_string($tag['attribute']['cols'])) {
14363 $w = intval($tag['attribute']['cols']) * $this->GetStringWidth(chr(32)) * 2;
14364 } else {
14365 $w = 40;
14366 }
14367 if (isset($tag['attribute']['rows']) AND !$this->empty_string($tag['attribute']['rows'])) {
14368 $h = intval($tag['attribute']['rows']) * $this->FontSize * $this->cell_height_ratio;
14369 } else {
14370 $h = 10;
14371 }
14372 $prop['multiline'] = 'true';
14373 $this->TextField($name, $w, $h, $prop, $opt, '', '', false);
14374 break;
14375 }
14376 case 'select': {
14377 $h = $this->FontSize * $this->cell_height_ratio;
14378 if (isset($tag['attribute']['size']) AND !$this->empty_string($tag['attribute']['size'])) {
14379 $h *= ($tag['attribute']['size'] + 1);
14380 }
14381 $prop = array();
14382 $opt = array();
14383 if (isset($tag['attribute']['name']) AND !$this->empty_string($tag['attribute']['name'])) {
14384 $name = $tag['attribute']['name'];
14385 } else {
14386 break;
14387 }
14388 $w = 0;
14389 if (isset($tag['attribute']['opt']) AND !$this->empty_string($tag['attribute']['opt'])) {
14390 $options = explode ("\r", $tag['attribute']['opt']);
14391 $values = array();
14392 foreach ($options as $val) {
14393 if (strpos($val, "\t") !== false) {
14394 $opts = explode("\t", $val);
14395 $values[] = $opts;
14396 $w = max($w, $this->GetStringWidth($opts[1]));
14397 } else {
14398 $values[] = $val;
14399 $w = max($w, $this->GetStringWidth($val));
14400 }
14401 }
14402 } else {
14403 break;
14404 }
14405 $w *= 2;
14406 if (isset($tag['attribute']['multiple']) AND ($tag['attribute']['multiple']='multiple')) {
14407 $prop['multipleSelection'] = 'true';
14408 $this->ListBox($name, $w, $h, $values, $prop, $opt, '', '', false);
14409 } else {
14410 $this->ComboBox($name, $w, $h, $values, $prop, $opt, '', '', false);
14411 }
14412 break;
14413 }
14414 case 'tcpdf': {
14415 // NOT HTML: used to call TCPDF methods
14416 if (isset($tag['attribute']['method'])) {
14417 $tcpdf_method = $tag['attribute']['method'];
14418 if (method_exists($this, $tcpdf_method)) {
14419 if (isset($tag['attribute']['params']) AND (!empty($tag['attribute']['params']))) {
14420 eval('$params = array('.$this->unhtmlentities($tag['attribute']['params']).');');
14421 call_user_func_array(array($this, $tcpdf_method), $params);
14422 } else {
14423 $this->$tcpdf_method();
14424 }
14425 $this->newline = true;
14426 }
14427 }
14428 }
14429 default: {
14430 break;
14431 }
14432 }
14433 }
14434
14442 protected function closeHTMLTagHandler(&$dom, $key, $cell=false) {
14443 $tag = $dom[$key];
14444 $parent = $dom[($dom[$key]['parent'])];
14445 $firstorlast = ((!isset($dom[($key + 1)])) OR ((!isset($dom[($key + 2)])) AND ($dom[($key + 1)]['value'] == 'marker')));
14446 $in_table_head = false;
14447 //Closing tag
14448 switch($tag['value']) {
14449 case 'tr': {
14450 $table_el = $dom[($dom[$key]['parent'])]['parent'];
14451 if(!isset($parent['endy'])) {
14452 $dom[($dom[$key]['parent'])]['endy'] = $this->y;
14453 $parent['endy'] = $this->y;
14454 }
14455 if(!isset($parent['endpage'])) {
14456 $dom[($dom[$key]['parent'])]['endpage'] = $this->page;
14457 $parent['endpage'] = $this->page;
14458 }
14459 // update row-spanned cells
14460 if (isset($dom[$table_el]['rowspans'])) {
14461 foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
14462 $dom[$table_el]['rowspans'][$k]['rowspan'] -= 1;
14463 if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) {
14464 if ($dom[$table_el]['rowspans'][$k]['endpage'] == $parent['endpage']) {
14465 $dom[($dom[$key]['parent'])]['endy'] = max($dom[$table_el]['rowspans'][$k]['endy'], $parent['endy']);
14466 } elseif ($dom[$table_el]['rowspans'][$k]['endpage'] > $parent['endpage']) {
14467 $dom[($dom[$key]['parent'])]['endy'] = $dom[$table_el]['rowspans'][$k]['endy'];
14468 $dom[($dom[$key]['parent'])]['endpage'] = $dom[$table_el]['rowspans'][$k]['endpage'];
14469 }
14470 }
14471 }
14472 // report new endy and endpage to the rowspanned cells
14473 foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
14474 if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) {
14475 $dom[$table_el]['rowspans'][$k]['endpage'] = max($dom[$table_el]['rowspans'][$k]['endpage'], $dom[($dom[$key]['parent'])]['endpage']);
14476 $dom[($dom[$key]['parent'])]['endpage'] = $dom[$table_el]['rowspans'][$k]['endpage'];
14477 $dom[$table_el]['rowspans'][$k]['endy'] = max($dom[$table_el]['rowspans'][$k]['endy'], $dom[($dom[$key]['parent'])]['endy']);
14478 $dom[($dom[$key]['parent'])]['endy'] = $dom[$table_el]['rowspans'][$k]['endy'];
14479 }
14480 }
14481 // update remaining rowspanned cells
14482 foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
14483 if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) {
14484 $dom[$table_el]['rowspans'][$k]['endpage'] = $dom[($dom[$key]['parent'])]['endpage'];
14485 $dom[$table_el]['rowspans'][$k]['endy'] = $dom[($dom[$key]['parent'])]['endy'];
14486 }
14487 }
14488 }
14489 $this->setPage($dom[($dom[$key]['parent'])]['endpage']);
14490 $this->y = $dom[($dom[$key]['parent'])]['endy'];
14491 if (isset($dom[$table_el]['attribute']['cellspacing'])) {
14492 $cellspacing = $this->getHTMLUnitToUnits($dom[$table_el]['attribute']['cellspacing'], 1, 'px');
14493 $this->y += $cellspacing;
14494 }
14495 $this->Ln(0, $cell);
14496 $this->x = $parent['startx'];
14497 // account for booklet mode
14498 if ($this->page > $parent['startpage']) {
14499 if (($this->rtl) AND ($this->pagedim[$this->page]['orm'] != $this->pagedim[$parent['startpage']]['orm'])) {
14500 $this->x += ($this->pagedim[$this->page]['orm'] - $this->pagedim[$parent['startpage']]['orm']);
14501 } elseif ((!$this->rtl) AND ($this->pagedim[$this->page]['olm'] != $this->pagedim[$parent['startpage']]['olm'])) {
14502 $this->x += ($this->pagedim[$this->page]['olm'] - $this->pagedim[$parent['startpage']]['olm']);
14503 }
14504 }
14505 break;
14506 }
14507 case 'tablehead':
14508 // closing tag used for the thead part
14509 $in_table_head = true;
14510 case 'table': {
14511 // draw borders
14512 $table_el = $parent;
14513 if ((isset($table_el['attribute']['border']) AND ($table_el['attribute']['border'] > 0))
14514 OR (isset($table_el['style']['border']) AND ($table_el['style']['border'] > 0))) {
14515 $border = 1;
14516 } else {
14517 $border = 0;
14518 }
14519 // fix bottom line alignment of last line before page break
14520 foreach ($dom[($dom[$key]['parent'])]['trids'] as $j => $trkey) {
14521 // update row-spanned cells
14522 if (isset($dom[($dom[$key]['parent'])]['rowspans'])) {
14523 foreach ($dom[($dom[$key]['parent'])]['rowspans'] as $k => $trwsp) {
14524 if ($trwsp['trid'] == $trkey) {
14525 $dom[($dom[$key]['parent'])]['rowspans'][$k]['mrowspan'] -= 1;
14526 }
14527 if (isset($prevtrkey) AND ($trwsp['trid'] == $prevtrkey) AND ($trwsp['mrowspan'] >= 0)) {
14528 $dom[($dom[$key]['parent'])]['rowspans'][$k]['trid'] = $trkey;
14529 }
14530 }
14531 }
14532 if (isset($prevtrkey) AND ($dom[$trkey]['startpage'] > $dom[$prevtrkey]['endpage'])) {
14533 $pgendy = $this->pagedim[$dom[$prevtrkey]['endpage']]['hk'] - $this->pagedim[$dom[$prevtrkey]['endpage']]['bm'];
14534 $dom[$prevtrkey]['endy'] = $pgendy;
14535 // update row-spanned cells
14536 if (isset($dom[($dom[$key]['parent'])]['rowspans'])) {
14537 foreach ($dom[($dom[$key]['parent'])]['rowspans'] as $k => $trwsp) {
14538 if (($trwsp['trid'] == $trkey) AND ($trwsp['mrowspan'] == 1) AND ($trwsp['endpage'] == $dom[$prevtrkey]['endpage'])) {
14539 $dom[($dom[$key]['parent'])]['rowspans'][$k]['endy'] = $pgendy;
14540 $dom[($dom[$key]['parent'])]['rowspans'][$k]['mrowspan'] = -1;
14541 }
14542 }
14543 }
14544 }
14545 $prevtrkey = $trkey;
14546 $table_el = $dom[($dom[$key]['parent'])];
14547 }
14548 // for each row
14549 foreach ($table_el['trids'] as $j => $trkey) {
14550 $parent = $dom[$trkey];
14551 // for each cell on the row
14552 foreach ($parent['cellpos'] as $k => $cellpos) {
14553 if (isset($cellpos['rowspanid']) AND ($cellpos['rowspanid'] >= 0)) {
14554 $cellpos['startx'] = $table_el['rowspans'][($cellpos['rowspanid'])]['startx'];
14555 $cellpos['endx'] = $table_el['rowspans'][($cellpos['rowspanid'])]['endx'];
14556 $endy = $table_el['rowspans'][($cellpos['rowspanid'])]['endy'];
14557 $startpage = $table_el['rowspans'][($cellpos['rowspanid'])]['startpage'];
14558 $endpage = $table_el['rowspans'][($cellpos['rowspanid'])]['endpage'];
14559 } else {
14560 $endy = $parent['endy'];
14561 $startpage = $parent['startpage'];
14562 $endpage = $parent['endpage'];
14563 }
14564 if ($endpage > $startpage) {
14565 // design borders around HTML cells.
14566 for ($page=$startpage; $page <= $endpage; ++$page) {
14567 $this->setPage($page);
14568 if ($page == $startpage) {
14569 $this->y = $parent['starty']; // put cursor at the beginning of row on the first page
14570 $ch = $this->getPageHeight() - $parent['starty'] - $this->getBreakMargin();
14571 $cborder = $this->getBorderMode($border, $position='start');
14572 } elseif ($page == $endpage) {
14573 $this->y = $this->tMargin; // put cursor at the beginning of last page
14574 $ch = $endy - $this->tMargin;
14575 $cborder = $this->getBorderMode($border, $position='end');
14576 } else {
14577 $this->y = $this->tMargin; // put cursor at the beginning of the current page
14578 $ch = $this->getPageHeight() - $this->tMargin - $this->getBreakMargin();
14579 $cborder = $this->getBorderMode($border, $position='middle');
14580 }
14581 if (isset($cellpos['bgcolor']) AND ($cellpos['bgcolor']) !== false) {
14582 $this->SetFillColorArray($cellpos['bgcolor']);
14583 $fill = true;
14584 } else {
14585 $fill = false;
14586 }
14587 $cw = abs($cellpos['endx'] - $cellpos['startx']);
14588 $this->x = $cellpos['startx'];
14589 // account for margin changes
14590 if ($page > $startpage) {
14591 if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) {
14592 $this->x -= ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']);
14593 } elseif ((!$this->rtl) AND ($this->pagedim[$page]['lm'] != $this->pagedim[$startpage]['olm'])) {
14594 $this->x += ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']);
14595 }
14596 }
14597 // design a cell around the text
14598 $ccode = $this->FillColor."\n".$this->getCellCode($cw, $ch, '', $cborder, 1, '', $fill, '', 0, true);
14599 if ($cborder OR $fill) {
14600 $pagebuff = $this->getPageBuffer($this->page);
14601 $pstart = substr($pagebuff, 0, $this->intmrk[$this->page]);
14602 $pend = substr($pagebuff, $this->intmrk[$this->page]);
14603 $this->setPageBuffer($this->page, $pstart.$ccode."\n".$pend);
14604 $this->intmrk[$this->page] += strlen($ccode."\n");
14605 }
14606 }
14607 } else {
14608 $this->setPage($startpage);
14609 if (isset($cellpos['bgcolor']) AND ($cellpos['bgcolor']) !== false) {
14610 $this->SetFillColorArray($cellpos['bgcolor']);
14611 $fill = true;
14612 } else {
14613 $fill = false;
14614 }
14615 $this->x = $cellpos['startx'];
14616 $this->y = $parent['starty'];
14617 $cw = abs($cellpos['endx'] - $cellpos['startx']);
14618 $ch = $endy - $parent['starty'];
14619 // design a cell around the text
14620 $ccode = $this->FillColor."\n".$this->getCellCode($cw, $ch, '', $border, 1, '', $fill, '', 0, true);
14621 if ($border OR $fill) {
14622 if (end($this->transfmrk[$this->page]) !== false) {
14623 $pagemarkkey = key($this->transfmrk[$this->page]);
14624 $pagemark = &$this->transfmrk[$this->page][$pagemarkkey];
14625 } elseif ($this->InFooter) {
14626 $pagemark = &$this->footerpos[$this->page];
14627 } else {
14628 $pagemark = &$this->intmrk[$this->page];
14629 }
14630 $pagebuff = $this->getPageBuffer($this->page);
14631 $pstart = substr($pagebuff, 0, $pagemark);
14632 $pend = substr($pagebuff, $pagemark);
14633 $this->setPageBuffer($this->page, $pstart.$ccode."\n".$pend);
14634 $pagemark += strlen($ccode."\n");
14635 }
14636 }
14637 }
14638 if (isset($table_el['attribute']['cellspacing'])) {
14639 $cellspacing = $this->getHTMLUnitToUnits($table_el['attribute']['cellspacing'], 1, 'px');
14640 $this->y += $cellspacing;
14641 }
14642 $this->Ln(0, $cell);
14643 $this->x = $parent['startx'];
14644 if ($endpage > $startpage) {
14645 if (($this->rtl) AND ($this->pagedim[$endpage]['orm'] != $this->pagedim[$startpage]['orm'])) {
14646 $this->x += ($this->pagedim[$endpage]['orm'] - $this->pagedim[$startpage]['orm']);
14647 } elseif ((!$this->rtl) AND ($this->pagedim[$endpage]['olm'] != $this->pagedim[$startpage]['olm'])) {
14648 $this->x += ($this->pagedim[$endpage]['olm'] - $this->pagedim[$startpage]['olm']);
14649 }
14650 }
14651 }
14652 if (!$in_table_head) {
14653 // we are not inside a thead section
14654 if (isset($parent['cellpadding'])) {
14655 $this->cMargin = $this->oldcMargin;
14656 }
14657 $this->lasth = $this->FontSize * $this->cell_height_ratio;
14658 if (isset($this->theadMargins['top'])) {
14659 // restore top margin
14660 $this->tMargin = $this->theadMargins['top'];
14661 $this->pagedim[$this->page]['tm'] = $this->tMargin;
14662 }
14663 // reset table header
14664 $this->thead = '';
14665 $this->theadMargins = array();
14666 }
14667 break;
14668 }
14669 case 'a': {
14670 $this->HREF = '';
14671 break;
14672 }
14673 case 'sup': {
14674 $this->SetXY($this->GetX(), $this->GetY() + ((0.7 * $parent['fontsize']) / $this->k));
14675 break;
14676 }
14677 case 'sub': {
14678 $this->SetXY($this->GetX(), $this->GetY() - ((0.3 * $parent['fontsize'])/$this->k));
14679 break;
14680 }
14681 case 'div': {
14682 $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], true);
14683 break;
14684 }
14685 case 'blockquote': {
14686 if ($this->rtl) {
14687 $this->rMargin -= $this->listindent;
14688 } else {
14689 $this->lMargin -= $this->listindent;
14690 }
14691 $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], true);
14692 break;
14693 }
14694 case 'p': {
14695 $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], true);
14696 break;
14697 }
14698 case 'pre': {
14699 $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], true);
14700 $this->premode = false;
14701 break;
14702 }
14703 case 'dl': {
14704 --$this->listnum;
14705 if ($this->listnum <= 0) {
14706 $this->listnum = 0;
14707 $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], true);
14708 }
14709 break;
14710 }
14711 case 'dt': {
14712 $this->lispacer = '';
14713 $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], true);
14714 break;
14715 }
14716 case 'dd': {
14717 $this->lispacer = '';
14718 if ($this->rtl) {
14719 $this->rMargin -= $this->listindent;
14720 } else {
14721 $this->lMargin -= $this->listindent;
14722 }
14723 $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], true);
14724 break;
14725 }
14726 case 'ul':
14727 case 'ol': {
14728 --$this->listnum;
14729 $this->lispacer = '';
14730 if ($this->rtl) {
14731 $this->rMargin -= $this->listindent;
14732 } else {
14733 $this->lMargin -= $this->listindent;
14734 }
14735 if ($this->listnum <= 0) {
14736 $this->listnum = 0;
14737 $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], true);
14738 }
14739 $this->lasth = $this->FontSize * $this->cell_height_ratio;
14740 break;
14741 }
14742 case 'li': {
14743 $this->lispacer = '';
14744 $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], true);
14745 break;
14746 }
14747 case 'h1':
14748 case 'h2':
14749 case 'h3':
14750 case 'h4':
14751 case 'h5':
14752 case 'h6': {
14753 $this->addHTMLVertSpace(1, $cell, ($parent['fontsize'] * 1.5) / $this->k, $firstorlast, $tag['value'], true);
14754 break;
14755 }
14756 // Form fields (since 4.8.000 - 2009-09-07)
14757 case 'form': {
14758 $this->form_action = '';
14759 $this->form_enctype = 'application/x-www-form-urlencoded';
14760 break;
14761 }
14762 default : {
14763 break;
14764 }
14765 }
14766 $this->tmprtl = false;
14767 }
14768
14779 protected function addHTMLVertSpace($n, $cell=false, $h='', $firstorlast=false, $tag='', $closing=false) {
14780 if ($firstorlast) {
14781 $this->Ln(0, $cell);
14782 $this->htmlvspace = 0;
14783 return;
14784 }
14785 if (isset($this->tagvspaces[$tag][intval($closing)]['n'])) {
14786 $n = $this->tagvspaces[$tag][intval($closing)]['n'];
14787 }
14788 if (isset($this->tagvspaces[$tag][intval($closing)]['h'])) {
14789 $h = $this->tagvspaces[$tag][intval($closing)]['h'];
14790 }
14791 if (is_string($h)) {
14792 $vsize = $n * $this->lasth;
14793 } else {
14794 $vsize = $n * $h;
14795 }
14796 if ($vsize > $this->htmlvspace) {
14797 $this->Ln(($vsize - $this->htmlvspace), $cell);
14798 $this->htmlvspace = $vsize;
14799 }
14800 }
14801
14808 public function setLIsymbol($symbol='!') {
14809 $symbol = strtolower($symbol);
14810 switch ($symbol) {
14811 case '!' :
14812 case '#' :
14813 case 'disc' :
14814 case 'disc' :
14815 case 'circle' :
14816 case 'square' :
14817 case '1':
14818 case 'decimal':
14819 case 'decimal-leading-zero':
14820 case 'i':
14821 case 'lower-roman':
14822 case 'I':
14823 case 'upper-roman':
14824 case 'a':
14825 case 'lower-alpha':
14826 case 'lower-latin':
14827 case 'A':
14828 case 'upper-alpha':
14829 case 'upper-latin':
14830 case 'lower-greek': {
14831 $this->lisymbol = $symbol;
14832 break;
14833 }
14834 default : {
14835 $this->lisymbol = '';
14836 }
14837 }
14838 }
14839
14848 public function SetBooklet($booklet=true, $inner=-1, $outer=-1) {
14849 $this->booklet = $booklet;
14850 if ($inner >= 0) {
14851 $this->lMargin = $inner;
14852 }
14853 if ($outer >= 0) {
14854 $this->rMargin = $outer;
14855 }
14856 }
14857
14864 protected function swapMargins($reverse=true) {
14865 if ($reverse) {
14866 // swap left and right margins
14867 $mtemp = $this->original_lMargin;
14868 $this->original_lMargin = $this->original_rMargin;
14869 $this->original_rMargin = $mtemp;
14870 $deltam = $this->original_lMargin - $this->original_rMargin;
14871 $this->lMargin += $deltam;
14872 $this->rMargin -= $deltam;
14873 }
14874 }
14875
14888 public function setHtmlVSpace($tagvs) {
14889 $this->tagvspaces = $tagvs;
14890 }
14891
14898 public function setListIndentWidth($width) {
14899 return $this->customlistindent = floatval($width);
14900 }
14901
14908 public function setOpenCell($isopen) {
14909 $this->opencell = $isopen;
14910 }
14911
14919 public function setHtmlLinksStyle($color=array(0,0,255), $fontstyle='U') {
14920 $this->htmlLinkColorArray = $color;
14921 $this->htmlLinkFontStyle = $fontstyle;
14922 }
14923
14934 public function getHTMLUnitToUnits($htmlval, $refsize=1, $defaultunit='px', $points=false) {
14935 $supportedunits = array('%', 'em', 'ex', 'px', 'in', 'cm', 'mm', 'pc', 'pt');
14936 $retval = 0;
14937 $value = 0;
14938 $unit = 'px';
14939 $k = $this->k;
14940 if ($points) {
14941 $k = 1;
14942 }
14943 if (in_array($defaultunit, $supportedunits)) {
14944 $unit = $defaultunit;
14945 }
14946 if (is_numeric($htmlval)) {
14947 $value = floatval($htmlval);
14948 } elseif (preg_match('/([0-9\.]+)/', $htmlval, $mnum)) {
14949 $value = floatval($mnum[1]);
14950 if (preg_match('/([a-z%]+)/', $htmlval, $munit)) {
14951 if (in_array($munit[1], $supportedunits)) {
14952 $unit = $munit[1];
14953 }
14954 }
14955 }
14956 switch ($unit) {
14957 // percentage
14958 case '%': {
14959 $retval = (($value * $refsize) / 100);
14960 break;
14961 }
14962 // relative-size
14963 case 'em': {
14964 $retval = ($value * $refsize);
14965 break;
14966 }
14967 case 'ex': {
14968 $retval = $value * ($refsize / 2);
14969 break;
14970 }
14971 // absolute-size
14972 case 'in': {
14973 $retval = ($value * $this->dpi) / $k;
14974 break;
14975 }
14976 case 'cm': {
14977 $retval = ($value / 2.54 * $this->dpi) / $k;
14978 break;
14979 }
14980 case 'mm': {
14981 $retval = ($value / 25.4 * $this->dpi) / $k;
14982 break;
14983 }
14984 case 'pc': {
14985 // one pica is 12 points
14986 $retval = ($value * 12) / $k;
14987 break;
14988 }
14989 case 'pt': {
14990 $retval = $value / $k;
14991 break;
14992 }
14993 case 'px': {
14994 $retval = $this->pixelsToUnits($value);
14995 break;
14996 }
14997 }
14998 return $retval;
14999 }
15000
15008 public function intToRoman($number) {
15009 $roman = '';
15010 while ($number >= 1000) {
15011 $roman .= 'M';
15012 $number -= 1000;
15013 }
15014 while ($number >= 900) {
15015 $roman .= 'CM';
15016 $number -= 900;
15017 }
15018 while ($number >= 500) {
15019 $roman .= 'D';
15020 $number -= 500;
15021 }
15022 while ($number >= 400) {
15023 $roman .= 'CD';
15024 $number -= 400;
15025 }
15026 while ($number >= 100) {
15027 $roman .= 'C';
15028 $number -= 100;
15029 }
15030 while ($number >= 90) {
15031 $roman .= 'XC';
15032 $number -= 90;
15033 }
15034 while ($number >= 50) {
15035 $roman .= 'L';
15036 $number -= 50;
15037 }
15038 while ($number >= 40) {
15039 $roman .= 'XL';
15040 $number -= 40;
15041 }
15042 while ($number >= 10) {
15043 $roman .= 'X';
15044 $number -= 10;
15045 }
15046 while ($number >= 9) {
15047 $roman .= 'IX';
15048 $number -= 9;
15049 }
15050 while ($number >= 5) {
15051 $roman .= 'V';
15052 $number -= 5;
15053 }
15054 while ($number >= 4) {
15055 $roman .= 'IV';
15056 $number -= 4;
15057 }
15058 while ($number >= 1) {
15059 $roman .= 'I';
15060 --$number;
15061 }
15062 return $roman;
15063 }
15064
15073 protected function putHtmlListBullet($listdepth, $listtype='', $size=10) {
15074 $size /= $this->k;
15075 $fill = '';
15076 $color = $this->fgcolor;
15077 $width = 0;
15078 $textitem = '';
15079 $tmpx = $this->x;
15080 $lspace = $this->GetStringWidth(' ');
15081 if ($listtype == '!') {
15082 // set default list type for unordered list
15083 $deftypes = array('disc', 'circle', 'square');
15084 $listtype = $deftypes[($listdepth - 1) % 3];
15085 } elseif ($listtype == '#') {
15086 // set default list type for ordered list
15087 $listtype = 'decimal';
15088 }
15089 switch ($listtype) {
15090 // unordered types
15091 case 'none': {
15092 break;
15093 }
15094 case 'disc': {
15095 $fill = 'F';
15096 }
15097 case 'circle': {
15098 $fill .= 'D';
15099 $r = $size / 6;
15100 $lspace += (2 * $r);
15101 if ($this->rtl) {
15102 $this->x = $this->w - $this->x - $lspace;
15103 } else {
15104 $this->x -= $lspace;
15105 }
15106 $this->Circle(($this->x + $r), ($this->y + ($this->lasth / 2)), $r, 0, 360, $fill, array('color'=>$color), $color, 8);
15107 break;
15108 }
15109 case 'square': {
15110 $l = $size / 3;
15111 $lspace += $l;
15112 if ($this->rtl) {
15113 $this->x = $this->w - $this->x - $lspace;
15114 } else {
15115 $this->x -= $lspace;
15116 }
15117 $this->Rect($this->x, ($this->y + (($this->lasth - $l)/ 2)), $l, $l, 'F', array(), $color);
15118 break;
15119 }
15120 // ordered types
15121
15122 // $this->listcount[$this->listnum];
15123 // $textitem
15124 case '1':
15125 case 'decimal': {
15126 $textitem = $this->listcount[$this->listnum];
15127 break;
15128 }
15129 case 'decimal-leading-zero': {
15130 $textitem = sprintf("%02d", $this->listcount[$this->listnum]);
15131 break;
15132 }
15133 case 'i':
15134 case 'lower-roman': {
15135 $textitem = strtolower($this->intToRoman($this->listcount[$this->listnum]));
15136 break;
15137 }
15138 case 'I':
15139 case 'upper-roman': {
15140 $textitem = $this->intToRoman($this->listcount[$this->listnum]);
15141 break;
15142 }
15143 case 'a':
15144 case 'lower-alpha':
15145 case 'lower-latin': {
15146 $textitem = chr(97 + $this->listcount[$this->listnum] - 1);
15147 break;
15148 }
15149 case 'A':
15150 case 'upper-alpha':
15151 case 'upper-latin': {
15152 $textitem = chr(65 + $this->listcount[$this->listnum] - 1);
15153 break;
15154 }
15155 case 'lower-greek': {
15156 $textitem = $this->unichr(945 + $this->listcount[$this->listnum] - 1);
15157 break;
15158 }
15159 /*
15160 // Types to be implemented (special handling)
15161 case 'hebrew': {
15162 break;
15163 }
15164 case 'armenian': {
15165 break;
15166 }
15167 case 'georgian': {
15168 break;
15169 }
15170 case 'cjk-ideographic': {
15171 break;
15172 }
15173 case 'hiragana': {
15174 break;
15175 }
15176 case 'katakana': {
15177 break;
15178 }
15179 case 'hiragana-iroha': {
15180 break;
15181 }
15182 case 'katakana-iroha': {
15183 break;
15184 }
15185 */
15186 default: {
15187 $textitem = $this->listcount[$this->listnum];
15188 }
15189 }
15190 if (!$this->empty_string($textitem)) {
15191 // print ordered item
15192 if ($this->rtl) {
15193 $textitem = '.'.$textitem;
15194 } else {
15195 $textitem = $textitem.'.';
15196 }
15197 $lspace += $this->GetStringWidth($textitem);
15198 if ($this->rtl) {
15199 $this->x += $lspace;
15200 } else {
15201 $this->x -= $lspace;
15202 }
15203 $this->Write($this->lasth, $textitem, '', false, '', false, 0, false);
15204 }
15205 $this->x = $tmpx;
15206 $this->lispacer = '';
15207 }
15208
15215 protected function getGraphicVars() {
15216 $grapvars = array(
15217 'FontFamily' => $this->FontFamily,
15218 'FontStyle' => $this->FontStyle,
15219 'FontSizePt' => $this->FontSizePt,
15220 'rMargin' => $this->rMargin,
15221 'lMargin' => $this->lMargin,
15222 'cMargin' => $this->cMargin,
15223 'LineWidth' => $this->LineWidth,
15224 'linestyleWidth' => $this->linestyleWidth,
15225 'linestyleCap' => $this->linestyleCap,
15226 'linestyleJoin' => $this->linestyleJoin,
15227 'linestyleDash' => $this->linestyleDash,
15228 'DrawColor' => $this->DrawColor,
15229 'FillColor' => $this->FillColor,
15230 'TextColor' => $this->TextColor,
15231 'ColorFlag' => $this->ColorFlag,
15232 'bgcolor' => $this->bgcolor,
15233 'fgcolor' => $this->fgcolor,
15234 'htmlvspace' => $this->htmlvspace,
15235 'lasth' => $this->lasth
15236 );
15237 return $grapvars;
15238 }
15239
15246 protected function setGraphicVars($gvars) {
15247 $this->FontFamily = $gvars['FontFamily'];
15248 $this->FontStyle = $gvars['FontStyle'];
15249 $this->FontSizePt = $gvars['FontSizePt'];
15250 $this->rMargin = $gvars['rMargin'];
15251 $this->lMargin = $gvars['lMargin'];
15252 $this->cMargin = $gvars['cMargin'];
15253 $this->LineWidth = $gvars['LineWidth'];
15254 $this->linestyleWidth = $gvars['linestyleWidth'];
15255 $this->linestyleCap = $gvars['linestyleCap'];
15256 $this->linestyleJoin = $gvars['linestyleJoin'];
15257 $this->linestyleDash = $gvars['linestyleDash'];
15258 $this->DrawColor = $gvars['DrawColor'];
15259 $this->FillColor = $gvars['FillColor'];
15260 $this->TextColor = $gvars['TextColor'];
15261 $this->ColorFlag = $gvars['ColorFlag'];
15262 $this->bgcolor = $gvars['bgcolor'];
15263 $this->fgcolor = $gvars['fgcolor'];
15264 $this->htmlvspace = $gvars['htmlvspace'];
15265 //$this->lasth = $gvars['lasth'];
15266 $this->_out(''.$this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor.' '.$this->FillColor.'');
15267 if (!$this->empty_string($this->FontFamily)) {
15268 $this->SetFont($this->FontFamily, $this->FontStyle, $this->FontSizePt);
15269 }
15270 }
15271
15279 protected function getObjFilename($name) {
15280 return tempnam(K_PATH_CACHE, $name.'_');
15281 }
15282
15291 protected function writeDiskCache($filename, $data, $append=false) {
15292 if ($append) {
15293 $fmode = 'ab+';
15294 } else {
15295 $fmode = 'wb+';
15296 }
15297 $f = @fopen($filename, $fmode);
15298 if (!$f) {
15299 $this->Error('Unable to write cache file: '.$filename);
15300 } else {
15301 fwrite($f, $data);
15302 fclose($f);
15303 }
15304 // update file lenght (needed for transactions)
15305 if (!isset($this->cache_file_lenght['_'.$filename])) {
15306 $this->cache_file_lenght['_'.$filename] = strlen($data);
15307 } else {
15308 $this->cache_file_lenght['_'.$filename] += strlen($data);
15309 }
15310 }
15311
15319 protected function readDiskCache($filename) {
15320 return file_get_contents($filename);
15321 }
15322
15329 protected function setBuffer($data) {
15330 $this->bufferlen += strlen($data);
15331 if ($this->diskcache) {
15332 if (!isset($this->buffer) OR $this->empty_string($this->buffer)) {
15333 $this->buffer = $this->getObjFilename('buffer');
15334 }
15335 $this->writeDiskCache($this->buffer, $data, true);
15336 } else {
15337 $this->buffer .= $data;
15338 }
15339 }
15340
15347 protected function getBuffer() {
15348 if ($this->diskcache) {
15349 return $this->readDiskCache($this->buffer);
15350 } else {
15351 return $this->buffer;
15352 }
15353 }
15354
15363 protected function setPageBuffer($page, $data, $append=false) {
15364 if ($this->diskcache) {
15365 if (!isset($this->pages[$page])) {
15366 $this->pages[$page] = $this->getObjFilename('page'.$page);
15367 }
15368 $this->writeDiskCache($this->pages[$page], $data, $append);
15369 } else {
15370 if ($append) {
15371 $this->pages[$page] .= $data;
15372 } else {
15373 $this->pages[$page] = $data;
15374 }
15375 }
15376 if ($append AND isset($this->pagelen[$page])) {
15377 $this->pagelen[$page] += strlen($data);
15378 } else {
15379 $this->pagelen[$page] = strlen($data);
15380 }
15381 }
15382
15390 protected function getPageBuffer($page) {
15391 if ($this->diskcache) {
15392 return $this->readDiskCache($this->pages[$page]);
15393 } elseif (isset($this->pages[$page])) {
15394 return $this->pages[$page];
15395 }
15396 return false;
15397 }
15398
15406 protected function setImageBuffer($image, $data) {
15407 if ($this->diskcache) {
15408 if (!isset($this->images[$image])) {
15409 $this->images[$image] = $this->getObjFilename('image'.$image);
15410 }
15411 $this->writeDiskCache($this->images[$image], serialize($data));
15412 } else {
15413 $this->images[$image] = $data;
15414 }
15415 if (!in_array($image, $this->imagekeys)) {
15416 $this->imagekeys[] = $image;
15417 }
15418 ++$this->numimages;
15419 }
15420
15429 protected function setImageSubBuffer($image, $key, $data) {
15430 if (!isset($this->images[$image])) {
15431 $this->setImageBuffer($image, array());
15432 }
15433 if ($this->diskcache) {
15434 $tmpimg = $this->getImageBuffer($image);
15435 $tmpimg[$key] = $data;
15436 $this->writeDiskCache($this->images[$image], serialize($tmpimg));
15437 } else {
15438 $this->images[$image][$key] = $data;
15439 }
15440 }
15441
15449 protected function getImageBuffer($image) {
15450 if ($this->diskcache AND isset($this->images[$image])) {
15451 return unserialize($this->readDiskCache($this->images[$image]));
15452 } elseif (isset($this->images[$image])) {
15453 return $this->images[$image];
15454 }
15455 return false;
15456 }
15457
15465 protected function setFontBuffer($font, $data) {
15466 if ($this->diskcache) {
15467 if (!isset($this->fonts[$font])) {
15468 $this->fonts[$font] = $this->getObjFilename('font');
15469 }
15470 $this->writeDiskCache($this->fonts[$font], serialize($data));
15471 } else {
15472 $this->fonts[$font] = $data;
15473 }
15474 if (!in_array($font, $this->fontkeys)) {
15475 $this->fontkeys[] = $font;
15476 }
15477 }
15478
15487 protected function setFontSubBuffer($font, $key, $data) {
15488 if (!isset($this->fonts[$font])) {
15489 $this->setFontBuffer($font, array());
15490 }
15491 if ($this->diskcache) {
15492 $tmpfont = $this->getFontBuffer($font);
15493 $tmpfont[$key] = $data;
15494 $this->writeDiskCache($this->fonts[$font], serialize($tmpfont));
15495 } else {
15496 $this->fonts[$font][$key] = $data;
15497 }
15498 }
15499
15507 protected function getFontBuffer($font) {
15508 if ($this->diskcache AND isset($this->fonts[$font])) {
15509 return unserialize($this->readDiskCache($this->fonts[$font]));
15510 } elseif (isset($this->fonts[$font])) {
15511 return $this->fonts[$font];
15512 }
15513 return false;
15514 }
15515
15524 public function movePage($frompage, $topage) {
15525 if (($frompage > $this->numpages) OR ($frompage <= $topage)) {
15526 return false;
15527 }
15528 if ($frompage == $this->page) {
15529 // close the page before moving it
15530 $this->endPage();
15531 }
15532 // move all page-related states
15533 $tmppage = $this->pages[$frompage];
15534 $tmppagedim = $this->pagedim[$frompage];
15535 $tmppagelen = $this->pagelen[$frompage];
15536 $tmpintmrk = $this->intmrk[$frompage];
15537 if (isset($this->footerpos[$frompage])) {
15538 $tmpfooterpos = $this->footerpos[$frompage];
15539 }
15540 if (isset($this->footerlen[$frompage])) {
15541 $tmpfooterlen = $this->footerlen[$frompage];
15542 }
15543 if (isset($this->transfmrk[$frompage])) {
15544 $tmptransfmrk = $this->transfmrk[$frompage];
15545 }
15546 if (isset($this->PageAnnots[$frompage])) {
15547 $tmpannots = $this->PageAnnots[$frompage];
15548 }
15549 if (isset($this->newpagegroup[$frompage])) {
15550 $tmpnewpagegroup = $this->newpagegroup[$frompage];
15551 }
15552 for ($i = $frompage; $i > $topage; --$i) {
15553 $j = $i - 1;
15554 // shift pages down
15555 $this->pages[$i] = $this->pages[$j];
15556 $this->pagedim[$i] = $this->pagedim[$j];
15557 $this->pagelen[$i] = $this->pagelen[$j];
15558 $this->intmrk[$i] = $this->intmrk[$j];
15559 if (isset($this->footerpos[$j])) {
15560 $this->footerpos[$i] = $this->footerpos[$j];
15561 } elseif (isset($this->footerpos[$i])) {
15562 unset($this->footerpos[$i]);
15563 }
15564 if (isset($this->footerlen[$j])) {
15565 $this->footerlen[$i] = $this->footerlen[$j];
15566 } elseif (isset($this->footerlen[$i])) {
15567 unset($this->footerlen[$i]);
15568 }
15569 if (isset($this->transfmrk[$j])) {
15570 $this->transfmrk[$i] = $this->transfmrk[$j];
15571 } elseif (isset($this->transfmrk[$i])) {
15572 unset($this->transfmrk[$i]);
15573 }
15574 if (isset($this->PageAnnots[$j])) {
15575 $this->PageAnnots[$i] = $this->PageAnnots[$j];
15576 } elseif (isset($this->PageAnnots[$i])) {
15577 unset($this->PageAnnots[$i]);
15578 }
15579 if (isset($this->newpagegroup[$j])) {
15580 $this->newpagegroup[$i] = $this->newpagegroup[$j];
15581 } elseif (isset($this->newpagegroup[$i])) {
15582 unset($this->newpagegroup[$i]);
15583 }
15584 }
15585 $this->pages[$topage] = $tmppage;
15586 $this->pagedim[$topage] = $tmppagedim;
15587 $this->pagelen[$topage] = $tmppagelen;
15588 $this->intmrk[$topage] = $tmpintmrk;
15589 if (isset($tmpfooterpos)) {
15590 $this->footerpos[$topage] = $tmpfooterpos;
15591 } elseif (isset($this->footerpos[$topage])) {
15592 unset($this->footerpos[$topage]);
15593 }
15594 if (isset($tmpfooterlen)) {
15595 $this->footerlen[$topage] = $tmpfooterlen;
15596 } elseif (isset($this->footerlen[$topage])) {
15597 unset($this->footerlen[$topage]);
15598 }
15599 if (isset($tmptransfmrk)) {
15600 $this->transfmrk[$topage] = $tmptransfmrk;
15601 } elseif (isset($this->transfmrk[$topage])) {
15602 unset($this->transfmrk[$topage]);
15603 }
15604 if (isset($tmpannots)) {
15605 $this->PageAnnots[$topage] = $tmpannots;
15606 } elseif (isset($this->PageAnnots[$topage])) {
15607 unset($this->PageAnnots[$topage]);
15608 }
15609 if (isset($tmpnewpagegroup)) {
15610 $this->newpagegroup[$topage] = $tmpnewpagegroup;
15611 } elseif (isset($this->newpagegroup[$topage])) {
15612 unset($this->newpagegroup[$topage]);
15613 }
15614 // adjust outlines
15615 $tmpoutlines = $this->outlines;
15616 foreach ($tmpoutlines as $key => $outline) {
15617 if (($outline['p'] >= $topage) AND ($outline['p'] < $frompage)) {
15618 $this->outlines[$key]['p'] = $outline['p'] + 1;
15619 } elseif ($outline['p'] == $frompage) {
15620 $this->outlines[$key]['p'] = $topage;
15621 }
15622 }
15623 // adjust links
15624 $tmplinks = $this->links;
15625 foreach ($tmplinks as $key => $link) {
15626 if (($link[0] >= $topage) AND ($link[0] < $frompage)) {
15627 $this->links[$key][0] = $link[0] + 1;
15628 } elseif ($link[0] == $frompage) {
15629 $this->links[$key][0] = $topage;
15630 }
15631 }
15632 // adjust javascript
15633 $tmpjavascript = $this->javascript;
15634 global $jfrompage, $jtopage;
15635 $jfrompage = $frompage;
15636 $jtopage = $topage;
15637 $this->javascript = preg_replace_callback('/this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/',
15638 create_function('$matches', 'global $jfrompage, $jtopage;
15639 $pagenum = intval($matches[3]) + 1;
15640 if (($pagenum >= $jtopage) AND ($pagenum < $jfrompage)) {
15641 $newpage = ($pagenum + 1);
15642 } elseif ($pagenum == $jfrompage) {
15643 $newpage = $jtopage;
15644 } else {
15645 $newpage = $pagenum;
15646 }
15647 --$newpage;
15648 return "this.addField(\'".$matches[1]."\',\'".$matches[2]."\',".$newpage."";'), $tmpjavascript);
15649
15650 $this->lastPage(true);
15651 return true;
15652 }
15653
15661 public function deletePage($page) {
15662 if ($page > $this->numpages) {
15663 return false;
15664 }
15665
15666 unset($this->pages[$page]);
15667 unset($this->pagedim[$page]);
15668 unset($this->pagelen[$page]);
15669 unset($this->intmrk[$page]);
15670 if (isset($this->footerpos[$page])) {
15671 unset($this->footerpos[$page]);
15672 }
15673 if (isset($this->footerlen[$page])) {
15674 unset($this->footerlen[$page]);
15675 }
15676 if (isset($this->transfmrk[$page])) {
15677 unset($this->transfmrk[$page]);
15678 }
15679 if (isset($this->PageAnnots[$page])) {
15680 unset($this->PageAnnots[$page]);
15681 }
15682 if (isset($this->newpagegroup[$page])) {
15683 unset($this->newpagegroup[$page]);
15684 }
15685 if (isset($this->pageopen[$page])) {
15686 unset($this->pageopen[$page]);
15687 }
15688
15689 for ($i = $page; $i < $this->numpages; ++$i) {
15690 $j = $i + 1;
15691
15692 $this->pages[$i] = $this->pages[$j];
15693 $this->pagedim[$i] = $this->pagedim[$j];
15694 $this->pagelen[$i] = $this->pagelen[$j];
15695 $this->intmrk[$i] = $this->intmrk[$j];
15696 if (isset($this->footerpos[$j])) {
15697 $this->footerpos[$i] = $this->footerpos[$j];
15698 } elseif (isset($this->footerpos[$i])) {
15699 unset($this->footerpos[$i]);
15700 }
15701 if (isset($this->footerlen[$j])) {
15702 $this->footerlen[$i] = $this->footerlen[$j];
15703 } elseif (isset($this->footerlen[$i])) {
15704 unset($this->footerlen[$i]);
15705 }
15706 if (isset($this->transfmrk[$j])) {
15707 $this->transfmrk[$i] = $this->transfmrk[$j];
15708 } elseif (isset($this->transfmrk[$i])) {
15709 unset($this->transfmrk[$i]);
15710 }
15711 if (isset($this->PageAnnots[$j])) {
15712 $this->PageAnnots[$i] = $this->PageAnnots[$j];
15713 } elseif (isset($this->PageAnnots[$i])) {
15714 unset($this->PageAnnots[$i]);
15715 }
15716 if (isset($this->newpagegroup[$j])) {
15717 $this->newpagegroup[$i] = $this->newpagegroup[$j];
15718 } elseif (isset($this->newpagegroup[$i])) {
15719 unset($this->newpagegroup[$i]);
15720 }
15721 if (isset($this->pageopen[$j])) {
15722 $this->pageopen[$i] = $this->pageopen[$j];
15723 } elseif (isset($this->pageopen[$i])) {
15724 unset($this->pageopen[$i]);
15725 }
15726 }
15727
15728 unset($this->pages[$this->numpages]);
15729 unset($this->pagedim[$this->numpages]);
15730 unset($this->pagelen[$this->numpages]);
15731 unset($this->intmrk[$this->numpages]);
15732 if (isset($this->footerpos[$this->numpages])) {
15733 unset($this->footerpos[$this->numpages]);
15734 }
15735 if (isset($this->footerlen[$this->numpages])) {
15736 unset($this->footerlen[$this->numpages]);
15737 }
15738 if (isset($this->transfmrk[$this->numpages])) {
15739 unset($this->transfmrk[$this->numpages]);
15740 }
15741 if (isset($this->PageAnnots[$this->numpages])) {
15742 unset($this->PageAnnots[$this->numpages]);
15743 }
15744 if (isset($this->newpagegroup[$this->numpages])) {
15745 unset($this->newpagegroup[$this->numpages]);
15746 }
15747 if (isset($this->pageopen[$this->numpages])) {
15748 unset($this->pageopen[$this->numpages]);
15749 }
15750 --$this->numpages;
15751 $this->page = $this->numpages;
15752
15753 $tmpoutlines = $this->outlines;
15754 foreach ($tmpoutlines as $key => $outline) {
15755 if ($outline['p'] > $page) {
15756 $this->outlines[$key]['p'] = $outline['p'] - 1;
15757 } elseif ($outline['p'] == $page) {
15758 unset($this->outlines[$key]);
15759 }
15760 }
15761
15762 $tmplinks = $this->links;
15763 foreach ($tmplinks as $key => $link) {
15764 if ($link[0] > $page) {
15765 $this->links[$key][0] = $link[0] - 1;
15766 } elseif ($link[0] == $page) {
15767 unset($this->links[$key]);
15768 }
15769 }
15770
15771 $tmpjavascript = $this->javascript;
15772 global $jpage;
15773 $jpage = $page;
15774 $this->javascript = preg_replace_callback('/this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/',
15775 create_function('$matches', 'global $jpage;
15776 $pagenum = intval($matches[3]) + 1;
15777 if ($pagenum >= $jpage) {
15778 $newpage = ($pagenum - 1);
15779 } elseif ($pagenum == $jpage) {
15780 $newpage = 1;
15781 } else {
15782 $newpage = $pagenum;
15783 }
15784 --$newpage;
15785 return "this.addField(\'".$matches[1]."\',\'".$matches[2]."\',".$newpage."";'), $tmpjavascript);
15786
15787 $this->lastPage(true);
15788 return true;
15789 }
15790
15801 public function addTOC($page='', $numbersfont='', $filler='.') {
15802 $fontsize = $this->FontSizePt;
15803 $fontfamily = $this->FontFamily;
15804 $fontstyle = $this->FontStyle;
15805 $w = $this->w - $this->lMargin - $this->rMargin;
15806 $spacer = $this->GetStringWidth(' ') * 4;
15807 $page_first = $this->getPage();
15808 $lmargin = $this->lMargin;
15809 $rmargin = $this->rMargin;
15810 $x_start = $this->GetX();
15811 if ($this->empty_string($numbersfont)) {
15812 $numbersfont = $this->default_monospaced_font;
15813 }
15814 if ($this->empty_string($filler)) {
15815 $filler = ' ';
15816 }
15817 if ($this->empty_string($page)) {
15818 $gap = ' ';
15819 } else {
15820 $gap = '';
15821 }
15822 foreach ($this->outlines as $key => $outline) {
15823 if ($this->rtl) {
15824 $aligntext = 'R';
15825 $alignnum = 'L';
15826 } else {
15827 $aligntext = 'L';
15828 $alignnum = 'R';
15829 }
15830 if ($outline['l'] == 0) {
15831 $this->SetFont($fontfamily, $fontstyle.'B', $fontsize);
15832 } else {
15833 $this->SetFont($fontfamily, $fontstyle, $fontsize - $outline['l']);
15834 }
15835 $indent = ($spacer * $outline['l']);
15836 if ($this->rtl) {
15837 $this->rMargin += $indent;
15838 $this->x -= $indent;
15839 } else {
15840 $this->lMargin += $indent;
15841 $this->x += $indent;
15842 }
15843 $link = $this->AddLink();
15844 $this->SetLink($link, 0, $outline['p']);
15845
15846 $this->Write(0, $outline['t'], $link, 0, $aligntext, false, 0, false, false, 0);
15847 $this->SetFont($numbersfont, $fontstyle, $fontsize);
15848 if ($this->empty_string($page)) {
15849 $pagenum = $outline['p'];
15850 } else {
15851
15852 $pagenum = '{#'.($outline['p']).'}';
15853 if (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')) {
15854 $pagenum = '{'.$pagenum.'}';
15855 }
15856 }
15857 $numwidth = $this->GetStringWidth($pagenum);
15858 if ($this->rtl) {
15859 $tw = $this->x - $this->lMargin;
15860 } else {
15861 $tw = $this->w - $this->rMargin - $this->x;
15862 }
15863 $fw = $tw - $numwidth - $this->GetStringWidth(' ');
15864 $numfills = floor($fw / $this->GetStringWidth($filler));
15865 if ($numfills > 0) {
15866 $rowfill = str_repeat($filler, $numfills);
15867 } else {
15868 $rowfill = '';
15869 }
15870 if ($this->rtl) {
15871 $pagenum = $pagenum.$gap.$rowfill.' ';
15872 } else {
15873 $pagenum = ' '.$rowfill.$gap.$pagenum;
15874 }
15875
15876
15877 $this->Cell($tw, 0, $pagenum, 0, 1, $alignnum, 0, $link, 0);
15878 $this->SetX($x_start);
15879 $this->lMargin = $lmargin;
15880 $this->rMargin = $rmargin;
15881 }
15882 $page_last = $this->getPage();
15883 $numpages = $page_last - $page_first + 1;
15884 if (!$this->empty_string($page)) {
15885 for ($p = $page_first; $p <= $page_last; ++$p) {
15886
15887 $temppage = $this->getPageBuffer($p);
15888 for ($n = 1; $n <= $this->numpages; ++$n) {
15889
15890 $k = '{#'.$n.'}';
15891 $ku = '{'.$k.'}';
15892 $alias_a = $this->_escape($k);
15893 $alias_au = $this->_escape('{'.$k.'}');
15894 if ($this->isunicode) {
15895 $alias_b = $this->_escape($this->UTF8ToLatin1($k));
15896 $alias_bu = $this->_escape($this->UTF8ToLatin1($ku));
15897 $alias_c = $this->_escape($this->utf8StrRev($k, false, $this->tmprtl));
15898 $alias_cu = $this->_escape($this->utf8StrRev($ku, false, $this->tmprtl));
15899 }
15900 if ($n >= $page) {
15901 $np = $n + $numpages;
15902 } else {
15903 $np = $n;
15904 }
15905 $ns = $this->formatTOCPageNumber($np);
15906 $nu = $ns;
15907 $sdiff = strlen($k) - strlen($ns) - 1;
15908 $sdiffu = strlen($ku) - strlen($ns) - 1;
15909 $sfill = str_repeat($filler, $sdiff);
15910 $sfillu = str_repeat($filler, $sdiffu);
15911 if ($this->rtl) {
15912 $ns = $ns.' '.$sfill;
15913 $nu = $nu.' '.$sfillu;
15914 } else {
15915 $ns = $sfill.' '.$ns;
15916 $nu = $sfillu.' '.$nu;
15917 }
15918 $nu = $this->UTF8ToUTF16BE($nu, false);
15919 $temppage = str_replace($alias_au, $nu, $temppage);
15920 if ($this->isunicode) {
15921 $temppage = str_replace($alias_bu, $nu, $temppage);
15922 $temppage = str_replace($alias_cu, $nu, $temppage);
15923 $temppage = str_replace($alias_b, $ns, $temppage);
15924 $temppage = str_replace($alias_c, $ns, $temppage);
15925 }
15926 $temppage = str_replace($alias_a, $ns, $temppage);
15927 }
15928
15929 $this->setPageBuffer($p, $temppage);
15930 }
15931
15932 for ($i = 0; $i < $numpages; ++$i) {
15933 $this->movePage($page_last, $page);
15934 }
15935 }
15936 $this->SetFont($fontfamily, $fontstyle, $fontsize);
15937 }
15938
15944 public function startTransaction() {
15945 if (isset($this->objcopy)) {
15946
15947 $this->commitTransaction();
15948 }
15949
15950 $this->start_transaction_page = $this->page;
15951
15952 $this->objcopy = $this->objclone($this);
15953 }
15954
15960 public function commitTransaction() {
15961 if (isset($this->objcopy)) {
15962 $this->objcopy->_destroy(true, true);
15963 unset($this->objcopy);
15964 }
15965 }
15966
15974 public function rollbackTransaction($self=false) {
15975 if (isset($this->objcopy)) {
15976 if (isset($this->objcopy->diskcache) AND $this->objcopy->diskcache) {
15977
15978 foreach ($this->objcopy->cache_file_lenght as $file => $lenght) {
15979 $file = substr($file, 1);
15980 $handle = fopen($file, 'r+');
15981 ftruncate($handle, $lenght);
15982 }
15983 }
15984 $this->_destroy(true, true);
15985 if ($self) {
15986 $objvars = get_object_vars($this->objcopy);
15987 foreach ($objvars as $key => $value) {
15988 $this->$key = $value;
15989 }
15990 }
15991 return $this->objcopy;
15992 }
15993 return $this;
15994 }
15995
16003 public function objclone($object) {
16004 return @clone($object);
16005 }
16006
16014 public function empty_string($str) {
16015 return (is_null($str) OR (is_string($str) AND (strlen($str) == 0)));
16016 }
16017
16018 }
16019 }
16020
16021
16022
16023 ?>