Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]

   1  <?php
   2  //============================================================+
   3  // File name   : tcpdf.php
   4  // Version     : 6.3.2
   5  // Begin       : 2002-08-03
   6  // Last Update : 2019-09-20
   7  // Author      : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
   8  // License     : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
   9  // -------------------------------------------------------------------
  10  // Copyright (C) 2002-2019 Nicola Asuni - Tecnick.com LTD
  11  //
  12  // This file is part of TCPDF software library.
  13  //
  14  // TCPDF is free software: you can redistribute it and/or modify it
  15  // under the terms of the GNU Lesser General Public License as
  16  // published by the Free Software Foundation, either version 3 of the
  17  // License, or (at your option) any later version.
  18  //
  19  // TCPDF is distributed in the hope that it will be useful, but
  20  // WITHOUT ANY WARRANTY; without even the implied warranty of
  21  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  22  // See the GNU Lesser General Public License for more details.
  23  //
  24  // You should have received a copy of the License
  25  // along with TCPDF. If not, see
  26  // <http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT>.
  27  //
  28  // See LICENSE.TXT file for more information.
  29  // -------------------------------------------------------------------
  30  //
  31  // Description :
  32  //   This is a PHP class for generating PDF documents without requiring external extensions.
  33  //
  34  // NOTE:
  35  //   This class was originally derived in 2002 from the Public
  36  //   Domain FPDF class by Olivier Plathey (http://www.fpdf.org),
  37  //   but now is almost entirely rewritten and contains thousands of
  38  //   new lines of code and hundreds new features.
  39  //
  40  // Main features:
  41  //  * no external libraries are required for the basic functions;
  42  //  * all standard page formats, custom page formats, custom margins and units of measure;
  43  //  * UTF-8 Unicode and Right-To-Left languages;
  44  //  * TrueTypeUnicode, TrueType, Type1 and CID-0 fonts;
  45  //  * font subsetting;
  46  //  * methods to publish some XHTML + CSS code, Javascript and Forms;
  47  //  * images, graphic (geometric figures) and transformation methods;
  48  //  * supports JPEG, PNG and SVG images natively, all images supported by GD (GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM) and all images supported via ImageMagick (http://www.imagemagick.org/www/formats.html)
  49  //  * 1D and 2D barcodes: CODE 39, ANSI MH10.8M-1983, USD-3, 3 of 9, CODE 93, USS-93, Standard 2 of 5, Interleaved 2 of 5, CODE 128 A/B/C, 2 and 5 Digits UPC-Based Extension, EAN 8, EAN 13, UPC-A, UPC-E, MSI, POSTNET, PLANET, RMS4CC (Royal Mail 4-state Customer Code), CBC (Customer Bar Code), KIX (Klant index - Customer index), Intelligent Mail Barcode, Onecode, USPS-B-3200, CODABAR, CODE 11, PHARMACODE, PHARMACODE TWO-TRACKS, Datamatrix, QR-Code, PDF417;
  50  //  * JPEG and PNG ICC profiles, Grayscale, RGB, CMYK, Spot Colors and Transparencies;
  51  //  * automatic page header and footer management;
  52  //  * document encryption up to 256 bit and digital signature certifications;
  53  //  * transactions to UNDO commands;
  54  //  * PDF annotations, including links, text and file attachments;
  55  //  * text rendering modes (fill, stroke and clipping);
  56  //  * multiple columns mode;
  57  //  * no-write page regions;
  58  //  * bookmarks, named destinations and table of content;
  59  //  * text hyphenation;
  60  //  * text stretching and spacing (tracking);
  61  //  * automatic page break, line break and text alignments including justification;
  62  //  * automatic page numbering and page groups;
  63  //  * move and delete pages;
  64  //  * page compression (requires php-zlib extension);
  65  //  * XOBject Templates;
  66  //  * Layers and object visibility.
  67  //	 * PDF/A-1b support
  68  //============================================================+
  69  
  70  /**
  71   * @file
  72   * This is a PHP class for generating PDF documents without requiring external extensions.<br>
  73   * TCPDF project (http://www.tcpdf.org) was originally derived in 2002 from the Public Domain FPDF class by Olivier Plathey (http://www.fpdf.org), but now is almost entirely rewritten.<br>
  74   * <h3>TCPDF main features are:</h3>
  75   * <ul>
  76   * <li>no external libraries are required for the basic functions;</li>
  77   * <li>all standard page formats, custom page formats, custom margins and units of measure;</li>
  78   * <li>UTF-8 Unicode and Right-To-Left languages;</li>
  79   * <li>TrueTypeUnicode, TrueType, Type1 and CID-0 fonts;</li>
  80   * <li>font subsetting;</li>
  81   * <li>methods to publish some XHTML + CSS code, Javascript and Forms;</li>
  82   * <li>images, graphic (geometric figures) and transformation methods;
  83   * <li>supports JPEG, PNG and SVG images natively, all images supported by GD (GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM) and all images supported via ImageMagick (http://www.imagemagick.org/www/formats.html)</li>
  84   * <li>1D and 2D barcodes: CODE 39, ANSI MH10.8M-1983, USD-3, 3 of 9, CODE 93, USS-93, Standard 2 of 5, Interleaved 2 of 5, CODE 128 A/B/C, 2 and 5 Digits UPC-Based Extension, EAN 8, EAN 13, UPC-A, UPC-E, MSI, POSTNET, PLANET, RMS4CC (Royal Mail 4-state Customer Code), CBC (Customer Bar Code), KIX (Klant index - Customer index), Intelligent Mail Barcode, Onecode, USPS-B-3200, CODABAR, CODE 11, PHARMACODE, PHARMACODE TWO-TRACKS, Datamatrix, QR-Code, PDF417;</li>
  85   * <li>JPEG and PNG ICC profiles, Grayscale, RGB, CMYK, Spot Colors and Transparencies;</li>
  86   * <li>automatic page header and footer management;</li>
  87   * <li>document encryption up to 256 bit and digital signature certifications;</li>
  88   * <li>transactions to UNDO commands;</li>
  89   * <li>PDF annotations, including links, text and file attachments;</li>
  90   * <li>text rendering modes (fill, stroke and clipping);</li>
  91   * <li>multiple columns mode;</li>
  92   * <li>no-write page regions;</li>
  93   * <li>bookmarks, named destinations and table of content;</li>
  94   * <li>text hyphenation;</li>
  95   * <li>text stretching and spacing (tracking);</li>
  96   * <li>automatic page break, line break and text alignments including justification;</li>
  97   * <li>automatic page numbering and page groups;</li>
  98   * <li>move and delete pages;</li>
  99   * <li>page compression (requires php-zlib extension);</li>
 100   * <li>XOBject Templates;</li>
 101   * <li>Layers and object visibility;</li>
 102   * <li>PDF/A-1b support.</li>
 103   * </ul>
 104   * Tools to encode your unicode fonts are on fonts/utils directory.</p>
 105   * @package com.tecnick.tcpdf
 106   * @author Nicola Asuni
 107   * @version 6.3.2
 108   */
 109  
 110  // TCPDF configuration
 111  require_once(dirname(__FILE__).'/tcpdf_autoconfig.php');
 112  // TCPDF static font methods and data
 113  require_once(dirname(__FILE__).'/include/tcpdf_font_data.php');
 114  // TCPDF static font methods and data
 115  require_once(dirname(__FILE__).'/include/tcpdf_fonts.php');
 116  // TCPDF static color methods and data
 117  require_once(dirname(__FILE__).'/include/tcpdf_colors.php');
 118  // TCPDF static image methods and data
 119  require_once(dirname(__FILE__).'/include/tcpdf_images.php');
 120  // TCPDF static methods and data
 121  require_once(dirname(__FILE__).'/include/tcpdf_static.php');
 122  
 123  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 124  
 125  /**
 126   * @class TCPDF
 127   * PHP class for generating PDF documents without requiring external extensions.
 128   * TCPDF project (http://www.tcpdf.org) has been originally derived in 2002 from the Public Domain FPDF class by Olivier Plathey (http://www.fpdf.org), but now is almost entirely rewritten.<br>
 129   * @package com.tecnick.tcpdf
 130   * @brief PHP class for generating PDF documents without requiring external extensions.
 131   * @version 6.3.2
 132   * @author Nicola Asuni - info@tecnick.com
 133   * @IgnoreAnnotation("protected")
 134   * @IgnoreAnnotation("public")
 135   * @IgnoreAnnotation("pre")
 136   */
 137  class TCPDF {
 138  
 139  	 // Protected properties
 140  
 141  	 /**
 142  	  * Current page number.
 143  	  * @protected
 144  	  */
 145  	 protected $page;
 146  
 147  	 /**
 148  	  * Current object number.
 149  	  * @protected
 150  	  */
 151  	 protected $n;
 152  
 153  	 /**
 154  	  * Array of object offsets.
 155  	  * @protected
 156  	  */
 157  	 protected $offsets = array();
 158  
 159  	 /**
 160  	  * Array of object IDs for each page.
 161  	  * @protected
 162  	  */
 163  	 protected $pageobjects = array();
 164  
 165  	 /**
 166  	  * Buffer holding in-memory PDF.
 167  	  * @protected
 168  	  */
 169  	 protected $buffer;
 170  
 171  	 /**
 172  	  * Array containing pages.
 173  	  * @protected
 174  	  */
 175  	 protected $pages = array();
 176  
 177  	 /**
 178  	  * Current document state.
 179  	  * @protected
 180  	  */
 181  	 protected $state;
 182  
 183  	 /**
 184  	  * Compression flag.
 185  	  * @protected
 186  	  */
 187  	 protected $compress;
 188  
 189  	 /**
 190  	  * Current page orientation (P = Portrait, L = Landscape).
 191  	  * @protected
 192  	  */
 193  	 protected $CurOrientation;
 194  
 195  	 /**
 196  	  * Page dimensions.
 197  	  * @protected
 198  	  */
 199  	 protected $pagedim = array();
 200  
 201  	 /**
 202  	  * Scale factor (number of points in user unit).
 203  	  * @protected
 204  	  */
 205  	 protected $k;
 206  
 207  	 /**
 208  	  * Width of page format in points.
 209  	  * @protected
 210  	  */
 211  	 protected $fwPt;
 212  
 213  	 /**
 214  	  * Height of page format in points.
 215  	  * @protected
 216  	  */
 217  	 protected $fhPt;
 218  
 219  	 /**
 220  	  * Current width of page in points.
 221  	  * @protected
 222  	  */
 223  	 protected $wPt;
 224  
 225  	 /**
 226  	  * Current height of page in points.
 227  	  * @protected
 228  	  */
 229  	 protected $hPt;
 230  
 231  	 /**
 232  	  * Current width of page in user unit.
 233  	  * @protected
 234  	  */
 235  	 protected $w;
 236  
 237  	 /**
 238  	  * Current height of page in user unit.
 239  	  * @protected
 240  	  */
 241  	 protected $h;
 242  
 243  	 /**
 244  	  * Left margin.
 245  	  * @protected
 246  	  */
 247  	 protected $lMargin;
 248  
 249  	 /**
 250  	  * Right margin.
 251  	  * @protected
 252  	  */
 253  	 protected $rMargin;
 254  
 255  	 /**
 256  	  * Cell left margin (used by regions).
 257  	  * @protected
 258  	  */
 259  	 protected $clMargin;
 260  
 261  	 /**
 262  	  * Cell right margin (used by regions).
 263  	  * @protected
 264  	  */
 265  	 protected $crMargin;
 266  
 267  	 /**
 268  	  * Top margin.
 269  	  * @protected
 270  	  */
 271  	 protected $tMargin;
 272  
 273  	 /**
 274  	  * Page break margin.
 275  	  * @protected
 276  	  */
 277  	 protected $bMargin;
 278  
 279  	 /**
 280  	  * Array of cell internal paddings ('T' => top, 'R' => right, 'B' => bottom, 'L' => left).
 281  	  * @since 5.9.000 (2010-10-03)
 282  	  * @protected
 283  	  */
 284  	 protected $cell_padding = array('T' => 0, 'R' => 0, 'B' => 0, 'L' => 0);
 285  
 286  	 /**
 287  	  * Array of cell margins ('T' => top, 'R' => right, 'B' => bottom, 'L' => left).
 288  	  * @since 5.9.000 (2010-10-04)
 289  	  * @protected
 290  	  */
 291  	 protected $cell_margin = array('T' => 0, 'R' => 0, 'B' => 0, 'L' => 0);
 292  
 293  	 /**
 294  	  * Current horizontal position in user unit for cell positioning.
 295  	  * @protected
 296  	  */
 297  	 protected $x;
 298  
 299  	 /**
 300  	  * Current vertical position in user unit for cell positioning.
 301  	  * @protected
 302  	  */
 303  	 protected $y;
 304  
 305  	 /**
 306  	  * Height of last cell printed.
 307  	  * @protected
 308  	  */
 309  	 protected $lasth;
 310  
 311  	 /**
 312  	  * Line width in user unit.
 313  	  * @protected
 314  	  */
 315  	 protected $LineWidth;
 316  
 317  	 /**
 318  	  * Array of standard font names.
 319  	  * @protected
 320  	  */
 321  	 protected $CoreFonts;
 322  
 323  	 /**
 324  	  * Array of used fonts.
 325  	  * @protected
 326  	  */
 327  	 protected $fonts = array();
 328  
 329  	 /**
 330  	  * Array of font files.
 331  	  * @protected
 332  	  */
 333  	 protected $FontFiles = array();
 334  
 335  	 /**
 336  	  * Array of encoding differences.
 337  	  * @protected
 338  	  */
 339  	 protected $diffs = array();
 340  
 341  	 /**
 342  	  * Array of used images.
 343  	  * @protected
 344  	  */
 345  	 protected $images = array();
 346  
 347  	 /**
 348  	  * Depth of the svg tag, to keep track if the svg tag is a subtag or the root tag.
 349  	  * @protected
 350  	  */
 351  	 protected $svg_tag_depth = 0;
 352  
 353  	 /**
 354  	  * Array of Annotations in pages.
 355  	  * @protected
 356  	  */
 357  	 protected $PageAnnots = array();
 358  
 359  	 /**
 360  	  * Array of internal links.
 361  	  * @protected
 362  	  */
 363  	 protected $links = array();
 364  
 365  	 /**
 366  	  * Current font family.
 367  	  * @protected
 368  	  */
 369  	 protected $FontFamily;
 370  
 371  	 /**
 372  	  * Current font style.
 373  	  * @protected
 374  	  */
 375  	 protected $FontStyle;
 376  
 377  	 /**
 378  	  * Current font ascent (distance between font top and baseline).
 379  	  * @protected
 380  	  * @since 2.8.000 (2007-03-29)
 381  	  */
 382  	 protected $FontAscent;
 383  
 384  	 /**
 385  	  * Current font descent (distance between font bottom and baseline).
 386  	  * @protected
 387  	  * @since 2.8.000 (2007-03-29)
 388  	  */
 389  	 protected $FontDescent;
 390  
 391  	 /**
 392  	  * Underlining flag.
 393  	  * @protected
 394  	  */
 395  	 protected $underline;
 396  
 397  	 /**
 398  	  * Overlining flag.
 399  	  * @protected
 400  	  */
 401  	 protected $overline;
 402  
 403  	 /**
 404  	  * Current font info.
 405  	  * @protected
 406  	  */
 407  	 protected $CurrentFont;
 408  
 409  	 /**
 410  	  * Current font size in points.
 411  	  * @protected
 412  	  */
 413  	 protected $FontSizePt;
 414  
 415  	 /**
 416  	  * Current font size in user unit.
 417  	  * @protected
 418  	  */
 419  	 protected $FontSize;
 420  
 421  	 /**
 422  	  * Commands for drawing color.
 423  	  * @protected
 424  	  */
 425  	 protected $DrawColor;
 426  
 427  	 /**
 428  	  * Commands for filling color.
 429  	  * @protected
 430  	  */
 431  	 protected $FillColor;
 432  
 433  	 /**
 434  	  * Commands for text color.
 435  	  * @protected
 436  	  */
 437  	 protected $TextColor;
 438  
 439  	 /**
 440  	  * Indicates whether fill and text colors are different.
 441  	  * @protected
 442  	  */
 443  	 protected $ColorFlag;
 444  
 445  	 /**
 446  	  * Automatic page breaking.
 447  	  * @protected
 448  	  */
 449  	 protected $AutoPageBreak;
 450  
 451  	 /**
 452  	  * Threshold used to trigger page breaks.
 453  	  * @protected
 454  	  */
 455  	 protected $PageBreakTrigger;
 456  
 457  	 /**
 458  	  * Flag set when processing page header.
 459  	  * @protected
 460  	  */
 461  	 protected $InHeader = false;
 462  
 463  	 /**
 464  	  * Flag set when processing page footer.
 465  	  * @protected
 466  	  */
 467  	 protected $InFooter = false;
 468  
 469  	 /**
 470  	  * Zoom display mode.
 471  	  * @protected
 472  	  */
 473  	 protected $ZoomMode;
 474  
 475  	 /**
 476  	  * Layout display mode.
 477  	  * @protected
 478  	  */
 479  	 protected $LayoutMode;
 480  
 481  	 /**
 482  	  * If true set the document information dictionary in Unicode.
 483  	  * @protected
 484  	  */
 485  	 protected $docinfounicode = true;
 486  
 487  	 /**
 488  	  * Document title.
 489  	  * @protected
 490  	  */
 491  	 protected $title = '';
 492  
 493  	 /**
 494  	  * Document subject.
 495  	  * @protected
 496  	  */
 497  	 protected $subject = '';
 498  
 499  	 /**
 500  	  * Document author.
 501  	  * @protected
 502  	  */
 503  	 protected $author = '';
 504  
 505  	 /**
 506  	  * Document keywords.
 507  	  * @protected
 508  	  */
 509  	 protected $keywords = '';
 510  
 511  	 /**
 512  	  * Document creator.
 513  	  * @protected
 514  	  */
 515  	 protected $creator = '';
 516  
 517  	 /**
 518  	  * Starting page number.
 519  	  * @protected
 520  	  */
 521  	 protected $starting_page_number = 1;
 522  
 523  	 /**
 524  	  * The right-bottom (or left-bottom for RTL) corner X coordinate of last inserted image.
 525  	  * @since 2002-07-31
 526  	  * @author Nicola Asuni
 527  	  * @protected
 528  	  */
 529  	 protected $img_rb_x;
 530  
 531  	 /**
 532  	  * The right-bottom corner Y coordinate of last inserted image.
 533  	  * @since 2002-07-31
 534  	  * @author Nicola Asuni
 535  	  * @protected
 536  	  */
 537  	 protected $img_rb_y;
 538  
 539  	 /**
 540  	  * Adjusting factor to convert pixels to user units.
 541  	  * @since 2004-06-14
 542  	  * @author Nicola Asuni
 543  	  * @protected
 544  	  */
 545  	 protected $imgscale = 1;
 546  
 547  	 /**
 548  	  * Boolean flag set to true when the input text is unicode (require unicode fonts).
 549  	  * @since 2005-01-02
 550  	  * @author Nicola Asuni
 551  	  * @protected
 552  	  */
 553  	 protected $isunicode = false;
 554  
 555  	 /**
 556  	  * PDF version.
 557  	  * @since 1.5.3
 558  	  * @protected
 559  	  */
 560  	 protected $PDFVersion = '1.7';
 561  
 562  	 /**
 563  	  * ID of the stored default header template (-1 = not set).
 564  	  * @protected
 565  	  */
 566  	 protected $header_xobjid = false;
 567  
 568  	 /**
 569  	  * If true reset the Header Xobject template at each page
 570  	  * @protected
 571  	  */
 572  	 protected $header_xobj_autoreset = false;
 573  
 574  	 /**
 575  	  * Minimum distance between header and top page margin.
 576  	  * @protected
 577  	  */
 578  	 protected $header_margin;
 579  
 580  	 /**
 581  	  * Minimum distance between footer and bottom page margin.
 582  	  * @protected
 583  	  */
 584  	 protected $footer_margin;
 585  
 586  	 /**
 587  	  * Original left margin value.
 588  	  * @protected
 589  	  * @since 1.53.0.TC013
 590  	  */
 591  	 protected $original_lMargin;
 592  
 593  	 /**
 594  	  * Original right margin value.
 595  	  * @protected
 596  	  * @since 1.53.0.TC013
 597  	  */
 598  	 protected $original_rMargin;
 599  
 600  	 /**
 601  	  * Default font used on page header.
 602  	  * @protected
 603  	  */
 604  	 protected $header_font;
 605  
 606  	 /**
 607  	  * Default font used on page footer.
 608  	  * @protected
 609  	  */
 610  	 protected $footer_font;
 611  
 612  	 /**
 613  	  * Language templates.
 614  	  * @protected
 615  	  */
 616  	 protected $l;
 617  
 618  	 /**
 619  	  * Barcode to print on page footer (only if set).
 620  	  * @protected
 621  	  */
 622  	 protected $barcode = false;
 623  
 624  	 /**
 625  	  * Boolean flag to print/hide page header.
 626  	  * @protected
 627  	  */
 628  	 protected $print_header = true;
 629  
 630  	 /**
 631  	  * Boolean flag to print/hide page footer.
 632  	  * @protected
 633  	  */
 634  	 protected $print_footer = true;
 635  
 636  	 /**
 637  	  * Header image logo.
 638  	  * @protected
 639  	  */
 640  	 protected $header_logo = '';
 641  
 642  	 /**
 643  	  * Width of header image logo in user units.
 644  	  * @protected
 645  	  */
 646  	 protected $header_logo_width = 30;
 647  
 648  	 /**
 649  	  * Title to be printed on default page header.
 650  	  * @protected
 651  	  */
 652  	 protected $header_title = '';
 653  
 654  	 /**
 655  	  * String to pring on page header after title.
 656  	  * @protected
 657  	  */
 658  	 protected $header_string = '';
 659  
 660  	 /**
 661  	  * Color for header text (RGB array).
 662  	  * @since 5.9.174 (2012-07-25)
 663  	  * @protected
 664  	  */
 665  	 protected $header_text_color = array(0,0,0);
 666  
 667  	 /**
 668  	  * Color for header line (RGB array).
 669  	  * @since 5.9.174 (2012-07-25)
 670  	  * @protected
 671  	  */
 672  	 protected $header_line_color = array(0,0,0);
 673  
 674  	 /**
 675  	  * Color for footer text (RGB array).
 676  	  * @since 5.9.174 (2012-07-25)
 677  	  * @protected
 678  	  */
 679  	 protected $footer_text_color = array(0,0,0);
 680  
 681  	 /**
 682  	  * Color for footer line (RGB array).
 683  	  * @since 5.9.174 (2012-07-25)
 684  	  * @protected
 685  	  */
 686  	 protected $footer_line_color = array(0,0,0);
 687  
 688  	 /**
 689  	  * Text shadow data array.
 690  	  * @since 5.9.174 (2012-07-25)
 691  	  * @protected
 692  	  */
 693  	 protected $txtshadow = array('enabled'=>false, 'depth_w'=>0, 'depth_h'=>0, 'color'=>false, 'opacity'=>1, 'blend_mode'=>'Normal');
 694  
 695  	 /**
 696  	  * Default number of columns for html table.
 697  	  * @protected
 698  	  */
 699  	 protected $default_table_columns = 4;
 700  
 701  	 // variables for html parser
 702  
 703  	 /**
 704  	  * HTML PARSER: array to store current link and rendering styles.
 705  	  * @protected
 706  	  */
 707  	 protected $HREF = array();
 708  
 709  	 /**
 710  	  * List of available fonts on filesystem.
 711  	  * @protected
 712  	  */
 713  	 protected $fontlist = array();
 714  
 715  	 /**
 716  	  * Current foreground color.
 717  	  * @protected
 718  	  */
 719  	 protected $fgcolor;
 720  
 721  	 /**
 722  	  * HTML PARSER: array of boolean values, true in case of ordered list (OL), false otherwise.
 723  	  * @protected
 724  	  */
 725  	 protected $listordered = array();
 726  
 727  	 /**
 728  	  * HTML PARSER: array count list items on nested lists.
 729  	  * @protected
 730  	  */
 731  	 protected $listcount = array();
 732  
 733  	 /**
 734  	  * HTML PARSER: current list nesting level.
 735  	  * @protected
 736  	  */
 737  	 protected $listnum = 0;
 738  
 739  	 /**
 740  	  * HTML PARSER: indent amount for lists.
 741  	  * @protected
 742  	  */
 743  	 protected $listindent = 0;
 744  
 745  	 /**
 746  	  * HTML PARSER: current list indententation level.
 747  	  * @protected
 748  	  */
 749  	 protected $listindentlevel = 0;
 750  
 751  	 /**
 752  	  * Current background color.
 753  	  * @protected
 754  	  */
 755  	 protected $bgcolor;
 756  
 757  	 /**
 758  	  * Temporary font size in points.
 759  	  * @protected
 760  	  */
 761  	 protected $tempfontsize = 10;
 762  
 763  	 /**
 764  	  * Spacer string for LI tags.
 765  	  * @protected
 766  	  */
 767  	 protected $lispacer = '';
 768  
 769  	 /**
 770  	  * Default encoding.
 771  	  * @protected
 772  	  * @since 1.53.0.TC010
 773  	  */
 774  	 protected $encoding = 'UTF-8';
 775  
 776  	 /**
 777  	  * Boolean flag to indicate if the document language is Right-To-Left.
 778  	  * @protected
 779  	  * @since 2.0.000
 780  	  */
 781  	 protected $rtl = false;
 782  
 783  	 /**
 784  	  * Boolean flag used to force RTL or LTR string direction.
 785  	  * @protected
 786  	  * @since 2.0.000
 787  	  */
 788  	 protected $tmprtl = false;
 789  
 790  	 // --- Variables used for document encryption:
 791  
 792  	 /**
 793  	  * IBoolean flag indicating whether document is protected.
 794  	  * @protected
 795  	  * @since 2.0.000 (2008-01-02)
 796  	  */
 797  	 protected $encrypted;
 798  
 799  	 /**
 800  	  * Array containing encryption settings.
 801  	  * @protected
 802  	  * @since 5.0.005 (2010-05-11)
 803  	  */
 804  	 protected $encryptdata = array();
 805  
 806  	 /**
 807  	  * Last RC4 key encrypted (cached for optimisation).
 808  	  * @protected
 809  	  * @since 2.0.000 (2008-01-02)
 810  	  */
 811  	 protected $last_enc_key;
 812  
 813  	 /**
 814  	  * Last RC4 computed key.
 815  	  * @protected
 816  	  * @since 2.0.000 (2008-01-02)
 817  	  */
 818  	 protected $last_enc_key_c;
 819  
 820  	 /**
 821  	  * File ID (used on document trailer).
 822  	  * @protected
 823  	  * @since 5.0.005 (2010-05-12)
 824  	  */
 825  	 protected $file_id;
 826  
 827  	 // --- bookmark ---
 828  
 829  	 /**
 830  	  * Outlines for bookmark.
 831  	  * @protected
 832  	  * @since 2.1.002 (2008-02-12)
 833  	  */
 834  	 protected $outlines = array();
 835  
 836  	 /**
 837  	  * Outline root for bookmark.
 838  	  * @protected
 839  	  * @since 2.1.002 (2008-02-12)
 840  	  */
 841  	 protected $OutlineRoot;
 842  
 843  	 // --- javascript and form ---
 844  
 845  	 /**
 846  	  * Javascript code.
 847  	  * @protected
 848  	  * @since 2.1.002 (2008-02-12)
 849  	  */
 850  	 protected $javascript = '';
 851  
 852  	 /**
 853  	  * Javascript counter.
 854  	  * @protected
 855  	  * @since 2.1.002 (2008-02-12)
 856  	  */
 857  	 protected $n_js;
 858  
 859  	 /**
 860  	  * line through state
 861  	  * @protected
 862  	  * @since 2.8.000 (2008-03-19)
 863  	  */
 864  	 protected $linethrough;
 865  
 866  	 /**
 867  	  * Array with additional document-wide usage rights for the document.
 868  	  * @protected
 869  	  * @since 5.8.014 (2010-08-23)
 870  	  */
 871  	 protected $ur = array();
 872  
 873  	 /**
 874  	  * DPI (Dot Per Inch) Document Resolution (do not change).
 875  	  * @protected
 876  	  * @since 3.0.000 (2008-03-27)
 877  	  */
 878  	 protected $dpi = 72;
 879  
 880  	 /**
 881  	  * Array of page numbers were a new page group was started (the page numbers are the keys of the array).
 882  	  * @protected
 883  	  * @since 3.0.000 (2008-03-27)
 884  	  */
 885  	 protected $newpagegroup = array();
 886  
 887  	 /**
 888  	  * Array that contains the number of pages in each page group.
 889  	  * @protected
 890  	  * @since 3.0.000 (2008-03-27)
 891  	  */
 892  	 protected $pagegroups = array();
 893  
 894  	 /**
 895  	  * Current page group number.
 896  	  * @protected
 897  	  * @since 3.0.000 (2008-03-27)
 898  	  */
 899  	 protected $currpagegroup = 0;
 900  
 901  	 /**
 902  	  * Array of transparency objects and parameters.
 903  	  * @protected
 904  	  * @since 3.0.000 (2008-03-27)
 905  	  */
 906  	 protected $extgstates;
 907  
 908  	 /**
 909  	  * Set the default JPEG compression quality (1-100).
 910  	  * @protected
 911  	  * @since 3.0.000 (2008-03-27)
 912  	  */
 913  	 protected $jpeg_quality;
 914  
 915  	 /**
 916  	  * Default cell height ratio.
 917  	  * @protected
 918  	  * @since 3.0.014 (2008-05-23)
 919  	  */
 920  	 protected $cell_height_ratio = K_CELL_HEIGHT_RATIO;
 921  
 922  	 /**
 923  	  * PDF viewer preferences.
 924  	  * @protected
 925  	  * @since 3.1.000 (2008-06-09)
 926  	  */
 927  	 protected $viewer_preferences;
 928  
 929  	 /**
 930  	  * A name object specifying how the document should be displayed when opened.
 931  	  * @protected
 932  	  * @since 3.1.000 (2008-06-09)
 933  	  */
 934  	 protected $PageMode;
 935  
 936  	 /**
 937  	  * Array for storing gradient information.
 938  	  * @protected
 939  	  * @since 3.1.000 (2008-06-09)
 940  	  */
 941  	 protected $gradients = array();
 942  
 943  	 /**
 944  	  * Array used to store positions inside the pages buffer (keys are the page numbers).
 945  	  * @protected
 946  	  * @since 3.2.000 (2008-06-26)
 947  	  */
 948  	 protected $intmrk = array();
 949  
 950  	 /**
 951  	  * Array used to store positions inside the pages buffer (keys are the page numbers).
 952  	  * @protected
 953  	  * @since 5.7.000 (2010-08-03)
 954  	  */
 955  	 protected $bordermrk = array();
 956  
 957  	 /**
 958  	  * Array used to store page positions to track empty pages (keys are the page numbers).
 959  	  * @protected
 960  	  * @since 5.8.007 (2010-08-18)
 961  	  */
 962  	 protected $emptypagemrk = array();
 963  
 964  	 /**
 965  	  * Array used to store content positions inside the pages buffer (keys are the page numbers).
 966  	  * @protected
 967  	  * @since 4.6.021 (2009-07-20)
 968  	  */
 969  	 protected $cntmrk = array();
 970  
 971  	 /**
 972  	  * Array used to store footer positions of each page.
 973  	  * @protected
 974  	  * @since 3.2.000 (2008-07-01)
 975  	  */
 976  	 protected $footerpos = array();
 977  
 978  	 /**
 979  	  * Array used to store footer length of each page.
 980  	  * @protected
 981  	  * @since 4.0.014 (2008-07-29)
 982  	  */
 983  	 protected $footerlen = array();
 984  
 985  	 /**
 986  	  * Boolean flag to indicate if a new line is created.
 987  	  * @protected
 988  	  * @since 3.2.000 (2008-07-01)
 989  	  */
 990  	 protected $newline = true;
 991  
 992  	 /**
 993  	  * End position of the latest inserted line.
 994  	  * @protected
 995  	  * @since 3.2.000 (2008-07-01)
 996  	  */
 997  	 protected $endlinex = 0;
 998  
 999  	 /**
1000  	  * PDF string for width value of the last line.
1001  	  * @protected
1002  	  * @since 4.0.006 (2008-07-16)
1003  	  */
1004  	 protected $linestyleWidth = '';
1005  
1006  	 /**
1007  	  * PDF string for CAP value of the last line.
1008  	  * @protected
1009  	  * @since 4.0.006 (2008-07-16)
1010  	  */
1011  	 protected $linestyleCap = '0 J';
1012  
1013  	 /**
1014  	  * PDF string for join value of the last line.
1015  	  * @protected
1016  	  * @since 4.0.006 (2008-07-16)
1017  	  */
1018  	 protected $linestyleJoin = '0 j';
1019  
1020  	 /**
1021  	  * PDF string for dash value of the last line.
1022  	  * @protected
1023  	  * @since 4.0.006 (2008-07-16)
1024  	  */
1025  	 protected $linestyleDash = '[] 0 d';
1026  
1027  	 /**
1028  	  * Boolean flag to indicate if marked-content sequence is open.
1029  	  * @protected
1030  	  * @since 4.0.013 (2008-07-28)
1031  	  */
1032  	 protected $openMarkedContent = false;
1033  
1034  	 /**
1035  	  * Count the latest inserted vertical spaces on HTML.
1036  	  * @protected
1037  	  * @since 4.0.021 (2008-08-24)
1038  	  */
1039  	 protected $htmlvspace = 0;
1040  
1041  	 /**
1042  	  * Array of Spot colors.
1043  	  * @protected
1044  	  * @since 4.0.024 (2008-09-12)
1045  	  */
1046  	 protected $spot_colors = array();
1047  
1048  	 /**
1049  	  * Symbol used for HTML unordered list items.
1050  	  * @protected
1051  	  * @since 4.0.028 (2008-09-26)
1052  	  */
1053  	 protected $lisymbol = '';
1054  
1055  	 /**
1056  	  * String used to mark the beginning and end of EPS image blocks.
1057  	  * @protected
1058  	  * @since 4.1.000 (2008-10-18)
1059  	  */
1060  	 protected $epsmarker = 'x#!#EPS#!#x';
1061  
1062  	 /**
1063  	  * Array of transformation matrix.
1064  	  * @protected
1065  	  * @since 4.2.000 (2008-10-29)
1066  	  */
1067  	 protected $transfmatrix = array();
1068  
1069  	 /**
1070  	  * Current key for transformation matrix.
1071  	  * @protected
1072  	  * @since 4.8.005 (2009-09-17)
1073  	  */
1074  	 protected $transfmatrix_key = 0;
1075  
1076  	 /**
1077  	  * Booklet mode for double-sided pages.
1078  	  * @protected
1079  	  * @since 4.2.000 (2008-10-29)
1080  	  */
1081  	 protected $booklet = false;
1082  
1083  	 /**
1084  	  * Epsilon value used for float calculations.
1085  	  * @protected
1086  	  * @since 4.2.000 (2008-10-29)
1087  	  */
1088  	 protected $feps = 0.005;
1089  
1090  	 /**
1091  	  * Array used for custom vertical spaces for HTML tags.
1092  	  * @protected
1093  	  * @since 4.2.001 (2008-10-30)
1094  	  */
1095  	 protected $tagvspaces = array();
1096  
1097  	 /**
1098  	  * HTML PARSER: custom indent amount for lists. Negative value means disabled.
1099  	  * @protected
1100  	  * @since 4.2.007 (2008-11-12)
1101  	  */
1102  	 protected $customlistindent = -1;
1103  
1104  	 /**
1105  	  * Boolean flag to indicate if the border of the cell sides that cross the page should be removed.
1106  	  * @protected
1107  	  * @since 4.2.010 (2008-11-14)
1108  	  */
1109  	 protected $opencell = true;
1110  
1111  	 /**
1112  	  * Array of files to embedd.
1113  	  * @protected
1114  	  * @since 4.4.000 (2008-12-07)
1115  	  */
1116  	 protected $embeddedfiles = array();
1117  
1118  	 /**
1119  	  * Boolean flag to indicate if we are inside a PRE tag.
1120  	  * @protected
1121  	  * @since 4.4.001 (2008-12-08)
1122  	  */
1123  	 protected $premode = false;
1124  
1125  	 /**
1126  	  * Array used to store positions of graphics transformation blocks inside the page buffer.
1127  	  * keys are the page numbers
1128  	  * @protected
1129  	  * @since 4.4.002 (2008-12-09)
1130  	  */
1131  	 protected $transfmrk = array();
1132  
1133  	 /**
1134  	  * Default color for html links.
1135  	  * @protected
1136  	  * @since 4.4.003 (2008-12-09)
1137  	  */
1138  	 protected $htmlLinkColorArray = array(0, 0, 255);
1139  
1140  	 /**
1141  	  * Default font style to add to html links.
1142  	  * @protected
1143  	  * @since 4.4.003 (2008-12-09)
1144  	  */
1145  	 protected $htmlLinkFontStyle = 'U';
1146  
1147  	 /**
1148  	  * Counts the number of pages.
1149  	  * @protected
1150  	  * @since 4.5.000 (2008-12-31)
1151  	  */
1152  	 protected $numpages = 0;
1153  
1154  	 /**
1155  	  * Array containing page lengths in bytes.
1156  	  * @protected
1157  	  * @since 4.5.000 (2008-12-31)
1158  	  */
1159  	 protected $pagelen = array();
1160  
1161  	 /**
1162  	  * Counts the number of pages.
1163  	  * @protected
1164  	  * @since 4.5.000 (2008-12-31)
1165  	  */
1166  	 protected $numimages = 0;
1167  
1168  	 /**
1169  	  * Store the image keys.
1170  	  * @protected
1171  	  * @since 4.5.000 (2008-12-31)
1172  	  */
1173  	 protected $imagekeys = array();
1174  
1175  	 /**
1176  	  * Length of the buffer in bytes.
1177  	  * @protected
1178  	  * @since 4.5.000 (2008-12-31)
1179  	  */
1180  	 protected $bufferlen = 0;
1181  
1182  	 /**
1183  	  * Counts the number of fonts.
1184  	  * @protected
1185  	  * @since 4.5.000 (2009-01-02)
1186  	  */
1187  	 protected $numfonts = 0;
1188  
1189  	 /**
1190  	  * Store the font keys.
1191  	  * @protected
1192  	  * @since 4.5.000 (2009-01-02)
1193  	  */
1194  	 protected $fontkeys = array();
1195  
1196  	 /**
1197  	  * Store the font object IDs.
1198  	  * @protected
1199  	  * @since 4.8.001 (2009-09-09)
1200  	  */
1201  	 protected $font_obj_ids = array();
1202  
1203  	 /**
1204  	  * Store the fage status (true when opened, false when closed).
1205  	  * @protected
1206  	  * @since 4.5.000 (2009-01-02)
1207  	  */
1208  	 protected $pageopen = array();
1209  
1210  	 /**
1211  	  * Default monospace font.
1212  	  * @protected
1213  	  * @since 4.5.025 (2009-03-10)
1214  	  */
1215  	 protected $default_monospaced_font = 'courier';
1216  
1217  	 /**
1218  	  * Cloned copy of the current class object.
1219  	  * @protected
1220  	  * @since 4.5.029 (2009-03-19)
1221  	  */
1222  	 protected $objcopy;
1223  
1224  	 /**
1225  	  * Array used to store the lengths of cache files.
1226  	  * @protected
1227  	  * @since 4.5.029 (2009-03-19)
1228  	  */
1229  	 protected $cache_file_length = array();
1230  
1231  	 /**
1232  	  * Table header content to be repeated on each new page.
1233  	  * @protected
1234  	  * @since 4.5.030 (2009-03-20)
1235  	  */
1236  	 protected $thead = '';
1237  
1238  	 /**
1239  	  * Margins used for table header.
1240  	  * @protected
1241  	  * @since 4.5.030 (2009-03-20)
1242  	  */
1243  	 protected $theadMargins = array();
1244  
1245  	 /**
1246  	  * Boolean flag to enable document digital signature.
1247  	  * @protected
1248  	  * @since 4.6.005 (2009-04-24)
1249  	  */
1250  	 protected $sign = false;
1251  
1252  	 /**
1253  	  * Digital signature data.
1254  	  * @protected
1255  	  * @since 4.6.005 (2009-04-24)
1256  	  */
1257  	 protected $signature_data = array();
1258  
1259  	 /**
1260  	  * Digital signature max length.
1261  	  * @protected
1262  	  * @since 4.6.005 (2009-04-24)
1263  	  */
1264  	 protected $signature_max_length = 11742;
1265  
1266  	 /**
1267  	  * Data for digital signature appearance.
1268  	  * @protected
1269  	  * @since 5.3.011 (2010-06-16)
1270  	  */
1271  	 protected $signature_appearance = array('page' => 1, 'rect' => '0 0 0 0');
1272  
1273  	 /**
1274  	  * Array of empty digital signature appearances.
1275  	  * @protected
1276  	  * @since 5.9.101 (2011-07-06)
1277  	  */
1278  	 protected $empty_signature_appearance = array();
1279  
1280  	 /**
1281  	  * Boolean flag to enable document timestamping with TSA.
1282  	  * @protected
1283  	  * @since 6.0.085 (2014-06-19)
1284  	  */
1285  	 protected $tsa_timestamp = false;
1286  
1287  	 /**
1288  	  * Timestamping data.
1289  	  * @protected
1290  	  * @since 6.0.085 (2014-06-19)
1291  	  */
1292  	 protected $tsa_data = array();
1293  
1294  	 /**
1295  	  * Regular expression used to find blank characters (required for word-wrapping).
1296  	  * @protected
1297  	  * @since 4.6.006 (2009-04-28)
1298  	  */
1299  	 protected $re_spaces = '/[^\S\xa0]/';
1300  
1301  	 /**
1302  	  * Array of $re_spaces parts.
1303  	  * @protected
1304  	  * @since 5.5.011 (2010-07-09)
1305  	  */
1306  	 protected $re_space = array('p' => '[^\S\xa0]', 'm' => '');
1307  
1308  	 /**
1309  	  * Digital signature object ID.
1310  	  * @protected
1311  	  * @since 4.6.022 (2009-06-23)
1312  	  */
1313  	 protected $sig_obj_id = 0;
1314  
1315  	 /**
1316  	  * ID of page objects.
1317  	  * @protected
1318  	  * @since 4.7.000 (2009-08-29)
1319  	  */
1320  	 protected $page_obj_id = array();
1321  
1322  	 /**
1323  	  * List of form annotations IDs.
1324  	  * @protected
1325  	  * @since 4.8.000 (2009-09-07)
1326  	  */
1327  	 protected $form_obj_id = array();
1328  
1329  	 /**
1330  	  * Deafult Javascript field properties. Possible values are described on official Javascript for Acrobat API reference. Annotation options can be directly specified using the 'aopt' entry.
1331  	  * @protected
1332  	  * @since 4.8.000 (2009-09-07)
1333  	  */
1334  	 protected $default_form_prop = array('lineWidth'=>1, 'borderStyle'=>'solid', 'fillColor'=>array(255, 255, 255), 'strokeColor'=>array(128, 128, 128));
1335  
1336  	 /**
1337  	  * Javascript objects array.
1338  	  * @protected
1339  	  * @since 4.8.000 (2009-09-07)
1340  	  */
1341  	 protected $js_objects = array();
1342  
1343  	 /**
1344  	  * Current form action (used during XHTML rendering).
1345  	  * @protected
1346  	  * @since 4.8.000 (2009-09-07)
1347  	  */
1348  	 protected $form_action = '';
1349  
1350  	 /**
1351  	  * Current form encryption type (used during XHTML rendering).
1352  	  * @protected
1353  	  * @since 4.8.000 (2009-09-07)
1354  	  */
1355  	 protected $form_enctype = 'application/x-www-form-urlencoded';
1356  
1357  	 /**
1358  	  * Current method to submit forms.
1359  	  * @protected
1360  	  * @since 4.8.000 (2009-09-07)
1361  	  */
1362  	 protected $form_mode = 'post';
1363  
1364  	 /**
1365  	  * List of fonts used on form fields (fontname => fontkey).
1366  	  * @protected
1367  	  * @since 4.8.001 (2009-09-09)
1368  	  */
1369  	 protected $annotation_fonts = array();
1370  
1371  	 /**
1372  	  * List of radio buttons parent objects.
1373  	  * @protected
1374  	  * @since 4.8.001 (2009-09-09)
1375  	  */
1376  	 protected $radiobutton_groups = array();
1377  
1378  	 /**
1379  	  * List of radio group objects IDs.
1380  	  * @protected
1381  	  * @since 4.8.001 (2009-09-09)
1382  	  */
1383  	 protected $radio_groups = array();
1384  
1385  	 /**
1386  	  * Text indentation value (used for text-indent CSS attribute).
1387  	  * @protected
1388  	  * @since 4.8.006 (2009-09-23)
1389  	  */
1390  	 protected $textindent = 0;
1391  
1392  	 /**
1393  	  * Store page number when startTransaction() is called.
1394  	  * @protected
1395  	  * @since 4.8.006 (2009-09-23)
1396  	  */
1397  	 protected $start_transaction_page = 0;
1398  
1399  	 /**
1400  	  * Store Y position when startTransaction() is called.
1401  	  * @protected
1402  	  * @since 4.9.001 (2010-03-28)
1403  	  */
1404  	 protected $start_transaction_y = 0;
1405  
1406  	 /**
1407  	  * True when we are printing the thead section on a new page.
1408  	  * @protected
1409  	  * @since 4.8.027 (2010-01-25)
1410  	  */
1411  	 protected $inthead = false;
1412  
1413  	 /**
1414  	  * Array of column measures (width, space, starting Y position).
1415  	  * @protected
1416  	  * @since 4.9.001 (2010-03-28)
1417  	  */
1418  	 protected $columns = array();
1419  
1420  	 /**
1421  	  * Number of colums.
1422  	  * @protected
1423  	  * @since 4.9.001 (2010-03-28)
1424  	  */
1425  	 protected $num_columns = 1;
1426  
1427  	 /**
1428  	  * Current column number.
1429  	  * @protected
1430  	  * @since 4.9.001 (2010-03-28)
1431  	  */
1432  	 protected $current_column = 0;
1433  
1434  	 /**
1435  	  * Starting page for columns.
1436  	  * @protected
1437  	  * @since 4.9.001 (2010-03-28)
1438  	  */
1439  	 protected $column_start_page = 0;
1440  
1441  	 /**
1442  	  * Maximum page and column selected.
1443  	  * @protected
1444  	  * @since 5.8.000 (2010-08-11)
1445  	  */
1446  	 protected $maxselcol = array('page' => 0, 'column' => 0);
1447  
1448  	 /**
1449  	  * Array of: X difference between table cell x start and starting page margin, cellspacing, cellpadding.
1450  	  * @protected
1451  	  * @since 5.8.000 (2010-08-11)
1452  	  */
1453  	 protected $colxshift = array('x' => 0, 's' => array('H' => 0, 'V' => 0), 'p' => array('L' => 0, 'T' => 0, 'R' => 0, 'B' => 0));
1454  
1455  	 /**
1456  	  * Text rendering mode: 0 = Fill text; 1 = Stroke text; 2 = Fill, then stroke text; 3 = Neither fill nor stroke text (invisible); 4 = Fill text and add to path for clipping; 5 = Stroke text and add to path for clipping; 6 = Fill, then stroke text and add to path for clipping; 7 = Add text to path for clipping.
1457  	  * @protected
1458  	  * @since 4.9.008 (2010-04-03)
1459  	  */
1460  	 protected $textrendermode = 0;
1461  
1462  	 /**
1463  	  * Text stroke width in doc units.
1464  	  * @protected
1465  	  * @since 4.9.008 (2010-04-03)
1466  	  */
1467  	 protected $textstrokewidth = 0;
1468  
1469  	 /**
1470  	  * Current stroke color.
1471  	  * @protected
1472  	  * @since 4.9.008 (2010-04-03)
1473  	  */
1474  	 protected $strokecolor;
1475  
1476  	 /**
1477  	  * Default unit of measure for document.
1478  	  * @protected
1479  	  * @since 5.0.000 (2010-04-22)
1480  	  */
1481  	 protected $pdfunit = 'mm';
1482  
1483  	 /**
1484  	  * Boolean flag true when we are on TOC (Table Of Content) page.
1485  	  * @protected
1486  	  */
1487  	 protected $tocpage = false;
1488  
1489  	 /**
1490  	  * Boolean flag: if true convert vector images (SVG, EPS) to raster image using GD or ImageMagick library.
1491  	  * @protected
1492  	  * @since 5.0.000 (2010-04-26)
1493  	  */
1494  	 protected $rasterize_vector_images = false;
1495  
1496  	 /**
1497  	  * Boolean flag: if true enables font subsetting by default.
1498  	  * @protected
1499  	  * @since 5.3.002 (2010-06-07)
1500  	  */
1501  	 protected $font_subsetting = true;
1502  
1503  	 /**
1504  	  * Array of default graphic settings.
1505  	  * @protected
1506  	  * @since 5.5.008 (2010-07-02)
1507  	  */
1508  	 protected $default_graphic_vars = array();
1509  
1510  	 /**
1511  	  * Array of XObjects.
1512  	  * @protected
1513  	  * @since 5.8.014 (2010-08-23)
1514  	  */
1515  	 protected $xobjects = array();
1516  
1517  	 /**
1518  	  * Boolean value true when we are inside an XObject.
1519  	  * @protected
1520  	  * @since 5.8.017 (2010-08-24)
1521  	  */
1522  	 protected $inxobj = false;
1523  
1524  	 /**
1525  	  * Current XObject ID.
1526  	  * @protected
1527  	  * @since 5.8.017 (2010-08-24)
1528  	  */
1529  	 protected $xobjid = '';
1530  
1531  	 /**
1532  	  * Percentage of character stretching.
1533  	  * @protected
1534  	  * @since 5.9.000 (2010-09-29)
1535  	  */
1536  	 protected $font_stretching = 100;
1537  
1538  	 /**
1539  	  * Increases or decreases the space between characters in a text by the specified amount (tracking).
1540  	  * @protected
1541  	  * @since 5.9.000 (2010-09-29)
1542  	  */
1543  	 protected $font_spacing = 0;
1544  
1545  	 /**
1546  	  * Array of no-write regions.
1547  	  * ('page' => page number or empy for current page, 'xt' => X top, 'yt' => Y top, 'xb' => X bottom, 'yb' => Y bottom, 'side' => page side 'L' = left or 'R' = right)
1548  	  * @protected
1549  	  * @since 5.9.003 (2010-10-14)
1550  	  */
1551  	 protected $page_regions = array();
1552  
1553  	 /**
1554  	  * Boolean value true when page region check is active.
1555  	  * @protected
1556  	  */
1557  	 protected $check_page_regions = true;
1558  
1559  	 /**
1560  	  * Array of PDF layers data.
1561  	  * @protected
1562  	  * @since 5.9.102 (2011-07-13)
1563  	  */
1564  	 protected $pdflayers = array();
1565  
1566  	 /**
1567  	  * A dictionary of names and corresponding destinations (Dests key on document Catalog).
1568  	  * @protected
1569  	  * @since 5.9.097 (2011-06-23)
1570  	  */
1571  	 protected $dests = array();
1572  
1573  	 /**
1574  	  * Object ID for Named Destinations
1575  	  * @protected
1576  	  * @since 5.9.097 (2011-06-23)
1577  	  */
1578  	 protected $n_dests;
1579  
1580  	 /**
1581  	  * Embedded Files Names
1582  	  * @protected
1583  	  * @since 5.9.204 (2013-01-23)
1584  	  */
1585  	 protected $efnames = array();
1586  
1587  	 /**
1588  	  * Directory used for the last SVG image.
1589  	  * @protected
1590  	  * @since 5.0.000 (2010-05-05)
1591  	  */
1592  	 protected $svgdir = '';
1593  
1594  	 /**
1595  	  *  Deafult unit of measure for SVG.
1596  	  * @protected
1597  	  * @since 5.0.000 (2010-05-02)
1598  	  */
1599  	 protected $svgunit = 'px';
1600  
1601  	 /**
1602  	  * Array of SVG gradients.
1603  	  * @protected
1604  	  * @since 5.0.000 (2010-05-02)
1605  	  */
1606  	 protected $svggradients = array();
1607  
1608  	 /**
1609  	  * ID of last SVG gradient.
1610  	  * @protected
1611  	  * @since 5.0.000 (2010-05-02)
1612  	  */
1613  	 protected $svggradientid = 0;
1614  
1615  	 /**
1616  	  * Boolean value true when in SVG defs group.
1617  	  * @protected
1618  	  * @since 5.0.000 (2010-05-02)
1619  	  */
1620  	 protected $svgdefsmode = false;
1621  
1622  	 /**
1623  	  * Array of SVG defs.
1624  	  * @protected
1625  	  * @since 5.0.000 (2010-05-02)
1626  	  */
1627  	 protected $svgdefs = array();
1628  
1629  	 /**
1630  	  * Boolean value true when in SVG clipPath tag.
1631  	  * @protected
1632  	  * @since 5.0.000 (2010-04-26)
1633  	  */
1634  	 protected $svgclipmode = false;
1635  
1636  	 /**
1637  	  * Array of SVG clipPath commands.
1638  	  * @protected
1639  	  * @since 5.0.000 (2010-05-02)
1640  	  */
1641  	 protected $svgclippaths = array();
1642  
1643  	 /**
1644  	  * Array of SVG clipPath tranformation matrix.
1645  	  * @protected
1646  	  * @since 5.8.022 (2010-08-31)
1647  	  */
1648  	 protected $svgcliptm = array();
1649  
1650  	 /**
1651  	  * ID of last SVG clipPath.
1652  	  * @protected
1653  	  * @since 5.0.000 (2010-05-02)
1654  	  */
1655  	 protected $svgclipid = 0;
1656  
1657  	 /**
1658  	  * SVG text.
1659  	  * @protected
1660  	  * @since 5.0.000 (2010-05-02)
1661  	  */
1662  	 protected $svgtext = '';
1663  
1664  	 /**
1665  	  * SVG text properties.
1666  	  * @protected
1667  	  * @since 5.8.013 (2010-08-23)
1668  	  */
1669  	 protected $svgtextmode = array();
1670  
1671  	 /**
1672  	  * Array of SVG properties.
1673  	  * @protected
1674  	  * @since 5.0.000 (2010-05-02)
1675  	  */
1676  	 protected $svgstyles = array(array(
1677  	 	 'alignment-baseline' => 'auto',
1678  	 	 'baseline-shift' => 'baseline',
1679  	 	 'clip' => 'auto',
1680  	 	 'clip-path' => 'none',
1681  	 	 'clip-rule' => 'nonzero',
1682  	 	 'color' => 'black',
1683  	 	 'color-interpolation' => 'sRGB',
1684  	 	 'color-interpolation-filters' => 'linearRGB',
1685  	 	 'color-profile' => 'auto',
1686  	 	 'color-rendering' => 'auto',
1687  	 	 'cursor' => 'auto',
1688  	 	 'direction' => 'ltr',
1689  	 	 'display' => 'inline',
1690  	 	 'dominant-baseline' => 'auto',
1691  	 	 'enable-background' => 'accumulate',
1692  	 	 'fill' => 'black',
1693  	 	 'fill-opacity' => 1,
1694  	 	 'fill-rule' => 'nonzero',
1695  	 	 'filter' => 'none',
1696  	 	 'flood-color' => 'black',
1697  	 	 'flood-opacity' => 1,
1698  	 	 'font' => '',
1699  	 	 'font-family' => 'helvetica',
1700  	 	 'font-size' => 'medium',
1701  	 	 'font-size-adjust' => 'none',
1702  	 	 'font-stretch' => 'normal',
1703  	 	 'font-style' => 'normal',
1704  	 	 'font-variant' => 'normal',
1705  	 	 'font-weight' => 'normal',
1706  	 	 'glyph-orientation-horizontal' => '0deg',
1707  	 	 'glyph-orientation-vertical' => 'auto',
1708  	 	 'image-rendering' => 'auto',
1709  	 	 'kerning' => 'auto',
1710  	 	 'letter-spacing' => 'normal',
1711  	 	 'lighting-color' => 'white',
1712  	 	 'marker' => '',
1713  	 	 'marker-end' => 'none',
1714  	 	 'marker-mid' => 'none',
1715  	 	 'marker-start' => 'none',
1716  	 	 'mask' => 'none',
1717  	 	 'opacity' => 1,
1718  	 	 'overflow' => 'auto',
1719  	 	 'pointer-events' => 'visiblePainted',
1720  	 	 'shape-rendering' => 'auto',
1721  	 	 'stop-color' => 'black',
1722  	 	 'stop-opacity' => 1,
1723  	 	 'stroke' => 'none',
1724  	 	 'stroke-dasharray' => 'none',
1725  	 	 'stroke-dashoffset' => 0,
1726  	 	 'stroke-linecap' => 'butt',
1727  	 	 'stroke-linejoin' => 'miter',
1728  	 	 'stroke-miterlimit' => 4,
1729  	 	 'stroke-opacity' => 1,
1730  	 	 'stroke-width' => 1,
1731  	 	 'text-anchor' => 'start',
1732  	 	 'text-decoration' => 'none',
1733  	 	 'text-rendering' => 'auto',
1734  	 	 'unicode-bidi' => 'normal',
1735  	 	 'visibility' => 'visible',
1736  	 	 'word-spacing' => 'normal',
1737  	 	 'writing-mode' => 'lr-tb',
1738  	 	 'text-color' => 'black',
1739  	 	 'transfmatrix' => array(1, 0, 0, 1, 0, 0)
1740  	 	 ));
1741  
1742  	 /**
1743  	  * If true force sRGB color profile for all document.
1744  	  * @protected
1745  	  * @since 5.9.121 (2011-09-28)
1746  	  */
1747  	 protected $force_srgb = false;
1748  
1749  	 /**
1750  	  * If true set the document to PDF/A mode.
1751  	  * @protected
1752  	  * @since 5.9.121 (2011-09-27)
1753  	  */
1754  	 protected $pdfa_mode = false;
1755  
1756  	 /**
1757  	  * version of PDF/A mode (1 - 3).
1758  	  * @protected
1759  	  * @since 6.2.26 (2019-03-12)
1760  	  */
1761  	 protected $pdfa_version = 1;
1762  
1763  	 /**
1764  	  * Document creation date-time
1765  	  * @protected
1766  	  * @since 5.9.152 (2012-03-22)
1767  	  */
1768  	 protected $doc_creation_timestamp;
1769  
1770  	 /**
1771  	  * Document modification date-time
1772  	  * @protected
1773  	  * @since 5.9.152 (2012-03-22)
1774  	  */
1775  	 protected $doc_modification_timestamp;
1776  
1777  	 /**
1778  	  * Custom XMP data.
1779  	  * @protected
1780  	  * @since 5.9.128 (2011-10-06)
1781  	  */
1782  	 protected $custom_xmp = '';
1783  
1784  	 /**
1785  	  * Custom XMP RDF data.
1786  	  * @protected
1787  	  * @since 6.3.0 (2019-09-19)
1788  	  */
1789  	 protected $custom_xmp_rdf = '';
1790  
1791  	 /**
1792  	  * Overprint mode array.
1793  	  * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008).
1794  	  * @protected
1795  	  * @since 5.9.152 (2012-03-23)
1796  	  */
1797  	 protected $overprint = array('OP' => false, 'op' => false, 'OPM' => 0);
1798  
1799  	 /**
1800  	  * Alpha mode array.
1801  	  * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008).
1802  	  * @protected
1803  	  * @since 5.9.152 (2012-03-23)
1804  	  */
1805  	 protected $alpha = array('CA' => 1, 'ca' => 1, 'BM' => '/Normal', 'AIS' => false);
1806  
1807  	 /**
1808  	  * Define the page boundaries boxes to be set on document.
1809  	  * @protected
1810  	  * @since 5.9.152 (2012-03-23)
1811  	  */
1812  	 protected $page_boxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox');
1813  
1814  	 /**
1815  	  * If true print TCPDF meta link.
1816  	  * @protected
1817  	  * @since 5.9.152 (2012-03-23)
1818  	  */
1819  	 protected $tcpdflink = true;
1820  
1821  	 /**
1822  	  * Cache array for computed GD gamma values.
1823  	  * @protected
1824  	  * @since 5.9.1632 (2012-06-05)
1825  	  */
1826  	 protected $gdgammacache = array();
1827  
1828      /**
1829       * Cache array for file content
1830       * @protected
1831       * @var array
1832       * @sinde 6.3.5 (2020-09-28)
1833       */
1834  	 protected $fileContentCache = array();
1835  
1836  	 /**
1837  	  * Whether to allow local file path in image html tags, when prefixed with file://
1838  	  *
1839  	  * @var bool
1840  	  * @protected
1841  	  * @since 6.4 (2020-07-23)
1842  	  */
1843  	 protected $allowLocalFiles = false;
1844  
1845  	 //------------------------------------------------------------
1846  	 // METHODS
1847  	 //------------------------------------------------------------
1848  
1849  	 /**
1850  	  * This is the class constructor.
1851  	  * It allows to set up the page format, the orientation and the measure unit used in all the methods (except for the font sizes).
1852  	  *
1853  	  * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or Portrait (default)</li><li>L or Landscape</li><li>'' (empty string) for automatic orientation</li></ul>
1854  	  * @param $unit (string) User measure unit. Possible values are:<ul><li>pt: point</li><li>mm: millimeter (default)</li><li>cm: centimeter</li><li>in: inch</li></ul><br />A point equals 1/72 of inch, that is to say about 0.35 mm (an inch being 2.54 cm). This is a very common unit in typography; font sizes are expressed in that unit.
1855  	  * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat().
1856  	  * @param $unicode (boolean) TRUE means that the input text is unicode (default = true)
1857  	  * @param $encoding (string) Charset encoding (used only when converting back html entities); default is UTF-8.
1858  	  * @param $diskcache (boolean) DEPRECATED FEATURE
1859  	  * @param $pdfa (integer) If not false, set the document to PDF/A mode and the good version (1 or 3).
1860  	  * @public
1861  	  * @see getPageSizeFromFormat(), setPageFormat()
1862  	  */
1863  	public function __construct($orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding='UTF-8', $diskcache=false, $pdfa=false) {
1864  	 	 // set file ID for trailer
1865  	 	 $serformat = (is_array($format) ? json_encode($format) : $format);
1866  	 	 $this->file_id = md5(TCPDF_STATIC::getRandomSeed('TCPDF'.$orientation.$unit.$serformat.$encoding));
1867  	 	 $this->font_obj_ids = array();
1868  	 	 $this->page_obj_id = array();
1869  	 	 $this->form_obj_id = array();
1870  
1871  	 	 // set pdf/a mode
1872  	 	 if ($pdfa != false) {
1873  	 	 	 $this->pdfa_mode = true;
1874  	 	 	 $this->pdfa_version = $pdfa;  // 1 or 3
1875  	 	 } else
1876  	 	 	 $this->pdfa_mode = false;
1877  
1878  	 	 $this->force_srgb = false;
1879  	 	 // set language direction
1880  	 	 $this->rtl = false;
1881  	 	 $this->tmprtl = false;
1882  	 	 // some checks
1883  	 	 $this->_dochecks();
1884  	 	 // initialization of properties
1885  	 	 $this->isunicode = $unicode;
1886  	 	 $this->page = 0;
1887  	 	 $this->transfmrk[0] = array();
1888  	 	 $this->pagedim = array();
1889  	 	 $this->n = 2;
1890  	 	 $this->buffer = '';
1891  	 	 $this->pages = array();
1892  	 	 $this->state = 0;
1893  	 	 $this->fonts = array();
1894  	 	 $this->FontFiles = array();
1895  	 	 $this->diffs = array();
1896  	 	 $this->images = array();
1897  	 	 $this->links = array();
1898  	 	 $this->gradients = array();
1899  	 	 $this->InFooter = false;
1900  	 	 $this->lasth = 0;
1901  	 	 $this->FontFamily = defined('PDF_FONT_NAME_MAIN')?PDF_FONT_NAME_MAIN:'helvetica';
1902  	 	 $this->FontStyle = '';
1903  	 	 $this->FontSizePt = 12;
1904  	 	 $this->underline = false;
1905  	 	 $this->overline = false;
1906  	 	 $this->linethrough = false;
1907  	 	 $this->DrawColor = '0 G';
1908  	 	 $this->FillColor = '0 g';
1909  	 	 $this->TextColor = '0 g';
1910  	 	 $this->ColorFlag = false;
1911  	 	 $this->pdflayers = array();
1912  	 	 // encryption values
1913  	 	 $this->encrypted = false;
1914  	 	 $this->last_enc_key = '';
1915  	 	 // standard Unicode fonts
1916  	 	 $this->CoreFonts = array(
1917  	 	 	 'courier'=>'Courier',
1918  	 	 	 'courierB'=>'Courier-Bold',
1919  	 	 	 'courierI'=>'Courier-Oblique',
1920  	 	 	 'courierBI'=>'Courier-BoldOblique',
1921  	 	 	 'helvetica'=>'Helvetica',
1922  	 	 	 'helveticaB'=>'Helvetica-Bold',
1923  	 	 	 'helveticaI'=>'Helvetica-Oblique',
1924  	 	 	 'helveticaBI'=>'Helvetica-BoldOblique',
1925  	 	 	 'times'=>'Times-Roman',
1926  	 	 	 'timesB'=>'Times-Bold',
1927  	 	 	 'timesI'=>'Times-Italic',
1928  	 	 	 'timesBI'=>'Times-BoldItalic',
1929  	 	 	 'symbol'=>'Symbol',
1930  	 	 	 'zapfdingbats'=>'ZapfDingbats'
1931  	 	 );
1932  	 	 // set scale factor
1933  	 	 $this->setPageUnit($unit);
1934  	 	 // set page format and orientation
1935  	 	 $this->setPageFormat($format, $orientation);
1936  	 	 // page margins (1 cm)
1937  	 	 $margin = 28.35 / $this->k;
1938  	 	 $this->SetMargins($margin, $margin);
1939  	 	 $this->clMargin = $this->lMargin;
1940  	 	 $this->crMargin = $this->rMargin;
1941  	 	 // internal cell padding
1942  	 	 $cpadding = $margin / 10;
1943  	 	 $this->setCellPaddings($cpadding, 0, $cpadding, 0);
1944  	 	 // cell margins
1945  	 	 $this->setCellMargins(0, 0, 0, 0);
1946  	 	 // line width (0.2 mm)
1947  	 	 $this->LineWidth = 0.57 / $this->k;
1948  	 	 $this->linestyleWidth = sprintf('%F w', ($this->LineWidth * $this->k));
1949  	 	 $this->linestyleCap = '0 J';
1950  	 	 $this->linestyleJoin = '0 j';
1951  	 	 $this->linestyleDash = '[] 0 d';
1952  	 	 // automatic page break
1953  	 	 $this->SetAutoPageBreak(true, (2 * $margin));
1954  	 	 // full width display mode
1955  	 	 $this->SetDisplayMode('fullwidth');
1956  	 	 // compression
1957  	 	 $this->SetCompression();
1958  	 	 // set default PDF version number
1959  	 	 $this->setPDFVersion();
1960  	 	 $this->tcpdflink = true;
1961  	 	 $this->encoding = $encoding;
1962  	 	 $this->HREF = array();
1963  	 	 $this->getFontsList();
1964  	 	 $this->fgcolor = array('R' => 0, 'G' => 0, 'B' => 0);
1965  	 	 $this->strokecolor = array('R' => 0, 'G' => 0, 'B' => 0);
1966  	 	 $this->bgcolor = array('R' => 255, 'G' => 255, 'B' => 255);
1967  	 	 $this->extgstates = array();
1968  	 	 $this->setTextShadow();
1969  	 	 // signature
1970  	 	 $this->sign = false;
1971  	 	 $this->tsa_timestamp = false;
1972  	 	 $this->tsa_data = array();
1973  	 	 $this->signature_appearance = array('page' => 1, 'rect' => '0 0 0 0', 'name' => 'Signature');
1974  	 	 $this->empty_signature_appearance = array();
1975  	 	 // user's rights
1976  	 	 $this->ur['enabled'] = false;
1977  	 	 $this->ur['document'] = '/FullSave';
1978  	 	 $this->ur['annots'] = '/Create/Delete/Modify/Copy/Import/Export';
1979  	 	 $this->ur['form'] = '/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate';
1980  	 	 $this->ur['signature'] = '/Modify';
1981  	 	 $this->ur['ef'] = '/Create/Delete/Modify/Import';
1982  	 	 $this->ur['formex'] = '';
1983  	 	 // set default JPEG quality
1984  	 	 $this->jpeg_quality = 75;
1985  	 	 // initialize some settings
1986  	 	 TCPDF_FONTS::utf8Bidi(array(), '', false, $this->isunicode, $this->CurrentFont);
1987  	 	 // set default font
1988  	 	 $this->SetFont($this->FontFamily, $this->FontStyle, $this->FontSizePt);
1989  	 	 $this->setHeaderFont(array($this->FontFamily, $this->FontStyle, $this->FontSizePt));
1990  	 	 $this->setFooterFont(array($this->FontFamily, $this->FontStyle, $this->FontSizePt));
1991  	 	 // check if PCRE Unicode support is enabled
1992  	 	 if ($this->isunicode AND (@preg_match('/\pL/u', 'a') == 1)) {
1993  	 	 	 // PCRE unicode support is turned ON
1994  	 	 	 // \s     : any whitespace character
1995  	 	 	 // \p{Z}  : any separator
1996  	 	 	 // \p{Lo} : Unicode letter or ideograph that does not have lowercase and uppercase variants. Is used to chunk chinese words.
1997  	 	 	 // \xa0   : Unicode Character 'NO-BREAK SPACE' (U+00A0)
1998  	 	 	 //$this->setSpacesRE('/(?!\xa0)[\s\p{Z}\p{Lo}]/u');
1999  	 	 	 $this->setSpacesRE('/(?!\xa0)[\s\p{Z}]/u');
2000  	 	 } else {
2001  	 	 	 // PCRE unicode support is turned OFF
2002  	 	 	 $this->setSpacesRE('/[^\S\xa0]/');
2003  	 	 }
2004  	 	 $this->default_form_prop = array('lineWidth'=>1, 'borderStyle'=>'solid', 'fillColor'=>array(255, 255, 255), 'strokeColor'=>array(128, 128, 128));
2005  	 	 // set document creation and modification timestamp
2006  	 	 $this->doc_creation_timestamp = time();
2007  	 	 $this->doc_modification_timestamp = $this->doc_creation_timestamp;
2008  	 	 // get default graphic vars
2009  	 	 $this->default_graphic_vars = $this->getGraphicVars();
2010  	 	 $this->header_xobj_autoreset = false;
2011  	 	 $this->custom_xmp = '';
2012  	 	 $this->custom_xmp_rdf = '';
2013  	 	 // Call cleanup method after script execution finishes or exit() is called.
2014  	 	 // NOTE: This will not be executed if the process is killed with a SIGTERM or SIGKILL signal.
2015  	 	 register_shutdown_function(array($this, '_destroy'), true);
2016  	 }
2017  
2018  	 /**
2019  	  * Default destructor.
2020  	  * @public
2021  	  * @since 1.53.0.TC016
2022  	  */
2023  	public function __destruct() {
2024  	 	 // cleanup
2025  	 	 $this->_destroy(true);
2026  	 }
2027  
2028  	 /**
2029  	  * Set the units of measure for the document.
2030  	  * @param $unit (string) User measure unit. Possible values are:<ul><li>pt: point</li><li>mm: millimeter (default)</li><li>cm: centimeter</li><li>in: inch</li></ul><br />A point equals 1/72 of inch, that is to say about 0.35 mm (an inch being 2.54 cm). This is a very common unit in typography; font sizes are expressed in that unit.
2031  	  * @public
2032  	  * @since 3.0.015 (2008-06-06)
2033  	  */
2034  	public function setPageUnit($unit) {
2035  	 	 $unit = strtolower($unit);
2036  	 	 //Set scale factor
2037  	 	 switch ($unit) {
2038  	 	 	 // points
2039  	 	 	 case 'px':
2040  	 	 	 case 'pt': {
2041  	 	 	 	 $this->k = 1;
2042  	 	 	 	 break;
2043  	 	 	 }
2044  	 	 	 // millimeters
2045  	 	 	 case 'mm': {
2046  	 	 	 	 $this->k = $this->dpi / 25.4;
2047  	 	 	 	 break;
2048  	 	 	 }
2049  	 	 	 // centimeters
2050  	 	 	 case 'cm': {
2051  	 	 	 	 $this->k = $this->dpi / 2.54;
2052  	 	 	 	 break;
2053  	 	 	 }
2054  	 	 	 // inches
2055  	 	 	 case 'in': {
2056  	 	 	 	 $this->k = $this->dpi;
2057  	 	 	 	 break;
2058  	 	 	 }
2059  	 	 	 // unsupported unit
2060  	 	 	 default : {
2061  	 	 	 	 $this->Error('Incorrect unit: '.$unit);
2062  	 	 	 	 break;
2063  	 	 	 }
2064  	 	 }
2065  	 	 $this->pdfunit = $unit;
2066  	 	 if (isset($this->CurOrientation)) {
2067  	 	 	 $this->setPageOrientation($this->CurOrientation);
2068  	 	 }
2069  	 }
2070  
2071  	 /**
2072  	  * Change the format of the current page
2073  	  * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() documentation or an array of two numbers (width, height) or an array containing the following measures and options:<ul>
2074  	  * <li>['format'] = page format name (one of the above);</li>
2075  	  * <li>['Rotate'] : The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90.</li>
2076  	  * <li>['PZ'] : The page's preferred zoom (magnification) factor.</li>
2077  	  * <li>['MediaBox'] : the boundaries of the physical medium on which the page shall be displayed or printed:</li>
2078  	  * <li>['MediaBox']['llx'] : lower-left x coordinate</li>
2079  	  * <li>['MediaBox']['lly'] : lower-left y coordinate</li>
2080  	  * <li>['MediaBox']['urx'] : upper-right x coordinate</li>
2081  	  * <li>['MediaBox']['ury'] : upper-right y coordinate</li>
2082  	  * <li>['CropBox'] : the visible region of default user space:</li>
2083  	  * <li>['CropBox']['llx'] : lower-left x coordinate</li>
2084  	  * <li>['CropBox']['lly'] : lower-left y coordinate</li>
2085  	  * <li>['CropBox']['urx'] : upper-right x coordinate</li>
2086  	  * <li>['CropBox']['ury'] : upper-right y coordinate</li>
2087  	  * <li>['BleedBox'] : the region to which the contents of the page shall be clipped when output in a production environment:</li>
2088  	  * <li>['BleedBox']['llx'] : lower-left x coordinate</li>
2089  	  * <li>['BleedBox']['lly'] : lower-left y coordinate</li>
2090  	  * <li>['BleedBox']['urx'] : upper-right x coordinate</li>
2091  	  * <li>['BleedBox']['ury'] : upper-right y coordinate</li>
2092  	  * <li>['TrimBox'] : the intended dimensions of the finished page after trimming:</li>
2093  	  * <li>['TrimBox']['llx'] : lower-left x coordinate</li>
2094  	  * <li>['TrimBox']['lly'] : lower-left y coordinate</li>
2095  	  * <li>['TrimBox']['urx'] : upper-right x coordinate</li>
2096  	  * <li>['TrimBox']['ury'] : upper-right y coordinate</li>
2097  	  * <li>['ArtBox'] : the extent of the page's meaningful content:</li>
2098  	  * <li>['ArtBox']['llx'] : lower-left x coordinate</li>
2099  	  * <li>['ArtBox']['lly'] : lower-left y coordinate</li>
2100  	  * <li>['ArtBox']['urx'] : upper-right x coordinate</li>
2101  	  * <li>['ArtBox']['ury'] : upper-right y coordinate</li>
2102  	  * <li>['BoxColorInfo'] :specify the colours and other visual characteristics that should be used in displaying guidelines on the screen for each of the possible page boundaries other than the MediaBox:</li>
2103  	  * <li>['BoxColorInfo'][BOXTYPE]['C'] : an array of three numbers in the range 0-255, representing the components in the DeviceRGB colour space.</li>
2104  	  * <li>['BoxColorInfo'][BOXTYPE]['W'] : the guideline width in default user units</li>
2105  	  * <li>['BoxColorInfo'][BOXTYPE]['S'] : the guideline style: S = Solid; D = Dashed</li>
2106  	  * <li>['BoxColorInfo'][BOXTYPE]['D'] : dash array defining a pattern of dashes and gaps to be used in drawing dashed guidelines</li>
2107  	  * <li>['trans'] : the style and duration of the visual transition to use when moving from another page to the given page during a presentation</li>
2108  	  * <li>['trans']['Dur'] : The page's display duration (also called its advance timing): the maximum length of time, in seconds, that the page shall be displayed during presentations before the viewer application shall automatically advance to the next page.</li>
2109  	  * <li>['trans']['S'] : transition style : Split, Blinds, Box, Wipe, Dissolve, Glitter, R, Fly, Push, Cover, Uncover, Fade</li>
2110  	  * <li>['trans']['D'] : The duration of the transition effect, in seconds.</li>
2111  	  * <li>['trans']['Dm'] : (Split and Blinds transition styles only) The dimension in which the specified transition effect shall occur: H = Horizontal, V = Vertical. Default value: H.</li>
2112  	  * <li>['trans']['M'] : (Split, Box and Fly transition styles only) The direction of motion for the specified transition effect: I = Inward from the edges of the page, O = Outward from the center of the pageDefault value: I.</li>
2113  	  * <li>['trans']['Di'] : (Wipe, Glitter, Fly, Cover, Uncover and Push transition styles only) The direction in which the specified transition effect shall moves, expressed in degrees counterclockwise starting from a left-to-right direction. If the value is a number, it shall be one of: 0 = Left to right, 90 = Bottom to top (Wipe only), 180 = Right to left (Wipe only), 270 = Top to bottom, 315 = Top-left to bottom-right (Glitter only). If the value is a name, it shall be None, which is relevant only for the Fly transition when the value of SS is not 1.0. Default value: 0.</li>
2114  	  * <li>['trans']['SS'] : (Fly transition style only) The starting or ending scale at which the changes shall be drawn. If M specifies an inward transition, the scale of the changes drawn shall progress from SS to 1.0 over the course of the transition. If M specifies an outward transition, the scale of the changes drawn shall progress from 1.0 to SS over the course of the transition. Default: 1.0.</li>
2115  	  * <li>['trans']['B'] : (Fly transition style only) If true, the area that shall be flown in is rectangular and opaque. Default: false.</li>
2116  	  * </ul>
2117  	  * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul>
2118  	  * <li>P or Portrait (default)</li>
2119  	  * <li>L or Landscape</li>
2120  	  * <li>'' (empty string) for automatic orientation</li>
2121  	  * </ul>
2122  	  * @protected
2123  	  * @since 3.0.015 (2008-06-06)
2124  	  * @see getPageSizeFromFormat()
2125  	  */
2126  	protected function setPageFormat($format, $orientation='P') {
2127  	 	 if (!empty($format) AND isset($this->pagedim[$this->page])) {
2128  	 	 	 // remove inherited values
2129  	 	 	 unset($this->pagedim[$this->page]);
2130  	 	 }
2131  	 	 if (is_string($format)) {
2132  	 	 	 // get page measures from format name
2133  	 	 	 $pf = TCPDF_STATIC::getPageSizeFromFormat($format);
2134  	 	 	 $this->fwPt = $pf[0];
2135  	 	 	 $this->fhPt = $pf[1];
2136  	 	 } else {
2137  	 	 	 // the boundaries of the physical medium on which the page shall be displayed or printed
2138  	 	 	 if (isset($format['MediaBox'])) {
2139  	 	 	 	 $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'MediaBox', $format['MediaBox']['llx'], $format['MediaBox']['lly'], $format['MediaBox']['urx'], $format['MediaBox']['ury'], false, $this->k, $this->pagedim);
2140  	 	 	 	 $this->fwPt = (($format['MediaBox']['urx'] - $format['MediaBox']['llx']) * $this->k);
2141  	 	 	 	 $this->fhPt = (($format['MediaBox']['ury'] - $format['MediaBox']['lly']) * $this->k);
2142  	 	 	 } else {
2143  	 	 	 	 if (isset($format[0]) AND is_numeric($format[0]) AND isset($format[1]) AND is_numeric($format[1])) {
2144  	 	 	 	 	 $pf = array(($format[0] * $this->k), ($format[1] * $this->k));
2145  	 	 	 	 } else {
2146  	 	 	 	 	 if (!isset($format['format'])) {
2147  	 	 	 	 	 	 // default value
2148  	 	 	 	 	 	 $format['format'] = 'A4';
2149  	 	 	 	 	 }
2150  	 	 	 	 	 $pf = TCPDF_STATIC::getPageSizeFromFormat($format['format']);
2151  	 	 	 	 }
2152  	 	 	 	 $this->fwPt = $pf[0];
2153  	 	 	 	 $this->fhPt = $pf[1];
2154  	 	 	 	 $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'MediaBox', 0, 0, $this->fwPt, $this->fhPt, true, $this->k, $this->pagedim);
2155  	 	 	 }
2156  	 	 	 // the visible region of default user space
2157  	 	 	 if (isset($format['CropBox'])) {
2158  	 	 	 	 $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'CropBox', $format['CropBox']['llx'], $format['CropBox']['lly'], $format['CropBox']['urx'], $format['CropBox']['ury'], false, $this->k, $this->pagedim);
2159  	 	 	 }
2160  	 	 	 // the region to which the contents of the page shall be clipped when output in a production environment
2161  	 	 	 if (isset($format['BleedBox'])) {
2162  	 	 	 	 $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'BleedBox', $format['BleedBox']['llx'], $format['BleedBox']['lly'], $format['BleedBox']['urx'], $format['BleedBox']['ury'], false, $this->k, $this->pagedim);
2163  	 	 	 }
2164  	 	 	 // the intended dimensions of the finished page after trimming
2165  	 	 	 if (isset($format['TrimBox'])) {
2166  	 	 	 	 $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'TrimBox', $format['TrimBox']['llx'], $format['TrimBox']['lly'], $format['TrimBox']['urx'], $format['TrimBox']['ury'], false, $this->k, $this->pagedim);
2167  	 	 	 }
2168  	 	 	 // the page's meaningful content (including potential white space)
2169  	 	 	 if (isset($format['ArtBox'])) {
2170  	 	 	 	 $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'ArtBox', $format['ArtBox']['llx'], $format['ArtBox']['lly'], $format['ArtBox']['urx'], $format['ArtBox']['ury'], false, $this->k, $this->pagedim);
2171  	 	 	 }
2172  	 	 	 // specify the colours and other visual characteristics that should be used in displaying guidelines on the screen for the various page boundaries
2173  	 	 	 if (isset($format['BoxColorInfo'])) {
2174  	 	 	 	 $this->pagedim[$this->page]['BoxColorInfo'] = $format['BoxColorInfo'];
2175  	 	 	 }
2176  	 	 	 if (isset($format['Rotate']) AND (($format['Rotate'] % 90) == 0)) {
2177  	 	 	 	 // The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90.
2178  	 	 	 	 $this->pagedim[$this->page]['Rotate'] = intval($format['Rotate']);
2179  	 	 	 }
2180  	 	 	 if (isset($format['PZ'])) {
2181  	 	 	 	 // The page's preferred zoom (magnification) factor
2182  	 	 	 	 $this->pagedim[$this->page]['PZ'] = floatval($format['PZ']);
2183  	 	 	 }
2184  	 	 	 if (isset($format['trans'])) {
2185  	 	 	 	 // The style and duration of the visual transition to use when moving from another page to the given page during a presentation
2186  	 	 	 	 if (isset($format['trans']['Dur'])) {
2187  	 	 	 	 	 // The page's display duration
2188  	 	 	 	 	 $this->pagedim[$this->page]['trans']['Dur'] = floatval($format['trans']['Dur']);
2189  	 	 	 	 }
2190  	 	 	 	 $stansition_styles = array('Split', 'Blinds', 'Box', 'Wipe', 'Dissolve', 'Glitter', 'R', 'Fly', 'Push', 'Cover', 'Uncover', 'Fade');
2191  	 	 	 	 if (isset($format['trans']['S']) AND in_array($format['trans']['S'], $stansition_styles)) {
2192  	 	 	 	 	 // The transition style that shall be used when moving to this page from another during a presentation
2193  	 	 	 	 	 $this->pagedim[$this->page]['trans']['S'] = $format['trans']['S'];
2194  	 	 	 	 	 $valid_effect = array('Split', 'Blinds');
2195  	 	 	 	 	 $valid_vals = array('H', 'V');
2196  	 	 	 	 	 if (isset($format['trans']['Dm']) AND in_array($format['trans']['S'], $valid_effect) AND in_array($format['trans']['Dm'], $valid_vals)) {
2197  	 	 	 	 	 	 $this->pagedim[$this->page]['trans']['Dm'] = $format['trans']['Dm'];
2198  	 	 	 	 	 }
2199  	 	 	 	 	 $valid_effect = array('Split', 'Box', 'Fly');
2200  	 	 	 	 	 $valid_vals = array('I', 'O');
2201  	 	 	 	 	 if (isset($format['trans']['M']) AND in_array($format['trans']['S'], $valid_effect) AND in_array($format['trans']['M'], $valid_vals)) {
2202  	 	 	 	 	 	 $this->pagedim[$this->page]['trans']['M'] = $format['trans']['M'];
2203  	 	 	 	 	 }
2204  	 	 	 	 	 $valid_effect = array('Wipe', 'Glitter', 'Fly', 'Cover', 'Uncover', 'Push');
2205  	 	 	 	 	 if (isset($format['trans']['Di']) AND in_array($format['trans']['S'], $valid_effect)) {
2206  	 	 	 	 	 	 if (((($format['trans']['Di'] == 90) OR ($format['trans']['Di'] == 180)) AND ($format['trans']['S'] == 'Wipe'))
2207  	 	 	 	 	 	 	 OR (($format['trans']['Di'] == 315) AND ($format['trans']['S'] == 'Glitter'))
2208  	 	 	 	 	 	 	 OR (($format['trans']['Di'] == 0) OR ($format['trans']['Di'] == 270))) {
2209  	 	 	 	 	 	 	 $this->pagedim[$this->page]['trans']['Di'] = intval($format['trans']['Di']);
2210  	 	 	 	 	 	 }
2211  	 	 	 	 	 }
2212  	 	 	 	 	 if (isset($format['trans']['SS']) AND ($format['trans']['S'] == 'Fly')) {
2213  	 	 	 	 	 	 $this->pagedim[$this->page]['trans']['SS'] = floatval($format['trans']['SS']);
2214  	 	 	 	 	 }
2215  	 	 	 	 	 if (isset($format['trans']['B']) AND ($format['trans']['B'] === true) AND ($format['trans']['S'] == 'Fly')) {
2216  	 	 	 	 	 	 $this->pagedim[$this->page]['trans']['B'] = 'true';
2217  	 	 	 	 	 }
2218  	 	 	 	 } else {
2219  	 	 	 	 	 $this->pagedim[$this->page]['trans']['S'] = 'R';
2220  	 	 	 	 }
2221  	 	 	 	 if (isset($format['trans']['D'])) {
2222  	 	 	 	 	 // The duration of the transition effect, in seconds
2223  	 	 	 	 	 $this->pagedim[$this->page]['trans']['D'] = floatval($format['trans']['D']);
2224  	 	 	 	 } else {
2225  	 	 	 	 	 $this->pagedim[$this->page]['trans']['D'] = 1;
2226  	 	 	 	 }
2227  	 	 	 }
2228  	 	 }
2229  	 	 $this->setPageOrientation($orientation);
2230  	 }
2231  
2232  	 /**
2233  	  * Set page orientation.
2234  	  * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or Portrait (default)</li><li>L or Landscape</li><li>'' (empty string) for automatic orientation</li></ul>
2235  	  * @param $autopagebreak (boolean) Boolean indicating if auto-page-break mode should be on or off.
2236  	  * @param $bottommargin (float) bottom margin of the page.
2237  	  * @public
2238  	  * @since 3.0.015 (2008-06-06)
2239  	  */
2240  	public function setPageOrientation($orientation, $autopagebreak='', $bottommargin='') {
2241  	 	 if (!isset($this->pagedim[$this->page]['MediaBox'])) {
2242  	 	 	 // the boundaries of the physical medium on which the page shall be displayed or printed
2243  	 	 	 $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'MediaBox', 0, 0, $this->fwPt, $this->fhPt, true, $this->k, $this->pagedim);
2244  	 	 }
2245  	 	 if (!isset($this->pagedim[$this->page]['CropBox'])) {
2246  	 	 	 // the visible region of default user space
2247  	 	 	 $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'CropBox', $this->pagedim[$this->page]['MediaBox']['llx'], $this->pagedim[$this->page]['MediaBox']['lly'], $this->pagedim[$this->page]['MediaBox']['urx'], $this->pagedim[$this->page]['MediaBox']['ury'], true, $this->k, $this->pagedim);
2248  	 	 }
2249  	 	 if (!isset($this->pagedim[$this->page]['BleedBox'])) {
2250  	 	 	 // the region to which the contents of the page shall be clipped when output in a production environment
2251  	 	 	 $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'BleedBox', $this->pagedim[$this->page]['CropBox']['llx'], $this->pagedim[$this->page]['CropBox']['lly'], $this->pagedim[$this->page]['CropBox']['urx'], $this->pagedim[$this->page]['CropBox']['ury'], true, $this->k, $this->pagedim);
2252  	 	 }
2253  	 	 if (!isset($this->pagedim[$this->page]['TrimBox'])) {
2254  	 	 	 // the intended dimensions of the finished page after trimming
2255  	 	 	 $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'TrimBox', $this->pagedim[$this->page]['CropBox']['llx'], $this->pagedim[$this->page]['CropBox']['lly'], $this->pagedim[$this->page]['CropBox']['urx'], $this->pagedim[$this->page]['CropBox']['ury'], true, $this->k, $this->pagedim);
2256  	 	 }
2257  	 	 if (!isset($this->pagedim[$this->page]['ArtBox'])) {
2258  	 	 	 // the page's meaningful content (including potential white space)
2259  	 	 	 $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'ArtBox', $this->pagedim[$this->page]['CropBox']['llx'], $this->pagedim[$this->page]['CropBox']['lly'], $this->pagedim[$this->page]['CropBox']['urx'], $this->pagedim[$this->page]['CropBox']['ury'], true, $this->k, $this->pagedim);
2260  	 	 }
2261  	 	 if (!isset($this->pagedim[$this->page]['Rotate'])) {
2262  	 	 	 // The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90.
2263  	 	 	 $this->pagedim[$this->page]['Rotate'] = 0;
2264  	 	 }
2265  	 	 if (!isset($this->pagedim[$this->page]['PZ'])) {
2266  	 	 	 // The page's preferred zoom (magnification) factor
2267  	 	 	 $this->pagedim[$this->page]['PZ'] = 1;
2268  	 	 }
2269  	 	 if ($this->fwPt > $this->fhPt) {
2270  	 	 	 // landscape
2271  	 	 	 $default_orientation = 'L';
2272  	 	 } else {
2273  	 	 	 // portrait
2274  	 	 	 $default_orientation = 'P';
2275  	 	 }
2276  	 	 $valid_orientations = array('P', 'L');
2277  	 	 if (empty($orientation)) {
2278  	 	 	 $orientation = $default_orientation;
2279  	 	 } else {
2280  	 	 	 $orientation = strtoupper($orientation[0]);
2281  	 	 }
2282  	 	 if (in_array($orientation, $valid_orientations) AND ($orientation != $default_orientation)) {
2283  	 	 	 $this->CurOrientation = $orientation;
2284  	 	 	 $this->wPt = $this->fhPt;
2285  	 	 	 $this->hPt = $this->fwPt;
2286  	 	 } else {
2287  	 	 	 $this->CurOrientation = $default_orientation;
2288  	 	 	 $this->wPt = $this->fwPt;
2289  	 	 	 $this->hPt = $this->fhPt;
2290  	 	 }
2291  	 	 if ((abs($this->pagedim[$this->page]['MediaBox']['urx'] - $this->hPt) < $this->feps) AND (abs($this->pagedim[$this->page]['MediaBox']['ury'] - $this->wPt) < $this->feps)){
2292  	 	 	 // swap X and Y coordinates (change page orientation)
2293  	 	 	 $this->pagedim = TCPDF_STATIC::swapPageBoxCoordinates($this->page, $this->pagedim);
2294  	 	 }
2295  	 	 $this->w = ($this->wPt / $this->k);
2296  	 	 $this->h = ($this->hPt / $this->k);
2297  	 	 if (TCPDF_STATIC::empty_string($autopagebreak)) {
2298  	 	 	 if (isset($this->AutoPageBreak)) {
2299  	 	 	 	 $autopagebreak = $this->AutoPageBreak;
2300  	 	 	 } else {
2301  	 	 	 	 $autopagebreak = true;
2302  	 	 	 }
2303  	 	 }
2304  	 	 if (TCPDF_STATIC::empty_string($bottommargin)) {
2305  	 	 	 if (isset($this->bMargin)) {
2306  	 	 	 	 $bottommargin = $this->bMargin;
2307  	 	 	 } else {
2308  	 	 	 	 // default value = 2 cm
2309  	 	 	 	 $bottommargin = 2 * 28.35 / $this->k;
2310  	 	 	 }
2311  	 	 }
2312  	 	 $this->SetAutoPageBreak($autopagebreak, $bottommargin);
2313  	 	 // store page dimensions
2314  	 	 $this->pagedim[$this->page]['w'] = $this->wPt;
2315  	 	 $this->pagedim[$this->page]['h'] = $this->hPt;
2316  	 	 $this->pagedim[$this->page]['wk'] = $this->w;
2317  	 	 $this->pagedim[$this->page]['hk'] = $this->h;
2318  	 	 $this->pagedim[$this->page]['tm'] = $this->tMargin;
2319  	 	 $this->pagedim[$this->page]['bm'] = $bottommargin;
2320  	 	 $this->pagedim[$this->page]['lm'] = $this->lMargin;
2321  	 	 $this->pagedim[$this->page]['rm'] = $this->rMargin;
2322  	 	 $this->pagedim[$this->page]['pb'] = $autopagebreak;
2323  	 	 $this->pagedim[$this->page]['or'] = $this->CurOrientation;
2324  	 	 $this->pagedim[$this->page]['olm'] = $this->original_lMargin;
2325  	 	 $this->pagedim[$this->page]['orm'] = $this->original_rMargin;
2326  	 }
2327  
2328  	 /**
2329  	  * Set regular expression to detect withespaces or word separators.
2330  	  * The pattern delimiter must be the forward-slash character "/".
2331  	  * Some example patterns are:
2332  	  * <pre>
2333  	  * Non-Unicode or missing PCRE unicode support: "/[^\S\xa0]/"
2334  	  * Unicode and PCRE unicode support: "/(?!\xa0)[\s\p{Z}]/u"
2335  	  * Unicode and PCRE unicode support in Chinese mode: "/(?!\xa0)[\s\p{Z}\p{Lo}]/u"
2336  	  * if PCRE unicode support is turned ON ("\P" is the negate class of "\p"):
2337  	  *      \s     : any whitespace character
2338  	  *      \p{Z}  : any separator
2339  	  *      \p{Lo} : Unicode letter or ideograph that does not have lowercase and uppercase variants. Is used to chunk chinese words.
2340  	  *      \xa0   : Unicode Character 'NO-BREAK SPACE' (U+00A0)
2341  	  * </pre>
2342  	  * @param $re (string) regular expression (leave empty for default).
2343  	  * @public
2344  	  * @since 4.6.016 (2009-06-15)
2345  	  */
2346  	public function setSpacesRE($re='/[^\S\xa0]/') {
2347  	 	 $this->re_spaces = $re;
2348  	 	 $re_parts = explode('/', $re);
2349  	 	 // get pattern parts
2350  	 	 $this->re_space = array();
2351  	 	 if (isset($re_parts[1]) AND !empty($re_parts[1])) {
2352  	 	 	 $this->re_space['p'] = $re_parts[1];
2353  	 	 } else {
2354  	 	 	 $this->re_space['p'] = '[\s]';
2355  	 	 }
2356  	 	 // set pattern modifiers
2357  	 	 if (isset($re_parts[2]) AND !empty($re_parts[2])) {
2358  	 	 	 $this->re_space['m'] = $re_parts[2];
2359  	 	 } else {
2360  	 	 	 $this->re_space['m'] = '';
2361  	 	 }
2362  	 }
2363  
2364  	 /**
2365  	  * Enable or disable Right-To-Left language mode
2366  	  * @param $enable (Boolean) if true enable Right-To-Left language mode.
2367  	  * @param $resetx (Boolean) if true reset the X position on direction change.
2368  	  * @public
2369  	  * @since 2.0.000 (2008-01-03)
2370  	  */
2371  	public function setRTL($enable, $resetx=true) {
2372  	 	 $enable = $enable ? true : false;
2373  	 	 $resetx = ($resetx AND ($enable != $this->rtl));
2374  	 	 $this->rtl = $enable;
2375  	 	 $this->tmprtl = false;
2376  	 	 if ($resetx) {
2377  	 	 	 $this->Ln(0);
2378  	 	 }
2379  	 }
2380  
2381  	 /**
2382  	  * Return the RTL status
2383  	  * @return boolean
2384  	  * @public
2385  	  * @since 4.0.012 (2008-07-24)
2386  	  */
2387  	public function getRTL() {
2388  	 	 return $this->rtl;
2389  	 }
2390  
2391  	 /**
2392  	  * Force temporary RTL language direction
2393  	  * @param $mode (mixed) can be false, 'L' for LTR or 'R' for RTL
2394  	  * @public
2395  	  * @since 2.1.000 (2008-01-09)
2396  	  */
2397  	public function setTempRTL($mode) {
2398  	 	 $newmode = false;
2399  	 	 switch (strtoupper($mode)) {
2400  	 	 	 case 'LTR':
2401  	 	 	 case 'L': {
2402  	 	 	 	 if ($this->rtl) {
2403  	 	 	 	 	 $newmode = 'L';
2404  	 	 	 	 }
2405  	 	 	 	 break;
2406  	 	 	 }
2407  	 	 	 case 'RTL':
2408  	 	 	 case 'R': {
2409  	 	 	 	 if (!$this->rtl) {
2410  	 	 	 	 	 $newmode = 'R';
2411  	 	 	 	 }
2412  	 	 	 	 break;
2413  	 	 	 }
2414  	 	 	 case false:
2415  	 	 	 default: {
2416  	 	 	 	 $newmode = false;
2417  	 	 	 	 break;
2418  	 	 	 }
2419  	 	 }
2420  	 	 $this->tmprtl = $newmode;
2421  	 }
2422  
2423  	 /**
2424  	  * Return the current temporary RTL status
2425  	  * @return boolean
2426  	  * @public
2427  	  * @since 4.8.014 (2009-11-04)
2428  	  */
2429  	public function isRTLTextDir() {
2430  	 	 return ($this->rtl OR ($this->tmprtl == 'R'));
2431  	 }
2432  
2433  	 /**
2434  	  * Set the last cell height.
2435  	  * @param $h (float) cell height.
2436  	  * @author Nicola Asuni
2437  	  * @public
2438  	  * @since 1.53.0.TC034
2439  	  */
2440  	public function setLastH($h) {
2441  	 	 $this->lasth = $h;
2442  	 }
2443  
2444  	 /**
2445  	  * Return the cell height
2446  	  * @param $fontsize (int) Font size in internal units
2447  	  * @param $padding (boolean) If true add cell padding
2448  	  * @public
2449  	  */
2450  	public function getCellHeight($fontsize, $padding=TRUE) {
2451  	 	 $height = ($fontsize * $this->cell_height_ratio);
2452  	 	 if ($padding) {
2453  	 	 	 $height += ($this->cell_padding['T'] + $this->cell_padding['B']);
2454  	 	 }
2455  	 	 return round($height, 6);
2456  	 }
2457  
2458  	 /**
2459  	  * Reset the last cell height.
2460  	  * @public
2461  	  * @since 5.9.000 (2010-10-03)
2462  	  */
2463  	public function resetLastH() {
2464  	 	 $this->lasth = $this->getCellHeight($this->FontSize);
2465  	 }
2466  
2467  	 /**
2468  	  * Get the last cell height.
2469  	  * @return last cell height
2470  	  * @public
2471  	  * @since 4.0.017 (2008-08-05)
2472  	  */
2473  	public function getLastH() {
2474  	 	 return $this->lasth;
2475  	 }
2476  
2477  	 /**
2478  	  * Set the adjusting factor to convert pixels to user units.
2479  	  * @param $scale (float) adjusting factor to convert pixels to user units.
2480  	  * @author Nicola Asuni
2481  	  * @public
2482  	  * @since 1.5.2
2483  	  */
2484  	public function setImageScale($scale) {
2485  	 	 $this->imgscale = $scale;
2486  	 }
2487  
2488  	 /**
2489  	  * Returns the adjusting factor to convert pixels to user units.
2490  	  * @return float adjusting factor to convert pixels to user units.
2491  	  * @author Nicola Asuni
2492  	  * @public
2493  	  * @since 1.5.2
2494  	  */
2495  	public function getImageScale() {
2496  	 	 return $this->imgscale;
2497  	 }
2498  
2499  	 /**
2500  	  * Returns an array of page dimensions:
2501  	  * <ul><li>$this->pagedim[$this->page]['w'] = page width in points</li><li>$this->pagedim[$this->page]['h'] = height in points</li><li>$this->pagedim[$this->page]['wk'] = page width in user units</li><li>$this->pagedim[$this->page]['hk'] = page height in user units</li><li>$this->pagedim[$this->page]['tm'] = top margin</li><li>$this->pagedim[$this->page]['bm'] = bottom margin</li><li>$this->pagedim[$this->page]['lm'] = left margin</li><li>$this->pagedim[$this->page]['rm'] = right margin</li><li>$this->pagedim[$this->page]['pb'] = auto page break</li><li>$this->pagedim[$this->page]['or'] = page orientation</li><li>$this->pagedim[$this->page]['olm'] = original left margin</li><li>$this->pagedim[$this->page]['orm'] = original right margin</li><li>$this->pagedim[$this->page]['Rotate'] = The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90.</li><li>$this->pagedim[$this->page]['PZ'] = The page's preferred zoom (magnification) factor.</li><li>$this->pagedim[$this->page]['trans'] : the style and duration of the visual transition to use when moving from another page to the given page during a presentation<ul><li>$this->pagedim[$this->page]['trans']['Dur'] = The page's display duration (also called its advance timing): the maximum length of time, in seconds, that the page shall be displayed during presentations before the viewer application shall automatically advance to the next page.</li><li>$this->pagedim[$this->page]['trans']['S'] = transition style : Split, Blinds, Box, Wipe, Dissolve, Glitter, R, Fly, Push, Cover, Uncover, Fade</li><li>$this->pagedim[$this->page]['trans']['D'] = The duration of the transition effect, in seconds.</li><li>$this->pagedim[$this->page]['trans']['Dm'] = (Split and Blinds transition styles only) The dimension in which the specified transition effect shall occur: H = Horizontal, V = Vertical. Default value: H.</li><li>$this->pagedim[$this->page]['trans']['M'] = (Split, Box and Fly transition styles only) The direction of motion for the specified transition effect: I = Inward from the edges of the page, O = Outward from the center of the pageDefault value: I.</li><li>$this->pagedim[$this->page]['trans']['Di'] = (Wipe, Glitter, Fly, Cover, Uncover and Push transition styles only) The direction in which the specified transition effect shall moves, expressed in degrees counterclockwise starting from a left-to-right direction. If the value is a number, it shall be one of: 0 = Left to right, 90 = Bottom to top (Wipe only), 180 = Right to left (Wipe only), 270 = Top to bottom, 315 = Top-left to bottom-right (Glitter only). If the value is a name, it shall be None, which is relevant only for the Fly transition when the value of SS is not 1.0. Default value: 0.</li><li>$this->pagedim[$this->page]['trans']['SS'] = (Fly transition style only) The starting or ending scale at which the changes shall be drawn. If M specifies an inward transition, the scale of the changes drawn shall progress from SS to 1.0 over the course of the transition. If M specifies an outward transition, the scale of the changes drawn shall progress from 1.0 to SS over the course of the transition. Default: 1.0. </li><li>$this->pagedim[$this->page]['trans']['B'] = (Fly transition style only) If true, the area that shall be flown in is rectangular and opaque. Default: false.</li></ul></li><li>$this->pagedim[$this->page]['MediaBox'] : the boundaries of the physical medium on which the page shall be displayed or printed<ul><li>$this->pagedim[$this->page]['MediaBox']['llx'] = lower-left x coordinate in points</li><li>$this->pagedim[$this->page]['MediaBox']['lly'] = lower-left y coordinate in points</li><li>$this->pagedim[$this->page]['MediaBox']['urx'] = upper-right x coordinate in points</li><li>$this->pagedim[$this->page]['MediaBox']['ury'] = upper-right y coordinate in points</li></ul></li><li>$this->pagedim[$this->page]['CropBox'] : the visible region of default user space<ul><li>$this->pagedim[$this->page]['CropBox']['llx'] = lower-left x coordinate in points</li><li>$this->pagedim[$this->page]['CropBox']['lly'] = lower-left y coordinate in points</li><li>$this->pagedim[$this->page]['CropBox']['urx'] = upper-right x coordinate in points</li><li>$this->pagedim[$this->page]['CropBox']['ury'] = upper-right y coordinate in points</li></ul></li><li>$this->pagedim[$this->page]['BleedBox'] : the region to which the contents of the page shall be clipped when output in a production environment<ul><li>$this->pagedim[$this->page]['BleedBox']['llx'] = lower-left x coordinate in points</li><li>$this->pagedim[$this->page]['BleedBox']['lly'] = lower-left y coordinate in points</li><li>$this->pagedim[$this->page]['BleedBox']['urx'] = upper-right x coordinate in points</li><li>$this->pagedim[$this->page]['BleedBox']['ury'] = upper-right y coordinate in points</li></ul></li><li>$this->pagedim[$this->page]['TrimBox'] : the intended dimensions of the finished page after trimming<ul><li>$this->pagedim[$this->page]['TrimBox']['llx'] = lower-left x coordinate in points</li><li>$this->pagedim[$this->page]['TrimBox']['lly'] = lower-left y coordinate in points</li><li>$this->pagedim[$this->page]['TrimBox']['urx'] = upper-right x coordinate in points</li><li>$this->pagedim[$this->page]['TrimBox']['ury'] = upper-right y coordinate in points</li></ul></li><li>$this->pagedim[$this->page]['ArtBox'] : the extent of the page's meaningful content<ul><li>$this->pagedim[$this->page]['ArtBox']['llx'] = lower-left x coordinate in points</li><li>$this->pagedim[$this->page]['ArtBox']['lly'] = lower-left y coordinate in points</li><li>$this->pagedim[$this->page]['ArtBox']['urx'] = upper-right x coordinate in points</li><li>$this->pagedim[$this->page]['ArtBox']['ury'] = upper-right y coordinate in points</li></ul></li></ul>
2502  	  * @param $pagenum (int) page number (empty = current page)
2503  	  * @return array of page dimensions.
2504  	  * @author Nicola Asuni
2505  	  * @public
2506  	  * @since 4.5.027 (2009-03-16)
2507  	  */
2508  	public function getPageDimensions($pagenum='') {
2509  	 	 if (empty($pagenum)) {
2510  	 	 	 $pagenum = $this->page;
2511  	 	 }
2512  	 	 return $this->pagedim[$pagenum];
2513  	 }
2514  
2515  	 /**
2516  	  * Returns the page width in units.
2517  	  * @param $pagenum (int) page number (empty = current page)
2518  	  * @return int page width.
2519  	  * @author Nicola Asuni
2520  	  * @public
2521  	  * @since 1.5.2
2522  	  * @see getPageDimensions()
2523  	  */
2524  	public function getPageWidth($pagenum='') {
2525  	 	 if (empty($pagenum)) {
2526  	 	 	 return $this->w;
2527  	 	 }
2528  	 	 return $this->pagedim[$pagenum]['w'];
2529  	 }
2530  
2531  	 /**
2532  	  * Returns the page height in units.
2533  	  * @param $pagenum (int) page number (empty = current page)
2534  	  * @return int page height.
2535  	  * @author Nicola Asuni
2536  	  * @public
2537  	  * @since 1.5.2
2538  	  * @see getPageDimensions()
2539  	  */
2540  	public function getPageHeight($pagenum='') {
2541  	 	 if (empty($pagenum)) {
2542  	 	 	 return $this->h;
2543  	 	 }
2544  	 	 return $this->pagedim[$pagenum]['h'];
2545  	 }
2546  
2547  	 /**
2548  	  * Returns the page break margin.
2549  	  * @param $pagenum (int) page number (empty = current page)
2550  	  * @return int page break margin.
2551  	  * @author Nicola Asuni
2552  	  * @public
2553  	  * @since 1.5.2
2554  	  * @see getPageDimensions()
2555  	  */
2556  	public function getBreakMargin($pagenum='') {
2557  	 	 if (empty($pagenum)) {
2558  	 	 	 return $this->bMargin;
2559  	 	 }
2560  	 	 return $this->pagedim[$pagenum]['bm'];
2561  	 }
2562  
2563  	 /**
2564  	  * Returns the scale factor (number of points in user unit).
2565  	  * @return int scale factor.
2566  	  * @author Nicola Asuni
2567  	  * @public
2568  	  * @since 1.5.2
2569  	  */
2570  	public function getScaleFactor() {
2571  	 	 return $this->k;
2572  	 }
2573  
2574  	 /**
2575  	  * Defines the left, top and right margins.
2576  	  * @param $left (float) Left margin.
2577  	  * @param $top (float) Top margin.
2578  	  * @param $right (float) Right margin. Default value is the left one.
2579  	  * @param $keepmargins (boolean) if true overwrites the default page margins
2580  	  * @public
2581  	  * @since 1.0
2582  	  * @see SetLeftMargin(), SetTopMargin(), SetRightMargin(), SetAutoPageBreak()
2583  	  */
2584  	public function SetMargins($left, $top, $right=-1, $keepmargins=false) {
2585  	 	 //Set left, top and right margins
2586  	 	 $this->lMargin = $left;
2587  	 	 $this->tMargin = $top;
2588  	 	 if ($right == -1) {
2589  	 	 	 $right = $left;
2590  	 	 }
2591  	 	 $this->rMargin = $right;
2592  	 	 if ($keepmargins) {
2593  	 	 	 // overwrite original values
2594  	 	 	 $this->original_lMargin = $this->lMargin;
2595  	 	 	 $this->original_rMargin = $this->rMargin;
2596  	 	 }
2597  	 }
2598  
2599  	 /**
2600  	  * Defines the left margin. The method can be called before creating the first page. If the current abscissa gets out of page, it is brought back to the margin.
2601  	  * @param $margin (float) The margin.
2602  	  * @public
2603  	  * @since 1.4
2604  	  * @see SetTopMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins()
2605  	  */
2606  	public function SetLeftMargin($margin) {
2607  	 	 //Set left margin
2608  	 	 $this->lMargin = $margin;
2609  	 	 if (($this->page > 0) AND ($this->x < $margin)) {
2610  	 	 	 $this->x = $margin;
2611  	 	 }
2612  	 }
2613  
2614  	 /**
2615  	  * Defines the top margin. The method can be called before creating the first page.
2616  	  * @param $margin (float) The margin.
2617  	  * @public
2618  	  * @since 1.5
2619  	  * @see SetLeftMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins()
2620  	  */
2621  	public function SetTopMargin($margin) {
2622  	 	 //Set top margin
2623  	 	 $this->tMargin = $margin;
2624  	 	 if (($this->page > 0) AND ($this->y < $margin)) {
2625  	 	 	 $this->y = $margin;
2626  	 	 }
2627  	 }
2628  
2629  	 /**
2630  	  * Defines the right margin. The method can be called before creating the first page.
2631  	  * @param $margin (float) The margin.
2632  	  * @public
2633  	  * @since 1.5
2634  	  * @see SetLeftMargin(), SetTopMargin(), SetAutoPageBreak(), SetMargins()
2635  	  */
2636  	public function SetRightMargin($margin) {
2637  	 	 $this->rMargin = $margin;
2638  	 	 if (($this->page > 0) AND ($this->x > ($this->w - $margin))) {
2639  	 	 	 $this->x = $this->w - $margin;
2640  	 	 }
2641  	 }
2642  
2643  	 /**
2644  	  * Set the same internal Cell padding for top, right, bottom, left-
2645  	  * @param $pad (float) internal padding.
2646  	  * @public
2647  	  * @since 2.1.000 (2008-01-09)
2648  	  * @see getCellPaddings(), setCellPaddings()
2649  	  */
2650  	public function SetCellPadding($pad) {
2651  	 	 if ($pad >= 0) {
2652  	 	 	 $this->cell_padding['L'] = $pad;
2653  	 	 	 $this->cell_padding['T'] = $pad;
2654  	 	 	 $this->cell_padding['R'] = $pad;
2655  	 	 	 $this->cell_padding['B'] = $pad;
2656  	 	 }
2657  	 }
2658  
2659  	 /**
2660  	  * Set the internal Cell paddings.
2661  	  * @param $left (float) left padding
2662  	  * @param $top (float) top padding
2663  	  * @param $right (float) right padding
2664  	  * @param $bottom (float) bottom padding
2665  	  * @public
2666  	  * @since 5.9.000 (2010-10-03)
2667  	  * @see getCellPaddings(), SetCellPadding()
2668  	  */
2669  	public function setCellPaddings($left='', $top='', $right='', $bottom='') {
2670  	 	 if (($left !== '') AND ($left >= 0)) {
2671  	 	 	 $this->cell_padding['L'] = $left;
2672  	 	 }
2673  	 	 if (($top !== '') AND ($top >= 0)) {
2674  	 	 	 $this->cell_padding['T'] = $top;
2675  	 	 }
2676  	 	 if (($right !== '') AND ($right >= 0)) {
2677  	 	 	 $this->cell_padding['R'] = $right;
2678  	 	 }
2679  	 	 if (($bottom !== '') AND ($bottom >= 0)) {
2680  	 	 	 $this->cell_padding['B'] = $bottom;
2681  	 	 }
2682  	 }
2683  
2684  	 /**
2685  	  * Get the internal Cell padding array.
2686  	  * @return array of padding values
2687  	  * @public
2688  	  * @since 5.9.000 (2010-10-03)
2689  	  * @see setCellPaddings(), SetCellPadding()
2690  	  */
2691  	public function getCellPaddings() {
2692  	 	 return $this->cell_padding;
2693  	 }
2694  
2695  	 /**
2696  	  * Set the internal Cell margins.
2697  	  * @param $left (float) left margin
2698  	  * @param $top (float) top margin
2699  	  * @param $right (float) right margin
2700  	  * @param $bottom (float) bottom margin
2701  	  * @public
2702  	  * @since 5.9.000 (2010-10-03)
2703  	  * @see getCellMargins()
2704  	  */
2705  	public function setCellMargins($left='', $top='', $right='', $bottom='') {
2706  	 	 if (($left !== '') AND ($left >= 0)) {
2707  	 	 	 $this->cell_margin['L'] = $left;
2708  	 	 }
2709  	 	 if (($top !== '') AND ($top >= 0)) {
2710  	 	 	 $this->cell_margin['T'] = $top;
2711  	 	 }
2712  	 	 if (($right !== '') AND ($right >= 0)) {
2713  	 	 	 $this->cell_margin['R'] = $right;
2714  	 	 }
2715  	 	 if (($bottom !== '') AND ($bottom >= 0)) {
2716  	 	 	 $this->cell_margin['B'] = $bottom;
2717  	 	 }
2718  	 }
2719  
2720  	 /**
2721  	  * Get the internal Cell margin array.
2722  	  * @return array of margin values
2723  	  * @public
2724  	  * @since 5.9.000 (2010-10-03)
2725  	  * @see setCellMargins()
2726  	  */
2727  	public function getCellMargins() {
2728  	 	 return $this->cell_margin;
2729  	 }
2730  
2731  	 /**
2732  	  * Adjust the internal Cell padding array to take account of the line width.
2733  	  * @param $brd (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
2734  	  * @return void|array of adjustments
2735  	  * @public
2736  	  * @since 5.9.000 (2010-10-03)
2737  	  */
2738  	protected function adjustCellPadding($brd=0) {
2739  	 	 if (empty($brd)) {
2740  	 	 	 return;
2741  	 	 }
2742  	 	 if (is_string($brd)) {
2743  	 	 	 // convert string to array
2744  	 	 	 $slen = strlen($brd);
2745  	 	 	 $newbrd = array();
2746  	 	 	 for ($i = 0; $i < $slen; ++$i) {
2747  	 	 	 	 $newbrd[$brd[$i]] = true;
2748  	 	 	 }
2749  	 	 	 $brd = $newbrd;
2750  	 	 } elseif (
2751  	 	 	 ($brd === 1)
2752  	 	 	 || ($brd === true)
2753  	 	 	 || (is_numeric($brd) && ((int)$brd > 0))
2754  	 	 ) {
2755  	 	 	 $brd = array('LRTB' => true);
2756  	 	 }
2757  	 	 if (!is_array($brd)) {
2758  	 	 	 return;
2759  	 	 }
2760  	 	 // store current cell padding
2761  	 	 $cp = $this->cell_padding;
2762  	 	 // select border mode
2763  	 	 if (isset($brd['mode'])) {
2764  	 	 	 $mode = $brd['mode'];
2765  	 	 	 unset($brd['mode']);
2766  	 	 } else {
2767  	 	 	 $mode = 'normal';
2768  	 	 }
2769  	 	 // process borders
2770  	 	 foreach ($brd as $border => $style) {
2771  	 	 	 $line_width = $this->LineWidth;
2772  	 	 	 if (is_array($style) && isset($style['width'])) {
2773  	 	 	 	 // get border width
2774  	 	 	 	 $line_width = $style['width'];
2775  	 	 	 }
2776  	 	 	 $adj = 0; // line width inside the cell
2777  	 	 	 switch ($mode) {
2778  	 	 	 	 case 'ext': {
2779  	 	 	 	 	 $adj = 0;
2780  	 	 	 	 	 break;
2781  	 	 	 	 }
2782  	 	 	 	 case 'int': {
2783  	 	 	 	 	 $adj = $line_width;
2784  	 	 	 	 	 break;
2785  	 	 	 	 }
2786  	 	 	 	 case 'normal':
2787  	 	 	 	 default: {
2788  	 	 	 	 	 $adj = ($line_width / 2);
2789  	 	 	 	 	 break;
2790  	 	 	 	 }
2791  	 	 	 }
2792  	 	 	 // correct internal cell padding if required to avoid overlap between text and lines
2793  	 	 	 if (
2794  	 	 	 	 is_numeric($this->cell_padding['T'])
2795  	 	 	 	 && ($this->cell_padding['T'] < $adj)
2796  	 	 	 	 && (strpos($border, 'T') !== false)
2797  	 	 	 ) {
2798  	 	 	 	 $this->cell_padding['T'] = $adj;
2799  	 	 	 }
2800  	 	 	 if (
2801  	 	 	 	 is_numeric($this->cell_padding['R'])
2802  	 	 	 	 && ($this->cell_padding['R'] < $adj)
2803  	 	 	 	 && (strpos($border, 'R') !== false)
2804  	 	 	 ) {
2805  	 	 	 	 $this->cell_padding['R'] = $adj;
2806  	 	 	 }
2807  	 	 	 if (
2808  	 	 	 	 is_numeric($this->cell_padding['B'])
2809  	 	 	 	 && ($this->cell_padding['B'] < $adj)
2810  	 	 	 	 && (strpos($border, 'B') !== false)
2811  	 	 	 ) {
2812  	 	 	 	 $this->cell_padding['B'] = $adj;
2813  	 	 	 }
2814  	 	 	 if (
2815  	 	 	 	 is_numeric($this->cell_padding['L'])
2816  	 	 	 	 && ($this->cell_padding['L'] < $adj)
2817  	 	 	 	 && (strpos($border, 'L') !== false)
2818  	 	 	 ) {
2819  	 	 	 	 $this->cell_padding['L'] = $adj;
2820  	 	 	 }
2821  
2822  	 	 }
2823  
2824  	 	 return array(
2825  	 	 	 'T' => ($this->cell_padding['T'] - $cp['T']),
2826  	 	 	 'R' => ($this->cell_padding['R'] - $cp['R']),
2827  	 	 	 'B' => ($this->cell_padding['B'] - $cp['B']),
2828  	 	 	 'L' => ($this->cell_padding['L'] - $cp['L']),
2829  	 	 );
2830  	 }
2831  
2832  	 /**
2833  	  * Enables or disables the automatic page breaking mode. When enabling, the second parameter is the distance from the bottom of the page that defines the triggering limit. By default, the mode is on and the margin is 2 cm.
2834  	  * @param $auto (boolean) Boolean indicating if mode should be on or off.
2835  	  * @param $margin (float) Distance from the bottom of the page.
2836  	  * @public
2837  	  * @since 1.0
2838  	  * @see Cell(), MultiCell(), AcceptPageBreak()
2839  	  */
2840  	public function SetAutoPageBreak($auto, $margin=0) {
2841  	 	 $this->AutoPageBreak = $auto ? true : false;
2842  	 	 $this->bMargin = $margin;
2843  	 	 $this->PageBreakTrigger = $this->h - $margin;
2844  	 }
2845  
2846  	 /**
2847  	  * Return the auto-page-break mode (true or false).
2848  	  * @return boolean auto-page-break mode
2849  	  * @public
2850  	  * @since 5.9.088
2851  	  */
2852  	public function getAutoPageBreak() {
2853  	 	 return $this->AutoPageBreak;
2854  	 }
2855  
2856  	 /**
2857  	  * Defines the way the document is to be displayed by the viewer.
2858  	  * @param $zoom (mixed) The zoom to use. It can be one of the following string values or a number indicating the zooming factor to use. <ul><li>fullpage: displays the entire page on screen </li><li>fullwidth: uses maximum width of window</li><li>real: uses real size (equivalent to 100% zoom)</li><li>default: uses viewer default mode</li></ul>
2859  	  * @param $layout (string) The page layout. Possible values are:<ul><li>SinglePage Display one page at a time</li><li>OneColumn Display the pages in one column</li><li>TwoColumnLeft Display the pages in two columns, with odd-numbered pages on the left</li><li>TwoColumnRight Display the pages in two columns, with odd-numbered pages on the right</li><li>TwoPageLeft (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the left</li><li>TwoPageRight (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the right</li></ul>
2860  	  * @param $mode (string) A name object specifying how the document should be displayed when opened:<ul><li>UseNone Neither document outline nor thumbnail images visible</li><li>UseOutlines Document outline visible</li><li>UseThumbs Thumbnail images visible</li><li>FullScreen Full-screen mode, with no menu bar, window controls, or any other window visible</li><li>UseOC (PDF 1.5) Optional content group panel visible</li><li>UseAttachments (PDF 1.6) Attachments panel visible</li></ul>
2861  	  * @public
2862  	  * @since 1.2
2863  	  */
2864  	public function SetDisplayMode($zoom, $layout='SinglePage', $mode='UseNone') {
2865  	 	 if (($zoom == 'fullpage') OR ($zoom == 'fullwidth') OR ($zoom == 'real') OR ($zoom == 'default') OR (!is_string($zoom))) {
2866  	 	 	 $this->ZoomMode = $zoom;
2867  	 	 } else {
2868  	 	 	 $this->Error('Incorrect zoom display mode: '.$zoom);
2869  	 	 }
2870  	 	 $this->LayoutMode = TCPDF_STATIC::getPageLayoutMode($layout);
2871  	 	 $this->PageMode = TCPDF_STATIC::getPageMode($mode);
2872  	 }
2873  
2874  	 /**
2875  	  * Activates or deactivates page compression. When activated, the internal representation of each page is compressed, which leads to a compression ratio of about 2 for the resulting document. Compression is on by default.
2876  	  * Note: the Zlib extension is required for this feature. If not present, compression will be turned off.
2877  	  * @param $compress (boolean) Boolean indicating if compression must be enabled.
2878  	  * @public
2879  	  * @since 1.4
2880  	  */
2881  	public function SetCompression($compress=true) {
2882  	 	 $this->compress = false;
2883  	 	 if (function_exists('gzcompress')) {
2884  	 	 	 if ($compress) {
2885  	 	 	 	 if ( !$this->pdfa_mode) {
2886  	 	 	 	 	 $this->compress = true;
2887  	 	 	 	 }
2888  	 	 	 }
2889  	 	 }
2890  	 }
2891  
2892  	 /**
2893  	  * Set flag to force sRGB_IEC61966-2.1 black scaled ICC color profile for the whole document.
2894  	  * @param $mode (boolean) If true force sRGB output intent.
2895  	  * @public
2896  	  * @since 5.9.121 (2011-09-28)
2897  	  */
2898  	public function setSRGBmode($mode=false) {
2899  	 	 $this->force_srgb = $mode ? true : false;
2900  	 }
2901  
2902  	 /**
2903  	  * Turn on/off Unicode mode for document information dictionary (meta tags).
2904  	  * This has effect only when unicode mode is set to false.
2905  	  * @param $unicode (boolean) if true set the meta information in Unicode
2906  	  * @since 5.9.027 (2010-12-01)
2907  	  * @public
2908  	  */
2909  	public function SetDocInfoUnicode($unicode=true) {
2910  	 	 $this->docinfounicode = $unicode ? true : false;
2911  	 }
2912  
2913  	 /**
2914  	  * Defines the title of the document.
2915  	  * @param $title (string) The title.
2916  	  * @public
2917  	  * @since 1.2
2918  	  * @see SetAuthor(), SetCreator(), SetKeywords(), SetSubject()
2919  	  */
2920  	public function SetTitle($title) {
2921  	 	 $this->title = $title;
2922  	 }
2923  
2924  	 /**
2925  	  * Defines the subject of the document.
2926  	  * @param $subject (string) The subject.
2927  	  * @public
2928  	  * @since 1.2
2929  	  * @see SetAuthor(), SetCreator(), SetKeywords(), SetTitle()
2930  	  */
2931  	public function SetSubject($subject) {
2932  	 	 $this->subject = $subject;
2933  	 }
2934  
2935  	 /**
2936  	  * Defines the author of the document.
2937  	  * @param $author (string) The name of the author.
2938  	  * @public
2939  	  * @since 1.2
2940  	  * @see SetCreator(), SetKeywords(), SetSubject(), SetTitle()
2941  	  */
2942  	public function SetAuthor($author) {
2943  	 	 $this->author = $author;
2944  	 }
2945  
2946  	 /**
2947  	  * Associates keywords with the document, generally in the form 'keyword1 keyword2 ...'.
2948  	  * @param $keywords (string) The list of keywords.
2949  	  * @public
2950  	  * @since 1.2
2951  	  * @see SetAuthor(), SetCreator(), SetSubject(), SetTitle()
2952  	  */
2953  	public function SetKeywords($keywords) {
2954  	 	 $this->keywords = $keywords;
2955  	 }
2956  
2957  	 /**
2958  	  * Defines the creator of the document. This is typically the name of the application that generates the PDF.
2959  	  * @param $creator (string) The name of the creator.
2960  	  * @public
2961  	  * @since 1.2
2962  	  * @see SetAuthor(), SetKeywords(), SetSubject(), SetTitle()
2963  	  */
2964  	public function SetCreator($creator) {
2965  	 	 $this->creator = $creator;
2966  	 }
2967  
2968  	 /**
2969  	  * Whether to allow local file path in image html tags, when prefixed with file://
2970  	  * 
2971  	  * @param $allowLocalFiles bool true, when local files should be allowed. Otherwise false.
2972  	  * @public
2973  	  * @since 6.4
2974  	  */
2975  	public function SetAllowLocalFiles($allowLocalFiles) {
2976  	 	 $this->allowLocalFiles = (bool) $allowLocalFiles;
2977  	 }
2978  
2979  
2980  	 /**
2981  	  * Throw an exception or print an error message and die if the K_TCPDF_PARSER_THROW_EXCEPTION_ERROR constant is set to true.
2982  	  * @param $msg (string) The error message
2983  	  * @public
2984  	  * @since 1.0
2985  	  */
2986  	public function Error($msg) {
2987  	 	 // unset all class variables
2988  	 	 $this->_destroy(true);
2989  	 	 if (defined('K_TCPDF_THROW_EXCEPTION_ERROR') AND !K_TCPDF_THROW_EXCEPTION_ERROR) {
2990  	 	 	 die('<strong>TCPDF ERROR: </strong>'.$msg);
2991  	 	 } else {
2992  	 	 	 throw new Exception('TCPDF ERROR: '.$msg);
2993  	 	 }
2994  	 }
2995  
2996  	 /**
2997  	  * This method begins the generation of the PDF document.
2998  	  * It is not necessary to call it explicitly because AddPage() does it automatically.
2999  	  * Note: no page is created by this method
3000  	  * @public
3001  	  * @since 1.0
3002  	  * @see AddPage(), Close()
3003  	  */
3004  	public function Open() {
3005  	 	 $this->state = 1;
3006  	 }
3007  
3008  	 /**
3009  	  * Terminates the PDF document.
3010  	  * It is not necessary to call this method explicitly because Output() does it automatically.
3011  	  * If the document contains no page, AddPage() is called to prevent from getting an invalid document.
3012  	  * @public
3013  	  * @since 1.0
3014  	  * @see Open(), Output()
3015  	  */
3016  	public function Close() {
3017  	 	 if ($this->state == 3) {
3018  	 	 	 return;
3019  	 	 }
3020  	 	 if ($this->page == 0) {
3021  	 	 	 $this->AddPage();
3022  	 	 }
3023  	 	 $this->endLayer();
3024  	 	 if ($this->tcpdflink) {
3025  	 	 	 // save current graphic settings
3026  	 	 	 $gvars = $this->getGraphicVars();
3027  	 	 	 $this->setEqualColumns();
3028  	 	 	 $this->lastpage(true);
3029  	 	 	 $this->SetAutoPageBreak(false);
3030  	 	 	 $this->x = 0;
3031  	 	 	 $this->y = $this->h - (1 / $this->k);
3032  	 	 	 $this->lMargin = 0;
3033  	 	 	 $this->_outSaveGraphicsState();
3034  	 	 	 $font = defined('PDF_FONT_NAME_MAIN')?PDF_FONT_NAME_MAIN:'helvetica';
3035  	 	 	 $this->SetFont($font, '', 1);
3036  	 	 	 $this->setTextRenderingMode(0, false, false);
3037  	 	 	 $msg = "\x50\x6f\x77\x65\x72\x65\x64\x20\x62\x79\x20\x54\x43\x50\x44\x46\x20\x28\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67\x29";
3038  	 	 	 $lnk = "\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67";
3039  	 	 	 $this->Cell(0, 0, $msg, 0, 0, 'L', 0, $lnk, 0, false, 'D', 'B');
3040  	 	 	 $this->_outRestoreGraphicsState();
3041  	 	 	 // restore graphic settings
3042  	 	 	 $this->setGraphicVars($gvars);
3043  	 	 }
3044  	 	 // close page
3045  	 	 $this->endPage();
3046  	 	 // close document
3047  	 	 $this->_enddoc();
3048  	 	 // unset all class variables (except critical ones)
3049  	 	 $this->_destroy(false);
3050  	 }
3051  
3052  	 /**
3053  	  * Move pointer at the specified document page and update page dimensions.
3054  	  * @param $pnum (int) page number (1 ... numpages)
3055  	  * @param $resetmargins (boolean) if true reset left, right, top margins and Y position.
3056  	  * @public
3057  	  * @since 2.1.000 (2008-01-07)
3058  	  * @see getPage(), lastpage(), getNumPages()
3059  	  */
3060  	public function setPage($pnum, $resetmargins=false) {
3061  	 	 if (($pnum == $this->page) AND ($this->state == 2)) {
3062  	 	 	 return;
3063  	 	 }
3064  	 	 if (($pnum > 0) AND ($pnum <= $this->numpages)) {
3065  	 	 	 $this->state = 2;
3066  	 	 	 // save current graphic settings
3067  	 	 	 //$gvars = $this->getGraphicVars();
3068  	 	 	 $oldpage = $this->page;
3069  	 	 	 $this->page = $pnum;
3070  	 	 	 $this->wPt = $this->pagedim[$this->page]['w'];
3071  	 	 	 $this->hPt = $this->pagedim[$this->page]['h'];
3072  	 	 	 $this->w = $this->pagedim[$this->page]['wk'];
3073  	 	 	 $this->h = $this->pagedim[$this->page]['hk'];
3074  	 	 	 $this->tMargin = $this->pagedim[$this->page]['tm'];
3075  	 	 	 $this->bMargin = $this->pagedim[$this->page]['bm'];
3076  	 	 	 $this->original_lMargin = $this->pagedim[$this->page]['olm'];
3077  	 	 	 $this->original_rMargin = $this->pagedim[$this->page]['orm'];
3078  	 	 	 $this->AutoPageBreak = $this->pagedim[$this->page]['pb'];
3079  	 	 	 $this->CurOrientation = $this->pagedim[$this->page]['or'];
3080  	 	 	 $this->SetAutoPageBreak($this->AutoPageBreak, $this->bMargin);
3081  	 	 	 // restore graphic settings
3082  	 	 	 //$this->setGraphicVars($gvars);
3083  	 	 	 if ($resetmargins) {
3084  	 	 	 	 $this->lMargin = $this->pagedim[$this->page]['olm'];
3085  	 	 	 	 $this->rMargin = $this->pagedim[$this->page]['orm'];
3086  	 	 	 	 $this->SetY($this->tMargin);
3087  	 	 	 } else {
3088  	 	 	 	 // account for booklet mode
3089  	 	 	 	 if ($this->pagedim[$this->page]['olm'] != $this->pagedim[$oldpage]['olm']) {
3090  	 	 	 	 	 $deltam = $this->pagedim[$this->page]['olm'] - $this->pagedim[$this->page]['orm'];
3091  	 	 	 	 	 $this->lMargin += $deltam;
3092  	 	 	 	 	 $this->rMargin -= $deltam;
3093  	 	 	 	 }
3094  	 	 	 }
3095  	 	 } else {
3096  	 	 	 $this->Error('Wrong page number on setPage() function: '.$pnum);
3097  	 	 }
3098  	 }
3099  
3100  	 /**
3101  	  * Reset pointer to the last document page.
3102  	  * @param $resetmargins (boolean) if true reset left, right, top margins and Y position.
3103  	  * @public
3104  	  * @since 2.0.000 (2008-01-04)
3105  	  * @see setPage(), getPage(), getNumPages()
3106  	  */
3107  	public function lastPage($resetmargins=false) {
3108  	 	 $this->setPage($this->getNumPages(), $resetmargins);
3109  	 }
3110  
3111  	 /**
3112  	  * Get current document page number.
3113  	  * @return int page number
3114  	  * @public
3115  	  * @since 2.1.000 (2008-01-07)
3116  	  * @see setPage(), lastpage(), getNumPages()
3117  	  */
3118  	public function getPage() {
3119  	 	 return $this->page;
3120  	 }
3121  
3122  	 /**
3123  	  * Get the total number of insered pages.
3124  	  * @return int number of pages
3125  	  * @public
3126  	  * @since 2.1.000 (2008-01-07)
3127  	  * @see setPage(), getPage(), lastpage()
3128  	  */
3129  	public function getNumPages() {
3130  	 	 return $this->numpages;
3131  	 }
3132  
3133  	 /**
3134  	  * Adds a new TOC (Table Of Content) page to the document.
3135  	  * @param $orientation (string) page orientation.
3136  	  * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat().
3137  	  * @param $keepmargins (boolean) if true overwrites the default page margins with the current margins
3138  	  * @public
3139  	  * @since 5.0.001 (2010-05-06)
3140  	  * @see AddPage(), startPage(), endPage(), endTOCPage()
3141  	  */
3142  	public function addTOCPage($orientation='', $format='', $keepmargins=false) {
3143  	 	 $this->AddPage($orientation, $format, $keepmargins, true);
3144  	 }
3145  
3146  	 /**
3147  	  * Terminate the current TOC (Table Of Content) page
3148  	  * @public
3149  	  * @since 5.0.001 (2010-05-06)
3150  	  * @see AddPage(), startPage(), endPage(), addTOCPage()
3151  	  */
3152  	public function endTOCPage() {
3153  	 	 $this->endPage(true);
3154  	 }
3155  
3156  	 /**
3157  	  * Adds a new page to the document. If a page is already present, the Footer() method is called first to output the footer (if enabled). Then the page is added, the current position set to the top-left corner according to the left and top margins (or top-right if in RTL mode), and Header() is called to display the header (if enabled).
3158  	  * The origin of the coordinate system is at the top-left corner (or top-right for RTL) and increasing ordinates go downwards.
3159  	  * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or PORTRAIT (default)</li><li>L or LANDSCAPE</li></ul>
3160  	  * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat().
3161  	  * @param $keepmargins (boolean) if true overwrites the default page margins with the current margins
3162  	  * @param $tocpage (boolean) if true set the tocpage state to true (the added page will be used to display Table Of Content).
3163  	  * @public
3164  	  * @since 1.0
3165  	  * @see startPage(), endPage(), addTOCPage(), endTOCPage(), getPageSizeFromFormat(), setPageFormat()
3166  	  */
3167  	public function AddPage($orientation='', $format='', $keepmargins=false, $tocpage=false) {
3168  	 	 if ($this->inxobj) {
3169  	 	 	 // we are inside an XObject template
3170  	 	 	 return;
3171  	 	 }
3172  	 	 if (!isset($this->original_lMargin) OR $keepmargins) {
3173  	 	 	 $this->original_lMargin = $this->lMargin;
3174  	 	 }
3175  	 	 if (!isset($this->original_rMargin) OR $keepmargins) {
3176  	 	 	 $this->original_rMargin = $this->rMargin;
3177  	 	 }
3178  	 	 // terminate previous page
3179  	 	 $this->endPage();
3180  	 	 // start new page
3181  	 	 $this->startPage($orientation, $format, $tocpage);
3182  	 }
3183  
3184  	 /**
3185  	  * Terminate the current page
3186  	  * @param $tocpage (boolean) if true set the tocpage state to false (end the page used to display Table Of Content).
3187  	  * @public
3188  	  * @since 4.2.010 (2008-11-14)
3189  	  * @see AddPage(), startPage(), addTOCPage(), endTOCPage()
3190  	  */
3191  	public function endPage($tocpage=false) {
3192  	 	 // check if page is already closed
3193  	 	 if (($this->page == 0) OR ($this->numpages > $this->page) OR (!$this->pageopen[$this->page])) {
3194  	 	 	 return;
3195  	 	 }
3196  	 	 // print page footer
3197  	 	 $this->setFooter();
3198  	 	 // close page
3199  	 	 $this->_endpage();
3200  	 	 // mark page as closed
3201  	 	 $this->pageopen[$this->page] = false;
3202  	 	 if ($tocpage) {
3203  	 	 	 $this->tocpage = false;
3204  	 	 }
3205  	 }
3206  
3207  	 /**
3208  	  * Starts a new page to the document. The page must be closed using the endPage() function.
3209  	  * The origin of the coordinate system is at the top-left corner and increasing ordinates go downwards.
3210  	  * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or PORTRAIT (default)</li><li>L or LANDSCAPE</li></ul>
3211  	  * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat().
3212  	  * @param $tocpage (boolean) if true the page is designated to contain the Table-Of-Content.
3213  	  * @since 4.2.010 (2008-11-14)
3214  	  * @see AddPage(), endPage(), addTOCPage(), endTOCPage(), getPageSizeFromFormat(), setPageFormat()
3215  	  * @public
3216  	  */
3217  	public function startPage($orientation='', $format='', $tocpage=false) {
3218  	 	 if ($tocpage) {
3219  	 	 	 $this->tocpage = true;
3220  	 	 }
3221  	 	 // move page numbers of documents to be attached
3222  	 	 if ($this->tocpage) {
3223  	 	 	 // move reference to unexistent pages (used for page attachments)
3224  	 	 	 // adjust outlines
3225  	 	 	 $tmpoutlines = $this->outlines;
3226  	 	 	 foreach ($tmpoutlines as $key => $outline) {
3227  	 	 	 	 if (!$outline['f'] AND ($outline['p'] > $this->numpages)) {
3228  	 	 	 	 	 $this->outlines[$key]['p'] = ($outline['p'] + 1);
3229  	 	 	 	 }
3230  	 	 	 }
3231  	 	 	 // adjust dests
3232  	 	 	 $tmpdests = $this->dests;
3233  	 	 	 foreach ($tmpdests as $key => $dest) {
3234  	 	 	 	 if (!$dest['f'] AND ($dest['p'] > $this->numpages)) {
3235  	 	 	 	 	 $this->dests[$key]['p'] = ($dest['p'] + 1);
3236  	 	 	 	 }
3237  	 	 	 }
3238  	 	 	 // adjust links
3239  	 	 	 $tmplinks = $this->links;
3240  	 	 	 foreach ($tmplinks as $key => $link) {
3241  	 	 	 	 if (!$link['f'] AND ($link['p'] > $this->numpages)) {
3242  	 	 	 	 	 $this->links[$key]['p'] = ($link['p'] + 1);
3243  	 	 	 	 }
3244  	 	 	 }
3245  	 	 }
3246  	 	 if ($this->numpages > $this->page) {
3247  	 	 	 // this page has been already added
3248  	 	 	 $this->setPage($this->page + 1);
3249  	 	 	 $this->SetY($this->tMargin);
3250  	 	 	 return;
3251  	 	 }
3252  	 	 // start a new page
3253  	 	 if ($this->state == 0) {
3254  	 	 	 $this->Open();
3255  	 	 }
3256  	 	 ++$this->numpages;
3257  	 	 $this->swapMargins($this->booklet);
3258  	 	 // save current graphic settings
3259  	 	 $gvars = $this->getGraphicVars();
3260  	 	 // start new page
3261  	 	 $this->_beginpage($orientation, $format);
3262  	 	 // mark page as open
3263  	 	 $this->pageopen[$this->page] = true;
3264  	 	 // restore graphic settings
3265  	 	 $this->setGraphicVars($gvars);
3266  	 	 // mark this point
3267  	 	 $this->setPageMark();
3268  	 	 // print page header
3269  	 	 $this->setHeader();
3270  	 	 // restore graphic settings
3271  	 	 $this->setGraphicVars($gvars);
3272  	 	 // mark this point
3273  	 	 $this->setPageMark();
3274  	 	 // print table header (if any)
3275  	 	 $this->setTableHeader();
3276  	 	 // set mark for empty page check
3277  	 	 $this->emptypagemrk[$this->page]= $this->pagelen[$this->page];
3278  	 }
3279  
3280  	 /**
3281  	  * Set start-writing mark on current page stream used to put borders and fills.
3282  	  * Borders and fills are always created after content and inserted on the position marked by this method.
3283  	  * This function must be called after calling Image() function for a background image.
3284  	  * Background images must be always inserted before calling Multicell() or WriteHTMLCell() or WriteHTML() functions.
3285  	  * @public
3286  	  * @since 4.0.016 (2008-07-30)
3287  	  */
3288  	public function setPageMark() {
3289  	 	 $this->intmrk[$this->page] = $this->pagelen[$this->page];
3290  	 	 $this->bordermrk[$this->page] = $this->intmrk[$this->page];
3291  	 	 $this->setContentMark();
3292  	 }
3293  
3294  	 /**
3295  	  * Set start-writing mark on selected page.
3296  	  * Borders and fills are always created after content and inserted on the position marked by this method.
3297  	  * @param $page (int) page number (default is the current page)
3298  	  * @protected
3299  	  * @since 4.6.021 (2009-07-20)
3300  	  */
3301  	protected function setContentMark($page=0) {
3302  	 	 if ($page <= 0) {
3303  	 	 	 $page = $this->page;
3304  	 	 }
3305  	 	 if (isset($this->footerlen[$page])) {
3306  	 	 	 $this->cntmrk[$page] = $this->pagelen[$page] - $this->footerlen[$page];
3307  	 	 } else {
3308  	 	 	 $this->cntmrk[$page] = $this->pagelen[$page];
3309  	 	 }
3310  	 }
3311  
3312  	 /**
3313  	  * Set header data.
3314  	  * @param $ln (string) header image logo
3315  	  * @param $lw (string) header image logo width in mm
3316  	  * @param $ht (string) string to print as title on document header
3317  	  * @param $hs (string) string to print on document header
3318  	  * @param $tc (array) RGB array color for text.
3319  	  * @param $lc (array) RGB array color for line.
3320  	  * @public
3321  	  */
3322  	public function setHeaderData($ln='', $lw=0, $ht='', $hs='', $tc=array(0,0,0), $lc=array(0,0,0)) {
3323  	 	 $this->header_logo = $ln;
3324  	 	 $this->header_logo_width = $lw;
3325  	 	 $this->header_title = $ht;
3326  	 	 $this->header_string = $hs;
3327  	 	 $this->header_text_color = $tc;
3328  	 	 $this->header_line_color = $lc;
3329  	 }
3330  
3331  	 /**
3332  	  * Set footer data.
3333  	  * @param $tc (array) RGB array color for text.
3334  	  * @param $lc (array) RGB array color for line.
3335  	  * @public
3336  	  */
3337  	public function setFooterData($tc=array(0,0,0), $lc=array(0,0,0)) {
3338  	 	 $this->footer_text_color = $tc;
3339  	 	 $this->footer_line_color = $lc;
3340  	 }
3341  
3342  	 /**
3343  	  * Returns header data:
3344  	  * <ul><li>$ret['logo'] = logo image</li><li>$ret['logo_width'] = width of the image logo in user units</li><li>$ret['title'] = header title</li><li>$ret['string'] = header description string</li></ul>
3345  	  * @return array()
3346  	  * @public
3347  	  * @since 4.0.012 (2008-07-24)
3348  	  */
3349  	public function getHeaderData() {
3350  	 	 $ret = array();
3351  	 	 $ret['logo'] = $this->header_logo;
3352  	 	 $ret['logo_width'] = $this->header_logo_width;
3353  	 	 $ret['title'] = $this->header_title;
3354  	 	 $ret['string'] = $this->header_string;
3355  	 	 $ret['text_color'] = $this->header_text_color;
3356  	 	 $ret['line_color'] = $this->header_line_color;
3357  	 	 return $ret;
3358  	 }
3359  
3360  	 /**
3361  	  * Set header margin.
3362  	  * (minimum distance between header and top page margin)
3363  	  * @param $hm (int) distance in user units
3364  	  * @public
3365  	  */
3366  	public function setHeaderMargin($hm=10) {
3367  	 	 $this->header_margin = $hm;
3368  	 }
3369  
3370  	 /**
3371  	  * Returns header margin in user units.
3372  	  * @return float
3373  	  * @since 4.0.012 (2008-07-24)
3374  	  * @public
3375  	  */
3376  	public function getHeaderMargin() {
3377  	 	 return $this->header_margin;
3378  	 }
3379  
3380  	 /**
3381  	  * Set footer margin.
3382  	  * (minimum distance between footer and bottom page margin)
3383  	  * @param $fm (int) distance in user units
3384  	  * @public
3385  	  */
3386  	public function setFooterMargin($fm=10) {
3387  	 	 $this->footer_margin = $fm;
3388  	 }
3389  
3390  	 /**
3391  	  * Returns footer margin in user units.
3392  	  * @return float
3393  	  * @since 4.0.012 (2008-07-24)
3394  	  * @public
3395  	  */
3396  	public function getFooterMargin() {
3397  	 	 return $this->footer_margin;
3398  	 }
3399  	 /**
3400  	  * Set a flag to print page header.
3401  	  * @param $val (boolean) set to true to print the page header (default), false otherwise.
3402  	  * @public
3403  	  */
3404  	public function setPrintHeader($val=true) {
3405  	 	 $this->print_header = $val ? true : false;
3406  	 }
3407  
3408  	 /**
3409  	  * Set a flag to print page footer.
3410  	  * @param $val (boolean) set to true to print the page footer (default), false otherwise.
3411  	  * @public
3412  	  */
3413  	public function setPrintFooter($val=true) {
3414  	 	 $this->print_footer = $val ? true : false;
3415  	 }
3416  
3417  	 /**
3418  	  * Return the right-bottom (or left-bottom for RTL) corner X coordinate of last inserted image
3419  	  * @return float
3420  	  * @public
3421  	  */
3422  	public function getImageRBX() {
3423  	 	 return $this->img_rb_x;
3424  	 }
3425  
3426  	 /**
3427  	  * Return the right-bottom (or left-bottom for RTL) corner Y coordinate of last inserted image
3428  	  * @return float
3429  	  * @public
3430  	  */
3431  	public function getImageRBY() {
3432  	 	 return $this->img_rb_y;
3433  	 }
3434  
3435  	 /**
3436  	  * Reset the xobject template used by Header() method.
3437  	  * @public
3438  	  */
3439  	public function resetHeaderTemplate() {
3440  	 	 $this->header_xobjid = false;
3441  	 }
3442  
3443  	 /**
3444  	  * Set a flag to automatically reset the xobject template used by Header() method at each page.
3445  	  * @param $val (boolean) set to true to reset Header xobject template at each page, false otherwise.
3446  	  * @public
3447  	  */
3448  	public function setHeaderTemplateAutoreset($val=true) {
3449  	 	 $this->header_xobj_autoreset = $val ? true : false;
3450  	 }
3451  
3452  	 /**
3453  	  * This method is used to render the page header.
3454  	  * It is automatically called by AddPage() and could be overwritten in your own inherited class.
3455  	  * @public
3456  	  */
3457  	public function Header() {
3458  	 	 if ($this->header_xobjid === false) {
3459  	 	 	 // start a new XObject Template
3460  	 	 	 $this->header_xobjid = $this->startTemplate($this->w, $this->tMargin);
3461  	 	 	 $headerfont = $this->getHeaderFont();
3462  	 	 	 $headerdata = $this->getHeaderData();
3463  	 	 	 $this->y = $this->header_margin;
3464  	 	 	 if ($this->rtl) {
3465  	 	 	 	 $this->x = $this->w - $this->original_rMargin;
3466  	 	 	 } else {
3467  	 	 	 	 $this->x = $this->original_lMargin;
3468  	 	 	 }
3469  	 	 	 if (($headerdata['logo']) AND ($headerdata['logo'] != K_BLANK_IMAGE)) {
3470  	 	 	 	 $imgtype = TCPDF_IMAGES::getImageFileType(K_PATH_IMAGES.$headerdata['logo']);
3471  	 	 	 	 if (($imgtype == 'eps') OR ($imgtype == 'ai')) {
3472  	 	 	 	 	 $this->ImageEps(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']);
3473  	 	 	 	 } elseif ($imgtype == 'svg') {
3474  	 	 	 	 	 $this->ImageSVG(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']);
3475  	 	 	 	 } else {
3476  	 	 	 	 	 $this->Image(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']);
3477  	 	 	 	 }
3478  	 	 	 	 $imgy = $this->getImageRBY();
3479  	 	 	 } else {
3480  	 	 	 	 $imgy = $this->y;
3481  	 	 	 }
3482  	 	 	 $cell_height = $this->getCellHeight($headerfont[2] / $this->k);
3483  	 	 	 // set starting margin for text data cell
3484  	 	 	 if ($this->getRTL()) {
3485  	 	 	 	 $header_x = $this->original_rMargin + ($headerdata['logo_width'] * 1.1);
3486  	 	 	 } else {
3487  	 	 	 	 $header_x = $this->original_lMargin + ($headerdata['logo_width'] * 1.1);
3488  	 	 	 }
3489  	 	 	 $cw = $this->w - $this->original_lMargin - $this->original_rMargin - ($headerdata['logo_width'] * 1.1);
3490  	 	 	 $this->SetTextColorArray($this->header_text_color);
3491  	 	 	 // header title
3492  	 	 	 $this->SetFont($headerfont[0], 'B', $headerfont[2] + 1);
3493  	 	 	 $this->SetX($header_x);
3494  	 	 	 $this->Cell($cw, $cell_height, $headerdata['title'], 0, 1, '', 0, '', 0);
3495  	 	 	 // header string
3496  	 	 	 $this->SetFont($headerfont[0], $headerfont[1], $headerfont[2]);
3497  	 	 	 $this->SetX($header_x);
3498  	 	 	 $this->MultiCell($cw, $cell_height, $headerdata['string'], 0, '', 0, 1, '', '', true, 0, false, true, 0, 'T', false);
3499  	 	 	 // print an ending header line
3500  	 	 	 $this->SetLineStyle(array('width' => 0.85 / $this->k, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $headerdata['line_color']));
3501  	 	 	 $this->SetY((2.835 / $this->k) + max($imgy, $this->y));
3502  	 	 	 if ($this->rtl) {
3503  	 	 	 	 $this->SetX($this->original_rMargin);
3504  	 	 	 } else {
3505  	 	 	 	 $this->SetX($this->original_lMargin);
3506  	 	 	 }
3507  	 	 	 $this->Cell(($this->w - $this->original_lMargin - $this->original_rMargin), 0, '', 'T', 0, 'C');
3508  	 	 	 $this->endTemplate();
3509  	 	 }
3510  	 	 // print header template
3511  	 	 $x = 0;
3512  	 	 $dx = 0;
3513  	 	 if (!$this->header_xobj_autoreset AND $this->booklet AND (($this->page % 2) == 0)) {
3514  	 	 	 // adjust margins for booklet mode
3515  	 	 	 $dx = ($this->original_lMargin - $this->original_rMargin);
3516  	 	 }
3517  	 	 if ($this->rtl) {
3518  	 	 	 $x = $this->w + $dx;
3519  	 	 } else {
3520  	 	 	 $x = 0 + $dx;
3521  	 	 }
3522  	 	 $this->printTemplate($this->header_xobjid, $x, 0, 0, 0, '', '', false);
3523  	 	 if ($this->header_xobj_autoreset) {
3524  	 	 	 // reset header xobject template at each page
3525  	 	 	 $this->header_xobjid = false;
3526  	 	 }
3527  	 }
3528  
3529  	 /**
3530  	  * This method is used to render the page footer.
3531  	  * It is automatically called by AddPage() and could be overwritten in your own inherited class.
3532  	  * @public
3533  	  */
3534  	public function Footer() {
3535  	 	 $cur_y = $this->y;
3536  	 	 $this->SetTextColorArray($this->footer_text_color);
3537  	 	 //set style for cell border
3538  	 	 $line_width = (0.85 / $this->k);
3539  	 	 $this->SetLineStyle(array('width' => $line_width, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $this->footer_line_color));
3540  	 	 //print document barcode
3541  	 	 $barcode = $this->getBarcode();
3542  	 	 if (!empty($barcode)) {
3543  	 	 	 $this->Ln($line_width);
3544  	 	 	 $barcode_width = round(($this->w - $this->original_lMargin - $this->original_rMargin) / 3);
3545  	 	 	 $style = array(
3546  	 	 	 	 'position' => $this->rtl?'R':'L',
3547  	 	 	 	 'align' => $this->rtl?'R':'L',
3548  	 	 	 	 'stretch' => false,
3549  	 	 	 	 'fitwidth' => true,
3550  	 	 	 	 'cellfitalign' => '',
3551  	 	 	 	 'border' => false,
3552  	 	 	 	 'padding' => 0,
3553  	 	 	 	 'fgcolor' => array(0,0,0),
3554  	 	 	 	 'bgcolor' => false,
3555  	 	 	 	 'text' => false
3556  	 	 	 );
3557  	 	 	 $this->write1DBarcode($barcode, 'C128', '', $cur_y + $line_width, '', (($this->footer_margin / 3) - $line_width), 0.3, $style, '');
3558  	 	 }
3559  	 	 $w_page = isset($this->l['w_page']) ? $this->l['w_page'].' ' : '';
3560  	 	 if (empty($this->pagegroups)) {
3561  	 	 	 $pagenumtxt = $w_page.$this->getAliasNumPage().' / '.$this->getAliasNbPages();
3562  	 	 } else {
3563  	 	 	 $pagenumtxt = $w_page.$this->getPageNumGroupAlias().' / '.$this->getPageGroupAlias();
3564  	 	 }
3565  	 	 $this->SetY($cur_y);
3566  	 	 //Print page number
3567  	 	 if ($this->getRTL()) {
3568  	 	 	 $this->SetX($this->original_rMargin);
3569  	 	 	 $this->Cell(0, 0, $pagenumtxt, 'T', 0, 'L');
3570  	 	 } else {
3571  	 	 	 $this->SetX($this->original_lMargin);
3572  	 	 	 $this->Cell(0, 0, $this->getAliasRightShift().$pagenumtxt, 'T', 0, 'R');
3573  	 	 }
3574  	 }
3575  
3576  	 /**
3577  	  * This method is used to render the page header.
3578  	  * @protected
3579  	  * @since 4.0.012 (2008-07-24)
3580  	  */
3581  	protected function setHeader() {
3582  	 	 if (!$this->print_header OR ($this->state != 2)) {
3583  	 	 	 return;
3584  	 	 }
3585  	 	 $this->InHeader = true;
3586  	 	 $this->setGraphicVars($this->default_graphic_vars);
3587  	 	 $temp_thead = $this->thead;
3588  	 	 $temp_theadMargins = $this->theadMargins;
3589  	 	 $lasth = $this->lasth;
3590  	 	 $newline = $this->newline;
3591  	 	 $this->_outSaveGraphicsState();
3592  	 	 $this->rMargin = $this->original_rMargin;
3593  	 	 $this->lMargin = $this->original_lMargin;
3594  	 	 $this->SetCellPadding(0);
3595  	 	 //set current position
3596  	 	 if ($this->rtl) {
3597  	 	 	 $this->SetXY($this->original_rMargin, $this->header_margin);
3598  	 	 } else {
3599  	 	 	 $this->SetXY($this->original_lMargin, $this->header_margin);
3600  	 	 }
3601  	 	 $this->SetFont($this->header_font[0], $this->header_font[1], $this->header_font[2]);
3602  	 	 $this->Header();
3603  	 	 //restore position
3604  	 	 if ($this->rtl) {
3605  	 	 	 $this->SetXY($this->original_rMargin, $this->tMargin);
3606  	 	 } else {
3607  	 	 	 $this->SetXY($this->original_lMargin, $this->tMargin);
3608  	 	 }
3609  	 	 $this->_outRestoreGraphicsState();
3610  	 	 $this->lasth = $lasth;
3611  	 	 $this->thead = $temp_thead;
3612  	 	 $this->theadMargins = $temp_theadMargins;
3613  	 	 $this->newline = $newline;
3614  	 	 $this->InHeader = false;
3615  	 }
3616  
3617  	 /**
3618  	  * This method is used to render the page footer.
3619  	  * @protected
3620  	  * @since 4.0.012 (2008-07-24)
3621  	  */
3622  	protected function setFooter() {
3623  	 	 if ($this->state != 2) {
3624  	 	 	 return;
3625  	 	 }
3626  	 	 $this->InFooter = true;
3627  	 	 // save current graphic settings
3628  	 	 $gvars = $this->getGraphicVars();
3629  	 	 // mark this point
3630  	 	 $this->footerpos[$this->page] = $this->pagelen[$this->page];
3631  	 	 $this->_out("\n");
3632  	 	 if ($this->print_footer) {
3633  	 	 	 $this->setGraphicVars($this->default_graphic_vars);
3634  	 	 	 $this->current_column = 0;
3635  	 	 	 $this->num_columns = 1;
3636  	 	 	 $temp_thead = $this->thead;
3637  	 	 	 $temp_theadMargins = $this->theadMargins;
3638  	 	 	 $lasth = $this->lasth;
3639  	 	 	 $this->_outSaveGraphicsState();
3640  	 	 	 $this->rMargin = $this->original_rMargin;
3641  	 	 	 $this->lMargin = $this->original_lMargin;
3642  	 	 	 $this->SetCellPadding(0);
3643  	 	 	 //set current position
3644  	 	 	 $footer_y = $this->h - $this->footer_margin;
3645  	 	 	 if ($this->rtl) {
3646  	 	 	 	 $this->SetXY($this->original_rMargin, $footer_y);
3647  	 	 	 } else {
3648  	 	 	 	 $this->SetXY($this->original_lMargin, $footer_y);
3649  	 	 	 }
3650  	 	 	 $this->SetFont($this->footer_font[0], $this->footer_font[1], $this->footer_font[2]);
3651  	 	 	 $this->Footer();
3652  	 	 	 //restore position
3653  	 	 	 if ($this->rtl) {
3654  	 	 	 	 $this->SetXY($this->original_rMargin, $this->tMargin);
3655  	 	 	 } else {
3656  	 	 	 	 $this->SetXY($this->original_lMargin, $this->tMargin);
3657  	 	 	 }
3658  	 	 	 $this->_outRestoreGraphicsState();
3659  	 	 	 $this->lasth = $lasth;
3660  	 	 	 $this->thead = $temp_thead;
3661  	 	 	 $this->theadMargins = $temp_theadMargins;
3662  	 	 }
3663  	 	 // restore graphic settings
3664  	 	 $this->setGraphicVars($gvars);
3665  	 	 $this->current_column = $gvars['current_column'];
3666  	 	 $this->num_columns = $gvars['num_columns'];
3667  	 	 // calculate footer length
3668  	 	 $this->footerlen[$this->page] = $this->pagelen[$this->page] - $this->footerpos[$this->page] + 1;
3669  	 	 $this->InFooter = false;
3670  	 }
3671  
3672  	 /**
3673  	  * Check if we are on the page body (excluding page header and footer).
3674  	  * @return true if we are not in page header nor in page footer, false otherwise.
3675  	  * @protected
3676  	  * @since 5.9.091 (2011-06-15)
3677  	  */
3678  	protected function inPageBody() {
3679  	 	 return (($this->InHeader === false) AND ($this->InFooter === false));
3680  	 }
3681  
3682  	 /**
3683  	  * This method is used to render the table header on new page (if any).
3684  	  * @protected
3685  	  * @since 4.5.030 (2009-03-25)
3686  	  */
3687  	protected function setTableHeader() {
3688  	 	 if ($this->num_columns > 1) {
3689  	 	 	 // multi column mode
3690  	 	 	 return;
3691  	 	 }
3692  	 	 if (isset($this->theadMargins['top'])) {
3693  	 	 	 // restore the original top-margin
3694  	 	 	 $this->tMargin = $this->theadMargins['top'];
3695  	 	 	 $this->pagedim[$this->page]['tm'] = $this->tMargin;
3696  	 	 	 $this->y = $this->tMargin;
3697  	 	 }
3698  	 	 if (!TCPDF_STATIC::empty_string($this->thead) AND (!$this->inthead)) {
3699  	 	 	 // set margins
3700  	 	 	 $prev_lMargin = $this->lMargin;
3701  	 	 	 $prev_rMargin = $this->rMargin;
3702  	 	 	 $prev_cell_padding = $this->cell_padding;
3703  	 	 	 $this->lMargin = $this->theadMargins['lmargin'] + ($this->pagedim[$this->page]['olm'] - $this->pagedim[$this->theadMargins['page']]['olm']);
3704  	 	 	 $this->rMargin = $this->theadMargins['rmargin'] + ($this->pagedim[$this->page]['orm'] - $this->pagedim[$this->theadMargins['page']]['orm']);
3705  	 	 	 $this->cell_padding = $this->theadMargins['cell_padding'];
3706  	 	 	 if ($this->rtl) {
3707  	 	 	 	 $this->x = $this->w - $this->rMargin;
3708  	 	 	 } else {
3709  	 	 	 	 $this->x = $this->lMargin;
3710  	 	 	 }
3711  	 	 	 // account for special "cell" mode
3712  	 	 	 if ($this->theadMargins['cell']) {
3713  	 	 	 	 if ($this->rtl) {
3714  	 	 	 	 	 $this->x -= $this->cell_padding['R'];
3715  	 	 	 	 } else {
3716  	 	 	 	 	 $this->x += $this->cell_padding['L'];
3717  	 	 	 	 }
3718  	 	 	 }
3719  	 	 	 $gvars = $this->getGraphicVars();
3720  	 	 	 if (!empty($this->theadMargins['gvars'])) {
3721  	 	 	 	 // set the correct graphic style
3722  	 	 	 	 $this->setGraphicVars($this->theadMargins['gvars']);
3723  	 	 	 	 $this->rMargin = $gvars['rMargin'];
3724  	 	 	 	 $this->lMargin = $gvars['lMargin'];
3725  	 	 	 }
3726  	 	 	 // print table header
3727  	 	 	 $this->writeHTML($this->thead, false, false, false, false, '');
3728  	 	 	 $this->setGraphicVars($gvars);
3729  	 	 	 // set new top margin to skip the table headers
3730  	 	 	 if (!isset($this->theadMargins['top'])) {
3731  	 	 	 	 $this->theadMargins['top'] = $this->tMargin;
3732  	 	 	 }
3733  	 	 	 // store end of header position
3734  	 	 	 if (!isset($this->columns[0]['th'])) {
3735  	 	 	 	 $this->columns[0]['th'] = array();
3736  	 	 	 }
3737  	 	 	 $this->columns[0]['th']['\''.$this->page.'\''] = $this->y;
3738  	 	 	 $this->tMargin = $this->y;
3739  	 	 	 $this->pagedim[$this->page]['tm'] = $this->tMargin;
3740  	 	 	 $this->lasth = 0;
3741  	 	 	 $this->lMargin = $prev_lMargin;
3742  	 	 	 $this->rMargin = $prev_rMargin;
3743  	 	 	 $this->cell_padding = $prev_cell_padding;
3744  	 	 }
3745  	 }
3746  
3747  	 /**
3748  	  * Returns the current page number.
3749  	  * @return int page number
3750  	  * @public
3751  	  * @since 1.0
3752  	  * @see getAliasNbPages()
3753  	  */
3754  	public function PageNo() {
3755  	 	 return $this->page;
3756  	 }
3757  
3758  	 /**
3759  	  * Returns the array of spot colors.
3760  	  * @return (array) Spot colors array.
3761  	  * @public
3762  	  * @since 6.0.038 (2013-09-30)
3763  	  */
3764  	public function getAllSpotColors() {
3765  	 	 return $this->spot_colors;
3766  	 }
3767  
3768  	 /**
3769  	  * Defines a new spot color.
3770  	  * It can be expressed in RGB components or gray scale.
3771  	  * The method can be called before the first page is created and the value is retained from page to page.
3772  	  * @param $name (string) Full name of the spot color.
3773  	  * @param $c (float) Cyan color for CMYK. Value between 0 and 100.
3774  	  * @param $m (float) Magenta color for CMYK. Value between 0 and 100.
3775  	  * @param $y (float) Yellow color for CMYK. Value between 0 and 100.
3776  	  * @param $k (float) Key (Black) color for CMYK. Value between 0 and 100.
3777  	  * @public
3778  	  * @since 4.0.024 (2008-09-12)
3779  	  * @see SetDrawSpotColor(), SetFillSpotColor(), SetTextSpotColor()
3780  	  */
3781  	public function AddSpotColor($name, $c, $m, $y, $k) {
3782  	 	 if (!isset($this->spot_colors[$name])) {
3783  	 	 	 $i = (1 + count($this->spot_colors));
3784  	 	 	 $this->spot_colors[$name] = array('C' => $c, 'M' => $m, 'Y' => $y, 'K' => $k, 'name' => $name, 'i' => $i);
3785  	 	 }
3786  	 }
3787  
3788  	 /**
3789  	  * Set the spot color for the specified type ('draw', 'fill', 'text').
3790  	  * @param $type (string) Type of object affected by this color: ('draw', 'fill', 'text').
3791  	  * @param $name (string) Name of the spot color.
3792  	  * @param $tint (float) Intensity of the color (from 0 to 100 ; 100 = full intensity by default).
3793  	  * @return (string) PDF color command.
3794  	  * @public
3795  	  * @since 5.9.125 (2011-10-03)
3796  	  */
3797  	public function setSpotColor($type, $name, $tint=100) {
3798  	 	 $spotcolor = TCPDF_COLORS::getSpotColor($name, $this->spot_colors);
3799  	 	 if ($spotcolor === false) {
3800  	 	 	 $this->Error('Undefined spot color: '.$name.', you must add it using the AddSpotColor() method.');
3801  	 	 }
3802  	 	 $tint = (max(0, min(100, $tint)) / 100);
3803  	 	 $pdfcolor = sprintf('/CS%d ', $this->spot_colors[$name]['i']);
3804  	 	 switch ($type) {
3805  	 	 	 case 'draw': {
3806  	 	 	 	 $pdfcolor .= sprintf('CS %F SCN', $tint);
3807  	 	 	 	 $this->DrawColor = $pdfcolor;
3808  	 	 	 	 $this->strokecolor = $spotcolor;
3809  	 	 	 	 break;
3810  	 	 	 }
3811  	 	 	 case 'fill': {
3812  	 	 	 	 $pdfcolor .= sprintf('cs %F scn', $tint);
3813  	 	 	 	 $this->FillColor = $pdfcolor;
3814  	 	 	 	 $this->bgcolor = $spotcolor;
3815  	 	 	 	 break;
3816  	 	 	 }
3817  	 	 	 case 'text': {
3818  	 	 	 	 $pdfcolor .= sprintf('cs %F scn', $tint);
3819  	 	 	 	 $this->TextColor = $pdfcolor;
3820  	 	 	 	 $this->fgcolor = $spotcolor;
3821  	 	 	 	 break;
3822  	 	 	 }
3823  	 	 }
3824  	 	 $this->ColorFlag = ($this->FillColor != $this->TextColor);
3825  	 	 if ($this->state == 2) {
3826  	 	 	 $this->_out($pdfcolor);
3827  	 	 }
3828  	 	 if ($this->inxobj) {
3829  	 	 	 // we are inside an XObject template
3830  	 	 	 $this->xobjects[$this->xobjid]['spot_colors'][$name] = $this->spot_colors[$name];
3831  	 	 }
3832  	 	 return $pdfcolor;
3833  	 }
3834  
3835  	 /**
3836  	  * Defines the spot color used for all drawing operations (lines, rectangles and cell borders).
3837  	  * @param $name (string) Name of the spot color.
3838  	  * @param $tint (float) Intensity of the color (from 0 to 100 ; 100 = full intensity by default).
3839  	  * @public
3840  	  * @since 4.0.024 (2008-09-12)
3841  	  * @see AddSpotColor(), SetFillSpotColor(), SetTextSpotColor()
3842  	  */
3843  	public function SetDrawSpotColor($name, $tint=100) {
3844  	 	 $this->setSpotColor('draw', $name, $tint);
3845  	 }
3846  
3847  	 /**
3848  	  * Defines the spot color used for all filling operations (filled rectangles and cell backgrounds).
3849  	  * @param $name (string) Name of the spot color.
3850  	  * @param $tint (float) Intensity of the color (from 0 to 100 ; 100 = full intensity by default).
3851  	  * @public
3852  	  * @since 4.0.024 (2008-09-12)
3853  	  * @see AddSpotColor(), SetDrawSpotColor(), SetTextSpotColor()
3854  	  */
3855  	public function SetFillSpotColor($name, $tint=100) {
3856  	 	 $this->setSpotColor('fill', $name, $tint);
3857  	 }
3858  
3859  	 /**
3860  	  * Defines the spot color used for text.
3861  	  * @param $name (string) Name of the spot color.
3862  	  * @param $tint (int) Intensity of the color (from 0 to 100 ; 100 = full intensity by default).
3863  	  * @public
3864  	  * @since 4.0.024 (2008-09-12)
3865  	  * @see AddSpotColor(), SetDrawSpotColor(), SetFillSpotColor()
3866  	  */
3867  	public function SetTextSpotColor($name, $tint=100) {
3868  	 	 $this->setSpotColor('text', $name, $tint);
3869  	 }
3870  
3871  	 /**
3872  	  * Set the color array for the specified type ('draw', 'fill', 'text').
3873  	  * It can be expressed in RGB, CMYK or GRAY SCALE components.
3874  	  * The method can be called before the first page is created and the value is retained from page to page.
3875  	  * @param $type (string) Type of object affected by this color: ('draw', 'fill', 'text').
3876  	  * @param $color (array) Array of colors (1=gray, 3=RGB, 4=CMYK or 5=spotcolor=CMYK+name values).
3877  	  * @param $ret (boolean) If true do not send the PDF command.
3878  	  * @return (string) The PDF command or empty string.
3879  	  * @public
3880  	  * @since 3.1.000 (2008-06-11)
3881  	  */
3882  	public function setColorArray($type, $color, $ret=false) {
3883  	 	 if (is_array($color)) {
3884  	 	 	 $color = array_values($color);
3885  	 	 	 // component: grey, RGB red or CMYK cyan
3886  	 	 	 $c = isset($color[0]) ? $color[0] : -1;
3887  	 	 	 // component: RGB green or CMYK magenta
3888  	 	 	 $m = isset($color[1]) ? $color[1] : -1;
3889  	 	 	 // component: RGB blue or CMYK yellow
3890  	 	 	 $y = isset($color[2]) ? $color[2] : -1;
3891  	 	 	 // component: CMYK black
3892  	 	 	 $k = isset($color[3]) ? $color[3] : -1;
3893  	 	 	 // color name
3894  	 	 	 $name = isset($color[4]) ? $color[4] : '';
3895  	 	 	 if ($c >= 0) {
3896  	 	 	 	 return $this->setColor($type, $c, $m, $y, $k, $ret, $name);
3897  	 	 	 }
3898  	 	 }
3899  	 	 return '';
3900  	 }
3901  
3902  	 /**
3903  	  * Defines the color used for all drawing operations (lines, rectangles and cell borders).
3904  	  * It can be expressed in RGB, CMYK or GRAY SCALE components.
3905  	  * The method can be called before the first page is created and the value is retained from page to page.
3906  	  * @param $color (array) Array of colors (1, 3 or 4 values).
3907  	  * @param $ret (boolean) If true do not send the PDF command.
3908  	  * @return string the PDF command
3909  	  * @public
3910  	  * @since 3.1.000 (2008-06-11)
3911  	  * @see SetDrawColor()
3912  	  */
3913  	public function SetDrawColorArray($color, $ret=false) {
3914  	 	 return $this->setColorArray('draw', $color, $ret);
3915  	 }
3916  
3917  	 /**
3918  	  * Defines the color used for all filling operations (filled rectangles and cell backgrounds).
3919  	  * It can be expressed in RGB, CMYK or GRAY SCALE components.
3920  	  * The method can be called before the first page is created and the value is retained from page to page.
3921  	  * @param $color (array) Array of colors (1, 3 or 4 values).
3922  	  * @param $ret (boolean) If true do not send the PDF command.
3923  	  * @public
3924  	  * @since 3.1.000 (2008-6-11)
3925  	  * @see SetFillColor()
3926  	  */
3927  	public function SetFillColorArray($color, $ret=false) {
3928  	 	 return $this->setColorArray('fill', $color, $ret);
3929  	 }
3930  
3931  	 /**
3932  	  * Defines the color used for text. It can be expressed in RGB components or gray scale.
3933  	  * The method can be called before the first page is created and the value is retained from page to page.
3934  	  * @param $color (array) Array of colors (1, 3 or 4 values).
3935  	  * @param $ret (boolean) If true do not send the PDF command.
3936  	  * @public
3937  	  * @since 3.1.000 (2008-6-11)
3938  	  * @see SetFillColor()
3939  	  */
3940  	public function SetTextColorArray($color, $ret=false) {
3941  	 	 return $this->setColorArray('text', $color, $ret);
3942  	 }
3943  
3944  	 /**
3945  	  * Defines the color used by the specified type ('draw', 'fill', 'text').
3946  	  * @param $type (string) Type of object affected by this color: ('draw', 'fill', 'text').
3947  	  * @param $col1 (float) GRAY level for single color, or Red color for RGB (0-255), or CYAN color for CMYK (0-100).
3948  	  * @param $col2 (float) GREEN color for RGB (0-255), or MAGENTA color for CMYK (0-100).
3949  	  * @param $col3 (float) BLUE color for RGB (0-255), or YELLOW color for CMYK (0-100).
3950  	  * @param $col4 (float) KEY (BLACK) color for CMYK (0-100).
3951  	  * @param $ret (boolean) If true do not send the command.
3952  	  * @param $name (string) spot color name (if any)
3953  	  * @return (string) The PDF command or empty string.
3954  	  * @public
3955  	  * @since 5.9.125 (2011-10-03)
3956  	  */
3957  	public function setColor($type, $col1=0, $col2=-1, $col3=-1, $col4=-1, $ret=false, $name='') {
3958  	 	 // set default values
3959  	 	 if (!is_numeric($col1)) {
3960  	 	 	 $col1 = 0;
3961  	 	 }
3962  	 	 if (!is_numeric($col2)) {
3963  	 	 	 $col2 = -1;
3964  	 	 }
3965  	 	 if (!is_numeric($col3)) {
3966  	 	 	 $col3 = -1;
3967  	 	 }
3968  	 	 if (!is_numeric($col4)) {
3969  	 	 	 $col4 = -1;
3970  	 	 }
3971  	 	 // set color by case
3972  	 	 $suffix = '';
3973  	 	 if (($col2 == -1) AND ($col3 == -1) AND ($col4 == -1)) {
3974  	 	 	 // Grey scale
3975  	 	 	 $col1 = max(0, min(255, $col1));
3976  	 	 	 $intcolor = array('G' => $col1);
3977  	 	 	 $pdfcolor = sprintf('%F ', ($col1 / 255));
3978  	 	 	 $suffix = 'g';
3979  	 	 } elseif ($col4 == -1) {
3980  	 	 	 // RGB
3981  	 	 	 $col1 = max(0, min(255, $col1));
3982  	 	 	 $col2 = max(0, min(255, $col2));
3983  	 	 	 $col3 = max(0, min(255, $col3));
3984  	 	 	 $intcolor = array('R' => $col1, 'G' => $col2, 'B' => $col3);
3985  	 	 	 $pdfcolor = sprintf('%F %F %F ', ($col1 / 255), ($col2 / 255), ($col3 / 255));
3986  	 	 	 $suffix = 'rg';
3987  	 	 } else {
3988  	 	 	 $col1 = max(0, min(100, $col1));
3989  	 	 	 $col2 = max(0, min(100, $col2));
3990  	 	 	 $col3 = max(0, min(100, $col3));
3991  	 	 	 $col4 = max(0, min(100, $col4));
3992  	 	 	 if (empty($name)) {
3993  	 	 	 	 // CMYK
3994  	 	 	 	 $intcolor = array('C' => $col1, 'M' => $col2, 'Y' => $col3, 'K' => $col4);
3995  	 	 	 	 $pdfcolor = sprintf('%F %F %F %F ', ($col1 / 100), ($col2 / 100), ($col3 / 100), ($col4 / 100));
3996  	 	 	 	 $suffix = 'k';
3997  	 	 	 } else {
3998  	 	 	 	 // SPOT COLOR
3999  	 	 	 	 $intcolor = array('C' => $col1, 'M' => $col2, 'Y' => $col3, 'K' => $col4, 'name' => $name);
4000  	 	 	 	 $this->AddSpotColor($name, $col1, $col2, $col3, $col4);
4001  	 	 	 	 $pdfcolor = $this->setSpotColor($type, $name, 100);
4002  	 	 	 }
4003  	 	 }
4004  	 	 switch ($type) {
4005  	 	 	 case 'draw': {
4006  	 	 	 	 $pdfcolor .= strtoupper($suffix);
4007  	 	 	 	 $this->DrawColor = $pdfcolor;
4008  	 	 	 	 $this->strokecolor = $intcolor;
4009  	 	 	 	 break;
4010  	 	 	 }
4011  	 	 	 case 'fill': {
4012  	 	 	 	 $pdfcolor .= $suffix;
4013  	 	 	 	 $this->FillColor = $pdfcolor;
4014  	 	 	 	 $this->bgcolor = $intcolor;
4015  	 	 	 	 break;
4016  	 	 	 }
4017  	 	 	 case 'text': {
4018  	 	 	 	 $pdfcolor .= $suffix;
4019  	 	 	 	 $this->TextColor = $pdfcolor;
4020  	 	 	 	 $this->fgcolor = $intcolor;
4021  	 	 	 	 break;
4022  	 	 	 }
4023  	 	 }
4024  	 	 $this->ColorFlag = ($this->FillColor != $this->TextColor);
4025  	 	 if (($type != 'text') AND ($this->state == 2)) {
4026  	 	 	 if (!$ret) {
4027  	 	 	 	 $this->_out($pdfcolor);
4028  	 	 	 }
4029  	 	 	 return $pdfcolor;
4030  	 	 }
4031  	 	 return '';
4032  	 }
4033  
4034  	 /**
4035  	  * Defines the color used for all drawing operations (lines, rectangles and cell borders). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.
4036  	  * @param $col1 (float) GRAY level for single color, or Red color for RGB (0-255), or CYAN color for CMYK (0-100).
4037  	  * @param $col2 (float) GREEN color for RGB (0-255), or MAGENTA color for CMYK (0-100).
4038  	  * @param $col3 (float) BLUE color for RGB (0-255), or YELLOW color for CMYK (0-100).
4039  	  * @param $col4 (float) KEY (BLACK) color for CMYK (0-100).
4040  	  * @param $ret (boolean) If true do not send the command.
4041  	  * @param $name (string) spot color name (if any)
4042  	  * @return string the PDF command
4043  	  * @public
4044  	  * @since 1.3
4045  	  * @see SetDrawColorArray(), SetFillColor(), SetTextColor(), Line(), Rect(), Cell(), MultiCell()
4046  	  */
4047  	public function SetDrawColor($col1=0, $col2=-1, $col3=-1, $col4=-1, $ret=false, $name='') {
4048  	 	 return $this->setColor('draw', $col1, $col2, $col3, $col4, $ret, $name);
4049  	 }
4050  
4051  	 /**
4052  	  * Defines the color used for all filling operations (filled rectangles and cell backgrounds). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.
4053  	  * @param $col1 (float) GRAY level for single color, or Red color for RGB (0-255), or CYAN color for CMYK (0-100).
4054  	  * @param $col2 (float) GREEN color for RGB (0-255), or MAGENTA color for CMYK (0-100).
4055  	  * @param $col3 (float) BLUE color for RGB (0-255), or YELLOW color for CMYK (0-100).
4056  	  * @param $col4 (float) KEY (BLACK) color for CMYK (0-100).
4057  	  * @param $ret (boolean) If true do not send the command.
4058  	  * @param $name (string) Spot color name (if any).
4059  	  * @return (string) The PDF command.
4060  	  * @public
4061  	  * @since 1.3
4062  	  * @see SetFillColorArray(), SetDrawColor(), SetTextColor(), Rect(), Cell(), MultiCell()
4063  	  */
4064  	public function SetFillColor($col1=0, $col2=-1, $col3=-1, $col4=-1, $ret=false, $name='') {
4065  	 	 return $this->setColor('fill', $col1, $col2, $col3, $col4, $ret, $name);
4066  	 }
4067  
4068  	 /**
4069  	  * Defines the color used for text. It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.
4070  	  * @param $col1 (float) GRAY level for single color, or Red color for RGB (0-255), or CYAN color for CMYK (0-100).
4071  	  * @param $col2 (float) GREEN color for RGB (0-255), or MAGENTA color for CMYK (0-100).
4072  	  * @param $col3 (float) BLUE color for RGB (0-255), or YELLOW color for CMYK (0-100).
4073  	  * @param $col4 (float) KEY (BLACK) color for CMYK (0-100).
4074  	  * @param $ret (boolean) If true do not send the command.
4075  	  * @param $name (string) Spot color name (if any).
4076  	  * @return (string) Empty string.
4077  	  * @public
4078  	  * @since 1.3
4079  	  * @see SetTextColorArray(), SetDrawColor(), SetFillColor(), Text(), Cell(), MultiCell()
4080  	  */
4081  	public function SetTextColor($col1=0, $col2=-1, $col3=-1, $col4=-1, $ret=false, $name='') {
4082  	 	 return $this->setColor('text', $col1, $col2, $col3, $col4, $ret, $name);
4083  	 }
4084  
4085  	 /**
4086  	  * Returns the length of a string in user unit. A font must be selected.<br>
4087  	  * @param $s (string) The string whose length is to be computed
4088  	  * @param $fontname (string) Family font. It can be either a name defined by AddFont() or one of the standard families. It is also possible to pass an empty string, in that case, the current family is retained.
4089  	  * @param $fontstyle (string) Font style. Possible values are (case insensitive):<ul><li>empty string: regular</li><li>B: bold</li><li>I: italic</li><li>U: underline</li><li>D: line-through</li><li>O: overline</li></ul> or any combination. The default value is regular.
4090  	  * @param $fontsize (float) Font size in points. The default value is the current size.
4091  	  * @param $getarray (boolean) if true returns an array of characters widths, if false returns the total length.
4092  	  * @return mixed int total string length or array of characted widths
4093  	  * @author Nicola Asuni
4094  	  * @public
4095  	  * @since 1.2
4096  	  */
4097  	public function GetStringWidth($s, $fontname='', $fontstyle='', $fontsize=0, $getarray=false) {
4098  	 	 return $this->GetArrStringWidth(TCPDF_FONTS::utf8Bidi(TCPDF_FONTS::UTF8StringToArray($s, $this->isunicode, $this->CurrentFont), $s, $this->tmprtl, $this->isunicode, $this->CurrentFont), $fontname, $fontstyle, $fontsize, $getarray);
4099  	 }
4100  
4101  	 /**
4102  	  * Returns the string length of an array of chars in user unit or an array of characters widths. A font must be selected.<br>
4103  	  * @param $sa (string) The array of chars whose total length is to be computed
4104  	  * @param $fontname (string) Family font. It can be either a name defined by AddFont() or one of the standard families. It is also possible to pass an empty string, in that case, the current family is retained.
4105  	  * @param $fontstyle (string) Font style. Possible values are (case insensitive):<ul><li>empty string: regular</li><li>B: bold</li><li>I: italic</li><li>U: underline</li><li>D: line through</li><li>O: overline</li></ul> or any combination. The default value is regular.
4106  	  * @param $fontsize (float) Font size in points. The default value is the current size.
4107  	  * @param $getarray (boolean) if true returns an array of characters widths, if false returns the total length.
4108  	  * @return mixed int total string length or array of characted widths
4109  	  * @author Nicola Asuni
4110  	  * @public
4111  	  * @since 2.4.000 (2008-03-06)
4112  	  */
4113  	public function GetArrStringWidth($sa, $fontname='', $fontstyle='', $fontsize=0, $getarray=false) {
4114  	 	 // store current values
4115  	 	 if (!TCPDF_STATIC::empty_string($fontname)) {
4116  	 	 	 $prev_FontFamily = $this->FontFamily;
4117  	 	 	 $prev_FontStyle = $this->FontStyle;
4118  	 	 	 $prev_FontSizePt = $this->FontSizePt;
4119  	 	 	 $this->SetFont($fontname, $fontstyle, $fontsize, '', 'default', false);
4120  	 	 }
4121  	 	 // convert UTF-8 array to Latin1 if required
4122  	 	 if ($this->isunicode AND (!$this->isUnicodeFont())) {
4123  	 	 	 $sa = TCPDF_FONTS::UTF8ArrToLatin1Arr($sa);
4124  	 	 }
4125  	 	 $w = 0; // total width
4126  	 	 $wa = array(); // array of characters widths
4127  	 	 foreach ($sa as $ck => $char) {
4128  	 	 	 // character width
4129  	 	 	 $cw = $this->GetCharWidth($char, isset($sa[($ck + 1)]));
4130  	 	 	 $wa[] = $cw;
4131  	 	 	 $w += $cw;
4132  	 	 }
4133  	 	 // restore previous values
4134  	 	 if (!TCPDF_STATIC::empty_string($fontname)) {
4135  	 	 	 $this->SetFont($prev_FontFamily, $prev_FontStyle, $prev_FontSizePt, '', 'default', false);
4136  	 	 }
4137  	 	 if ($getarray) {
4138  	 	 	 return $wa;
4139  	 	 }
4140  	 	 return $w;
4141  	 }
4142  
4143  	 /**
4144  	  * Returns the length of the char in user unit for the current font considering current stretching and spacing (tracking).
4145  	  * @param $char (int) The char code whose length is to be returned
4146  	  * @param $notlast (boolean) If false ignore the font-spacing.
4147  	  * @return float char width
4148  	  * @author Nicola Asuni
4149  	  * @public
4150  	  * @since 2.4.000 (2008-03-06)
4151  	  */
4152  	public function GetCharWidth($char, $notlast=true) {
4153  	 	 // get raw width
4154  	 	 $chw = $this->getRawCharWidth($char);
4155  	 	 if (($this->font_spacing < 0) OR (($this->font_spacing > 0) AND $notlast)) {
4156  	 	 	 // increase/decrease font spacing
4157  	 	 	 $chw += $this->font_spacing;
4158  	 	 }
4159  	 	 if ($this->font_stretching != 100) {
4160  	 	 	 // fixed stretching mode
4161  	 	 	 $chw *= ($this->font_stretching / 100);
4162  	 	 }
4163  	 	 return $chw;
4164  	 }
4165  
4166  	 /**
4167  	  * Returns the length of the char in user unit for the current font.
4168  	  * @param $char (int) The char code whose length is to be returned
4169  	  * @return float char width
4170  	  * @author Nicola Asuni
4171  	  * @public
4172  	  * @since 5.9.000 (2010-09-28)
4173  	  */
4174  	public function getRawCharWidth($char) {
4175  	 	 if ($char == 173) {
4176  	 	 	 // SHY character will not be printed
4177  	 	 	 return (0);
4178  	 	 }
4179  	 	 if (isset($this->CurrentFont['cw'][$char])) {
4180  	 	 	 $w = $this->CurrentFont['cw'][$char];
4181  	 	 } elseif (isset($this->CurrentFont['dw'])) {
4182  	 	 	 // default width
4183  	 	 	 $w = $this->CurrentFont['dw'];
4184  	 	 } elseif (isset($this->CurrentFont['cw'][32])) {
4185  	 	 	 // default width
4186  	 	 	 $w = $this->CurrentFont['cw'][32];
4187  	 	 } else {
4188  	 	 	 $w = 600;
4189  	 	 }
4190  	 	 return $this->getAbsFontMeasure($w);
4191  	 }
4192  
4193  	 /**
4194  	  * Returns the numbero of characters in a string.
4195  	  * @param $s (string) The input string.
4196  	  * @return int number of characters
4197  	  * @public
4198  	  * @since 2.0.0001 (2008-01-07)
4199  	  */
4200  	public function GetNumChars($s) {
4201  	 	 if ($this->isUnicodeFont()) {
4202  	 	 	 return count(TCPDF_FONTS::UTF8StringToArray($s, $this->isunicode, $this->CurrentFont));
4203  	 	 }
4204  	 	 return strlen($s);
4205  	 }
4206  
4207  	 /**
4208  	  * Fill the list of available fonts ($this->fontlist).
4209  	  * @protected
4210  	  * @since 4.0.013 (2008-07-28)
4211  	  */
4212  	protected function getFontsList() {
4213  	 	 if (($fontsdir = opendir(TCPDF_FONTS::_getfontpath())) !== false) {
4214  	 	 	 while (($file = readdir($fontsdir)) !== false) {
4215  	 	 	 	 if (substr($file, -4) == '.php') {
4216  	 	 	 	 	 array_push($this->fontlist, strtolower(basename($file, '.php')));
4217  	 	 	 	 }
4218  	 	 	 }
4219  	 	 	 closedir($fontsdir);
4220  	 	 }
4221  	 }
4222  
4223  	 /**
4224  	  * Imports a TrueType, Type1, core, or CID0 font and makes it available.
4225  	  * It is necessary to generate a font definition file first (read /fonts/utils/README.TXT).
4226  	  * The definition file (and the font file itself when embedding) must be present either in the current directory or in the one indicated by K_PATH_FONTS if the constant is defined. If it could not be found, the error "Could not include font definition file" is generated.
4227  	  * @param $family (string) Font family. The name can be chosen arbitrarily. If it is a standard family name, it will override the corresponding font.
4228  	  * @param $style (string) Font style. Possible values are (case insensitive):<ul><li>empty string: regular (default)</li><li>B: bold</li><li>I: italic</li><li>BI or IB: bold italic</li></ul>
4229  	  * @param $fontfile (string) The font definition file. By default, the name is built from the family and style, in lower case with no spaces.
4230  	  * @return array containing the font data, or false in case of error.
4231  	  * @param $subset (mixed) if true embedd only a subset of the font (stores only the information related to the used characters); if false embedd full font; if 'default' uses the default value set using setFontSubsetting(). This option is valid only for TrueTypeUnicode fonts. If you want to enable users to change the document, set this parameter to false. If you subset the font, the person who receives your PDF would need to have your same font in order to make changes to your PDF. The file size of the PDF would also be smaller because you are embedding only part of a font.
4232  	  * @public
4233  	  * @since 1.5
4234  	  * @see SetFont(), setFontSubsetting()
4235  	  */
4236  	public function AddFont($family, $style='', $fontfile='', $subset='default') {
4237  	 	 if ($subset === 'default') {
4238  	 	 	 $subset = $this->font_subsetting;
4239  	 	 }
4240  	 	 if ($this->pdfa_mode) {
4241  	 	 	 $subset = false;
4242  	 	 }
4243  	 	 if (TCPDF_STATIC::empty_string($family)) {
4244  	 	 	 if (!TCPDF_STATIC::empty_string($this->FontFamily)) {
4245  	 	 	 	 $family = $this->FontFamily;
4246  	 	 	 } else {
4247  	 	 	 	 $this->Error('Empty font family');
4248  	 	 	 }
4249  	 	 }
4250  	 	 // move embedded styles on $style
4251  	 	 if (substr($family, -1) == 'I') {
4252  	 	 	 $style .= 'I';
4253  	 	 	 $family = substr($family, 0, -1);
4254  	 	 }
4255  	 	 if (substr($family, -1) == 'B') {
4256  	 	 	 $style .= 'B';
4257  	 	 	 $family = substr($family, 0, -1);
4258  	 	 }
4259  	 	 // normalize family name
4260  	 	 $family = strtolower($family);
4261  	 	 if ((!$this->isunicode) AND ($family == 'arial')) {
4262  	 	 	 $family = 'helvetica';
4263  	 	 }
4264  	 	 if (($family == 'symbol') OR ($family == 'zapfdingbats')) {
4265  	 	 	 $style = '';
4266  	 	 }
4267  	 	 if ($this->pdfa_mode AND (isset($this->CoreFonts[$family]))) {
4268  	 	 	 // all fonts must be embedded
4269  	 	 	 $family = 'pdfa'.$family;
4270  	 	 }
4271  	 	 $tempstyle = strtoupper($style);
4272  	 	 $style = '';
4273  	 	 // underline
4274  	 	 if (strpos($tempstyle, 'U') !== false) {
4275  	 	 	 $this->underline = true;
4276  	 	 } else {
4277  	 	 	 $this->underline = false;
4278  	 	 }
4279  	 	 // line-through (deleted)
4280  	 	 if (strpos($tempstyle, 'D') !== false) {
4281  	 	 	 $this->linethrough = true;
4282  	 	 } else {
4283  	 	 	 $this->linethrough = false;
4284  	 	 }
4285  	 	 // overline
4286  	 	 if (strpos($tempstyle, 'O') !== false) {
4287  	 	 	 $this->overline = true;
4288  	 	 } else {
4289  	 	 	 $this->overline = false;
4290  	 	 }
4291  	 	 // bold
4292  	 	 if (strpos($tempstyle, 'B') !== false) {
4293  	 	 	 $style .= 'B';
4294  	 	 }
4295  	 	 // oblique
4296  	 	 if (strpos($tempstyle, 'I') !== false) {
4297  	 	 	 $style .= 'I';
4298  	 	 }
4299  	 	 $bistyle = $style;
4300  	 	 $fontkey = $family.$style;
4301  	 	 $font_style = $style.($this->underline ? 'U' : '').($this->linethrough ? 'D' : '').($this->overline ? 'O' : '');
4302  	 	 $fontdata = array('fontkey' => $fontkey, 'family' => $family, 'style' => $font_style);
4303  	 	 // check if the font has been already added
4304  	 	 $fb = $this->getFontBuffer($fontkey);
4305  	 	 if ($fb !== false) {
4306  	 	 	 if ($this->inxobj) {
4307  	 	 	 	 // we are inside an XObject template
4308  	 	 	 	 $this->xobjects[$this->xobjid]['fonts'][$fontkey] = $fb['i'];
4309  	 	 	 }
4310  	 	 	 return $fontdata;
4311  	 	 }
4312  	 	 // get specified font directory (if any)
4313  	 	 $fontdir = false;
4314  	 	 if (!TCPDF_STATIC::empty_string($fontfile)) {
4315  	 	 	 $fontdir = dirname($fontfile);
4316  	 	 	 if (TCPDF_STATIC::empty_string($fontdir) OR ($fontdir == '.')) {
4317  	 	 	 	 $fontdir = '';
4318  	 	 	 } else {
4319  	 	 	 	 $fontdir .= '/';
4320  	 	 	 }
4321  	 	 }
4322  	 	 // true when the font style variation is missing
4323  	 	 $missing_style = false;
4324  	 	 // search and include font file
4325  	 	 if (TCPDF_STATIC::empty_string($fontfile) OR (!@TCPDF_STATIC::file_exists($fontfile))) {
4326  	 	 	 // build a standard filenames for specified font
4327  	 	 	 $tmp_fontfile = str_replace(' ', '', $family).strtolower($style).'.php';
4328  	 	 	 $fontfile = TCPDF_FONTS::getFontFullPath($tmp_fontfile, $fontdir);
4329  	 	 	 if (TCPDF_STATIC::empty_string($fontfile)) {
4330  	 	 	 	 $missing_style = true;
4331  	 	 	 	 // try to remove the style part
4332  	 	 	 	 $tmp_fontfile = str_replace(' ', '', $family).'.php';
4333  	 	 	 	 $fontfile = TCPDF_FONTS::getFontFullPath($tmp_fontfile, $fontdir);
4334  	 	 	 }
4335  	 	 }
4336  	 	 // include font file
4337  	 	 if (!TCPDF_STATIC::empty_string($fontfile) AND (@TCPDF_STATIC::file_exists($fontfile))) {
4338  	 	 	 include($fontfile);
4339  	 	 } else {
4340  	 	 	 $this->Error('Could not include font definition file: '.$family.'');
4341  	 	 }
4342  	 	 // check font parameters
4343  	 	 if ((!isset($type)) OR (!isset($cw))) {
4344  	 	 	 $this->Error('The font definition file has a bad format: '.$fontfile.'');
4345  	 	 }
4346  	 	 // SET default parameters
4347  	 	 if (!isset($file) OR TCPDF_STATIC::empty_string($file)) {
4348  	 	 	 $file = '';
4349  	 	 }
4350  	 	 if (!isset($enc) OR TCPDF_STATIC::empty_string($enc)) {
4351  	 	 	 $enc = '';
4352  	 	 }
4353  	 	 if (!isset($cidinfo) OR TCPDF_STATIC::empty_string($cidinfo)) {
4354  	 	 	 $cidinfo = array('Registry'=>'Adobe', 'Ordering'=>'Identity', 'Supplement'=>0);
4355  	 	 	 $cidinfo['uni2cid'] = array();
4356  	 	 }
4357  	 	 if (!isset($ctg) OR TCPDF_STATIC::empty_string($ctg)) {
4358  	 	 	 $ctg = '';
4359  	 	 }
4360  	 	 if (!isset($desc) OR TCPDF_STATIC::empty_string($desc)) {
4361  	 	 	 $desc = array();
4362  	 	 }
4363  	 	 if (!isset($up) OR TCPDF_STATIC::empty_string($up)) {
4364  	 	 	 $up = -100;
4365  	 	 }
4366  	 	 if (!isset($ut) OR TCPDF_STATIC::empty_string($ut)) {
4367  	 	 	 $ut = 50;
4368  	 	 }
4369  	 	 if (!isset($cw) OR TCPDF_STATIC::empty_string($cw)) {
4370  	 	 	 $cw = array();
4371  	 	 }
4372  	 	 if (!isset($dw) OR TCPDF_STATIC::empty_string($dw)) {
4373  	 	 	 // set default width
4374  	 	 	 if (isset($desc['MissingWidth']) AND ($desc['MissingWidth'] > 0)) {
4375  	 	 	 	 $dw = $desc['MissingWidth'];
4376  	 	 	 } elseif (isset($cw[32])) {
4377  	 	 	 	 $dw = $cw[32];
4378  	 	 	 } else {
4379  	 	 	 	 $dw = 600;
4380  	 	 	 }
4381  	 	 }
4382  	 	 ++$this->numfonts;
4383  	 	 if ($type == 'core') {
4384  	 	 	 $name = $this->CoreFonts[$fontkey];
4385  	 	 	 $subset = false;
4386  	 	 } elseif (($type == 'TrueType') OR ($type == 'Type1')) {
4387  	 	 	 $subset = false;
4388  	 	 } elseif ($type == 'TrueTypeUnicode') {
4389  	 	 	 $enc = 'Identity-H';
4390  	 	 } elseif ($type == 'cidfont0') {
4391  	 	 	 if ($this->pdfa_mode) {
4392  	 	 	 	 $this->Error('All fonts must be embedded in PDF/A mode!');
4393  	 	 	 }
4394  	 	 } else {
4395  	 	 	 $this->Error('Unknow font type: '.$type.'');
4396  	 	 }
4397  	 	 // set name if unset
4398  	 	 if (!isset($name) OR empty($name)) {
4399  	 	 	 $name = $fontkey;
4400  	 	 }
4401  	 	 // create artificial font style variations if missing (only works with non-embedded fonts)
4402  	 	 if (($type != 'core') AND $missing_style) {
4403  	 	 	 // style variations
4404  	 	 	 $styles = array('' => '', 'B' => ',Bold', 'I' => ',Italic', 'BI' => ',BoldItalic');
4405  	 	 	 $name .= $styles[$bistyle];
4406  	 	 	 // artificial bold
4407  	 	 	 if (strpos($bistyle, 'B') !== false) {
4408  	 	 	 	 if (isset($desc['StemV'])) {
4409  	 	 	 	 	 // from normal to bold
4410  	 	 	 	 	 $desc['StemV'] = round($desc['StemV'] * 1.75);
4411  	 	 	 	 } else {
4412  	 	 	 	 	 // bold
4413  	 	 	 	 	 $desc['StemV'] = 123;
4414  	 	 	 	 }
4415  	 	 	 }
4416  	 	 	 // artificial italic
4417  	 	 	 if (strpos($bistyle, 'I') !== false) {
4418  	 	 	 	 if (isset($desc['ItalicAngle'])) {
4419  	 	 	 	 	 $desc['ItalicAngle'] -= 11;
4420  	 	 	 	 } else {
4421  	 	 	 	 	 $desc['ItalicAngle'] = -11;
4422  	 	 	 	 }
4423  	 	 	 	 if (isset($desc['Flags'])) {
4424  	 	 	 	 	 $desc['Flags'] |= 64; //bit 7
4425  	 	 	 	 } else {
4426  	 	 	 	 	 $desc['Flags'] = 64;
4427  	 	 	 	 }
4428  	 	 	 }
4429  	 	 }
4430  	 	 // check if the array of characters bounding boxes is defined
4431  	 	 if (!isset($cbbox)) {
4432  	 	 	 $cbbox = array();
4433  	 	 }
4434  	 	 // initialize subsetchars
4435  	 	 $subsetchars = array_fill(0, 255, true);
4436  	 	 $this->setFontBuffer($fontkey, array('fontkey' => $fontkey, 'i' => $this->numfonts, 'type' => $type, 'name' => $name, 'desc' => $desc, 'up' => $up, 'ut' => $ut, 'cw' => $cw, 'cbbox' => $cbbox, 'dw' => $dw, 'enc' => $enc, 'cidinfo' => $cidinfo, 'file' => $file, 'ctg' => $ctg, 'subset' => $subset, 'subsetchars' => $subsetchars));
4437  	 	 if ($this->inxobj) {
4438  	 	 	 // we are inside an XObject template
4439  	 	 	 $this->xobjects[$this->xobjid]['fonts'][$fontkey] = $this->numfonts;
4440  	 	 }
4441  	 	 if (isset($diff) AND (!empty($diff))) {
4442  	 	 	 //Search existing encodings
4443  	 	 	 $d = 0;
4444  	 	 	 $nb = count($this->diffs);
4445  	 	 	 for ($i=1; $i <= $nb; ++$i) {
4446  	 	 	 	 if ($this->diffs[$i] == $diff) {
4447  	 	 	 	 	 $d = $i;
4448  	 	 	 	 	 break;
4449  	 	 	 	 }
4450  	 	 	 }
4451  	 	 	 if ($d == 0) {
4452  	 	 	 	 $d = $nb + 1;
4453  	 	 	 	 $this->diffs[$d] = $diff;
4454  	 	 	 }
4455  	 	 	 $this->setFontSubBuffer($fontkey, 'diff', $d);
4456  	 	 }
4457  	 	 if (!TCPDF_STATIC::empty_string($file)) {
4458  	 	 	 if (!isset($this->FontFiles[$file])) {
4459  	 	 	 	 if ((strcasecmp($type,'TrueType') == 0) OR (strcasecmp($type, 'TrueTypeUnicode') == 0)) {
4460  	 	 	 	 	 $this->FontFiles[$file] = array('length1' => $originalsize, 'fontdir' => $fontdir, 'subset' => $subset, 'fontkeys' => array($fontkey));
4461  	 	 	 	 } elseif ($type != 'core') {
4462  	 	 	 	 	 $this->FontFiles[$file] = array('length1' => $size1, 'length2' => $size2, 'fontdir' => $fontdir, 'subset' => $subset, 'fontkeys' => array($fontkey));
4463  	 	 	 	 }
4464  	 	 	 } else {
4465  	 	 	 	 // update fontkeys that are sharing this font file
4466  	 	 	 	 $this->FontFiles[$file]['subset'] = ($this->FontFiles[$file]['subset'] AND $subset);
4467  	 	 	 	 if (!in_array($fontkey, $this->FontFiles[$file]['fontkeys'])) {
4468  	 	 	 	 	 $this->FontFiles[$file]['fontkeys'][] = $fontkey;
4469  	 	 	 	 }
4470  	 	 	 }
4471  	 	 }
4472  	 	 return $fontdata;
4473  	 }
4474  
4475  	 /**
4476  	  * Sets the font used to print character strings.
4477  	  * The font can be either a standard one or a font added via the AddFont() method. Standard fonts use Windows encoding cp1252 (Western Europe).
4478  	  * The method can be called before the first page is created and the font is retained from page to page.
4479  	  * If you just wish to change the current font size, it is simpler to call SetFontSize().
4480  	  * Note: for the standard fonts, the font metric files must be accessible. There are three possibilities for this:<ul><li>They are in the current directory (the one where the running script lies)</li><li>They are in one of the directories defined by the include_path parameter</li><li>They are in the directory defined by the K_PATH_FONTS constant</li></ul><br />
4481  	  * @param $family (string) Family font. It can be either a name defined by AddFont() or one of the standard Type1 families (case insensitive):<ul><li>times (Times-Roman)</li><li>timesb (Times-Bold)</li><li>timesi (Times-Italic)</li><li>timesbi (Times-BoldItalic)</li><li>helvetica (Helvetica)</li><li>helveticab (Helvetica-Bold)</li><li>helveticai (Helvetica-Oblique)</li><li>helveticabi (Helvetica-BoldOblique)</li><li>courier (Courier)</li><li>courierb (Courier-Bold)</li><li>courieri (Courier-Oblique)</li><li>courierbi (Courier-BoldOblique)</li><li>symbol (Symbol)</li><li>zapfdingbats (ZapfDingbats)</li></ul> It is also possible to pass an empty string. In that case, the current family is retained.
4482  	  * @param $style (string) Font style. Possible values are (case insensitive):<ul><li>empty string: regular</li><li>B: bold</li><li>I: italic</li><li>U: underline</li><li>D: line through</li><li>O: overline</li></ul> or any combination. The default value is regular. Bold and italic styles do not apply to Symbol and ZapfDingbats basic fonts or other fonts when not defined.
4483  	  * @param $size (float) Font size in points. The default value is the current size. If no size has been specified since the beginning of the document, the value taken is 12
4484  	  * @param $fontfile (string) The font definition file. By default, the name is built from the family and style, in lower case with no spaces.
4485  	  * @param $subset (mixed) if true embedd only a subset of the font (stores only the information related to the used characters); if false embedd full font; if 'default' uses the default value set using setFontSubsetting(). This option is valid only for TrueTypeUnicode fonts. If you want to enable users to change the document, set this parameter to false. If you subset the font, the person who receives your PDF would need to have your same font in order to make changes to your PDF. The file size of the PDF would also be smaller because you are embedding only part of a font.
4486  	  * @param $out (boolean) if true output the font size command, otherwise only set the font properties.
4487  	  * @author Nicola Asuni
4488  	  * @public
4489  	  * @since 1.0
4490  	  * @see AddFont(), SetFontSize()
4491  	  */
4492  	public function SetFont($family, $style='', $size=null, $fontfile='', $subset='default', $out=true) {
4493  	 	 //Select a font; size given in points
4494  	 	 if ($size === null) {
4495  	 	 	 $size = $this->FontSizePt;
4496  	 	 }
4497  	 	 if ($size < 0) {
4498  	 	 	 $size = 0;
4499  	 	 }
4500  	 	 // try to add font (if not already added)
4501  	 	 $fontdata = $this->AddFont($family, $style, $fontfile, $subset);
4502  	 	 $this->FontFamily = $fontdata['family'];
4503  	 	 $this->FontStyle = $fontdata['style'];
4504  	 	 if (isset($this->CurrentFont['fontkey']) AND isset($this->CurrentFont['subsetchars'])) {
4505  	 	 	 // save subset chars of the previous font
4506  	 	 	 $this->setFontSubBuffer($this->CurrentFont['fontkey'], 'subsetchars', $this->CurrentFont['subsetchars']);
4507  	 	 }
4508  	 	 $this->CurrentFont = $this->getFontBuffer($fontdata['fontkey']);
4509  	 	 $this->SetFontSize($size, $out);
4510  	 }
4511  
4512  	 /**
4513  	  * Defines the size of the current font.
4514  	  * @param $size (float) The font size in points.
4515  	  * @param $out (boolean) if true output the font size command, otherwise only set the font properties.
4516  	  * @public
4517  	  * @since 1.0
4518  	  * @see SetFont()
4519  	  */
4520  	public function SetFontSize($size, $out=true) {
4521  	 	 $size = (float)$size;
4522  	 	 // font size in points
4523  	 	 $this->FontSizePt = $size;
4524  	 	 // font size in user units
4525  	 	 $this->FontSize = $size / $this->k;
4526  	 	 // calculate some font metrics
4527  	 	 if (isset($this->CurrentFont['desc']['FontBBox'])) {
4528  	 	 	 $bbox = explode(' ', substr($this->CurrentFont['desc']['FontBBox'], 1, -1));
4529  	 	 	 $font_height = ((intval($bbox[3]) - intval($bbox[1])) * $size / 1000);
4530  	 	 } else {
4531  	 	 	 $font_height = $size * 1.219;
4532  	 	 }
4533  	 	 if (isset($this->CurrentFont['desc']['Ascent']) AND ($this->CurrentFont['desc']['Ascent'] > 0)) {
4534  	 	 	 $font_ascent = ($this->CurrentFont['desc']['Ascent'] * $size / 1000);
4535  	 	 }
4536  	 	 if (isset($this->CurrentFont['desc']['Descent']) AND ($this->CurrentFont['desc']['Descent'] <= 0)) {
4537  	 	 	 $font_descent = (- $this->CurrentFont['desc']['Descent'] * $size / 1000);
4538  	 	 }
4539  	 	 if (!isset($font_ascent) AND !isset($font_descent)) {
4540  	 	 	 // core font
4541  	 	 	 $font_ascent = 0.76 * $font_height;
4542  	 	 	 $font_descent = $font_height - $font_ascent;
4543  	 	 } elseif (!isset($font_descent)) {
4544  	 	 	 $font_descent = $font_height - $font_ascent;
4545  	 	 } elseif (!isset($font_ascent)) {
4546  	 	 	 $font_ascent = $font_height - $font_descent;
4547  	 	 }
4548  	 	 $this->FontAscent = ($font_ascent / $this->k);
4549  	 	 $this->FontDescent = ($font_descent / $this->k);
4550  	 	 if ($out AND ($this->page > 0) AND (isset($this->CurrentFont['i'])) AND ($this->state == 2)) {
4551  	 	 	 $this->_out(sprintf('BT /F%d %F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
4552  	 	 }
4553  	 }
4554  
4555  	 /**
4556  	  * Returns the bounding box of the current font in user units.
4557  	  * @return array
4558  	  * @public
4559  	  * @since 5.9.152 (2012-03-23)
4560  	  */
4561  	public function getFontBBox() {
4562  	 	 $fbbox = array();
4563  	 	 if (isset($this->CurrentFont['desc']['FontBBox'])) {
4564  	 	 	 $tmpbbox = explode(' ', substr($this->CurrentFont['desc']['FontBBox'], 1, -1));
4565  	 	 	 $fbbox = array_map(array($this,'getAbsFontMeasure'), $tmpbbox);
4566  	 	 } else {
4567  	 	 	 // Find max width
4568  	 	 	 if (isset($this->CurrentFont['desc']['MaxWidth'])) {
4569  	 	 	 	 $maxw = $this->getAbsFontMeasure(intval($this->CurrentFont['desc']['MaxWidth']));
4570  	 	 	 } else {
4571  	 	 	 	 $maxw = 0;
4572  	 	 	 	 if (isset($this->CurrentFont['desc']['MissingWidth'])) {
4573  	 	 	 	 	 $maxw = max($maxw, $this->CurrentFont['desc']['MissingWidth']);
4574  	 	 	 	 }
4575  	 	 	 	 if (isset($this->CurrentFont['desc']['AvgWidth'])) {
4576  	 	 	 	 	 $maxw = max($maxw, $this->CurrentFont['desc']['AvgWidth']);
4577  	 	 	 	 }
4578  	 	 	 	 if (isset($this->CurrentFont['dw'])) {
4579  	 	 	 	 	 $maxw = max($maxw, $this->CurrentFont['dw']);
4580  	 	 	 	 }
4581  	 	 	 	 foreach ($this->CurrentFont['cw'] as $char => $w) {
4582  	 	 	 	 	 $maxw = max($maxw, $w);
4583  	 	 	 	 }
4584  	 	 	 	 if ($maxw == 0) {
4585  	 	 	 	 	 $maxw = 600;
4586  	 	 	 	 }