45ea18e411bfb9cfc62fe9fc19cab31cac0dd80b
[moodle.git] / lib / tcpdf / tcpdf.php
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 //============================================================+
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  */
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');
123 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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 {
139         // Protected properties
141         /**
142          * Current page number.
143          * @protected
144          */
145         protected $page;
147         /**
148          * Current object number.
149          * @protected
150          */
151         protected $n;
153         /**
154          * Array of object offsets.
155          * @protected
156          */
157         protected $offsets = array();
159         /**
160          * Array of object IDs for each page.
161          * @protected
162          */
163         protected $pageobjects = array();
165         /**
166          * Buffer holding in-memory PDF.
167          * @protected
168          */
169         protected $buffer;
171         /**
172          * Array containing pages.
173          * @protected
174          */
175         protected $pages = array();
177         /**
178          * Current document state.
179          * @protected
180          */
181         protected $state;
183         /**
184          * Compression flag.
185          * @protected
186          */
187         protected $compress;
189         /**
190          * Current page orientation (P = Portrait, L = Landscape).
191          * @protected
192          */
193         protected $CurOrientation;
195         /**
196          * Page dimensions.
197          * @protected
198          */
199         protected $pagedim = array();
201         /**
202          * Scale factor (number of points in user unit).
203          * @protected
204          */
205         protected $k;
207         /**
208          * Width of page format in points.
209          * @protected
210          */
211         protected $fwPt;
213         /**
214          * Height of page format in points.
215          * @protected
216          */
217         protected $fhPt;
219         /**
220          * Current width of page in points.
221          * @protected
222          */
223         protected $wPt;
225         /**
226          * Current height of page in points.
227          * @protected
228          */
229         protected $hPt;
231         /**
232          * Current width of page in user unit.
233          * @protected
234          */
235         protected $w;
237         /**
238          * Current height of page in user unit.
239          * @protected
240          */
241         protected $h;
243         /**
244          * Left margin.
245          * @protected
246          */
247         protected $lMargin;
249         /**
250          * Right margin.
251          * @protected
252          */
253         protected $rMargin;
255         /**
256          * Cell left margin (used by regions).
257          * @protected
258          */
259         protected $clMargin;
261         /**
262          * Cell right margin (used by regions).
263          * @protected
264          */
265         protected $crMargin;
267         /**
268          * Top margin.
269          * @protected
270          */
271         protected $tMargin;
273         /**
274          * Page break margin.
275          * @protected
276          */
277         protected $bMargin;
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);
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);
293         /**
294          * Current horizontal position in user unit for cell positioning.
295          * @protected
296          */
297         protected $x;
299         /**
300          * Current vertical position in user unit for cell positioning.
301          * @protected
302          */
303         protected $y;
305         /**
306          * Height of last cell printed.
307          * @protected
308          */
309         protected $lasth;
311         /**
312          * Line width in user unit.
313          * @protected
314          */
315         protected $LineWidth;
317         /**
318          * Array of standard font names.
319          * @protected
320          */
321         protected $CoreFonts;
323         /**
324          * Array of used fonts.
325          * @protected
326          */
327         protected $fonts = array();
329         /**
330          * Array of font files.
331          * @protected
332          */
333         protected $FontFiles = array();
335         /**
336          * Array of encoding differences.
337          * @protected
338          */
339         protected $diffs = array();
341         /**
342          * Array of used images.
343          * @protected
344          */
345         protected $images = array();
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;
353         /**
354          * Array of Annotations in pages.
355          * @protected
356          */
357         protected $PageAnnots = array();
359         /**
360          * Array of internal links.
361          * @protected
362          */
363         protected $links = array();
365         /**
366          * Current font family.
367          * @protected
368          */
369         protected $FontFamily;
371         /**
372          * Current font style.
373          * @protected
374          */
375         protected $FontStyle;
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;
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;
391         /**
392          * Underlining flag.
393          * @protected
394          */
395         protected $underline;
397         /**
398          * Overlining flag.
399          * @protected
400          */
401         protected $overline;
403         /**
404          * Current font info.
405          * @protected
406          */
407         protected $CurrentFont;
409         /**
410          * Current font size in points.
411          * @protected
412          */
413         protected $FontSizePt;
415         /**
416          * Current font size in user unit.
417          * @protected
418          */
419         protected $FontSize;
421         /**
422          * Commands for drawing color.
423          * @protected
424          */
425         protected $DrawColor;
427         /**
428          * Commands for filling color.
429          * @protected
430          */
431         protected $FillColor;
433         /**
434          * Commands for text color.
435          * @protected
436          */
437         protected $TextColor;
439         /**
440          * Indicates whether fill and text colors are different.
441          * @protected
442          */
443         protected $ColorFlag;
445         /**
446          * Automatic page breaking.
447          * @protected
448          */
449         protected $AutoPageBreak;
451         /**
452          * Threshold used to trigger page breaks.
453          * @protected
454          */
455         protected $PageBreakTrigger;
457         /**
458          * Flag set when processing page header.
459          * @protected
460          */
461         protected $InHeader = false;
463         /**
464          * Flag set when processing page footer.
465          * @protected
466          */
467         protected $InFooter = false;
469         /**
470          * Zoom display mode.
471          * @protected
472          */
473         protected $ZoomMode;
475         /**
476          * Layout display mode.
477          * @protected
478          */
479         protected $LayoutMode;
481         /**
482          * If true set the document information dictionary in Unicode.
483          * @protected
484          */
485         protected $docinfounicode = true;
487         /**
488          * Document title.
489          * @protected
490          */
491         protected $title = '';
493         /**
494          * Document subject.
495          * @protected
496          */
497         protected $subject = '';
499         /**
500          * Document author.
501          * @protected
502          */
503         protected $author = '';
505         /**
506          * Document keywords.
507          * @protected
508          */
509         protected $keywords = '';
511         /**
512          * Document creator.
513          * @protected
514          */
515         protected $creator = '';
517         /**
518          * Starting page number.
519          * @protected
520          */
521         protected $starting_page_number = 1;
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;
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;
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;
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;
555         /**
556          * PDF version.
557          * @since 1.5.3
558          * @protected
559          */
560         protected $PDFVersion = '1.7';
562         /**
563          * ID of the stored default header template (-1 = not set).
564          * @protected
565          */
566         protected $header_xobjid = false;
568         /**
569          * If true reset the Header Xobject template at each page
570          * @protected
571          */
572         protected $header_xobj_autoreset = false;
574         /**
575          * Minimum distance between header and top page margin.
576          * @protected
577          */
578         protected $header_margin;
580         /**
581          * Minimum distance between footer and bottom page margin.
582          * @protected
583          */
584         protected $footer_margin;
586         /**
587          * Original left margin value.
588          * @protected
589          * @since 1.53.0.TC013
590          */
591         protected $original_lMargin;
593         /**
594          * Original right margin value.
595          * @protected
596          * @since 1.53.0.TC013
597          */
598         protected $original_rMargin;
600         /**
601          * Default font used on page header.
602          * @protected
603          */
604         protected $header_font;
606         /**
607          * Default font used on page footer.
608          * @protected
609          */
610         protected $footer_font;
612         /**
613          * Language templates.
614          * @protected
615          */
616         protected $l;
618         /**
619          * Barcode to print on page footer (only if set).
620          * @protected
621          */
622         protected $barcode = false;
624         /**
625          * Boolean flag to print/hide page header.
626          * @protected
627          */
628         protected $print_header = true;
630         /**
631          * Boolean flag to print/hide page footer.
632          * @protected
633          */
634         protected $print_footer = true;
636         /**
637          * Header image logo.
638          * @protected
639          */
640         protected $header_logo = '';
642         /**
643          * Width of header image logo in user units.
644          * @protected
645          */
646         protected $header_logo_width = 30;
648         /**
649          * Title to be printed on default page header.
650          * @protected
651          */
652         protected $header_title = '';
654         /**
655          * String to pring on page header after title.
656          * @protected
657          */
658         protected $header_string = '';
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);
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);
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);
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);
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');
695         /**
696          * Default number of columns for html table.
697          * @protected
698          */
699         protected $default_table_columns = 4;
701         // variables for html parser
703         /**
704          * HTML PARSER: array to store current link and rendering styles.
705          * @protected
706          */
707         protected $HREF = array();
709         /**
710          * List of available fonts on filesystem.
711          * @protected
712          */
713         protected $fontlist = array();
715         /**
716          * Current foreground color.
717          * @protected
718          */
719         protected $fgcolor;
721         /**
722          * HTML PARSER: array of boolean values, true in case of ordered list (OL), false otherwise.
723          * @protected
724          */
725         protected $listordered = array();
727         /**
728          * HTML PARSER: array count list items on nested lists.
729          * @protected
730          */
731         protected $listcount = array();
733         /**
734          * HTML PARSER: current list nesting level.
735          * @protected
736          */
737         protected $listnum = 0;
739         /**
740          * HTML PARSER: indent amount for lists.
741          * @protected
742          */
743         protected $listindent = 0;
745         /**
746          * HTML PARSER: current list indententation level.
747          * @protected
748          */
749         protected $listindentlevel = 0;
751         /**
752          * Current background color.
753          * @protected
754          */
755         protected $bgcolor;
757         /**
758          * Temporary font size in points.
759          * @protected
760          */
761         protected $tempfontsize = 10;
763         /**
764          * Spacer string for LI tags.
765          * @protected
766          */
767         protected $lispacer = '';
769         /**
770          * Default encoding.
771          * @protected
772          * @since 1.53.0.TC010
773          */
774         protected $encoding = 'UTF-8';
776         /**
777          * PHP internal encoding.
778          * @protected
779          * @since 1.53.0.TC016
780          */
781         protected $internal_encoding;
783         /**
784          * Boolean flag to indicate if the document language is Right-To-Left.
785          * @protected
786          * @since 2.0.000
787          */
788         protected $rtl = false;
790         /**
791          * Boolean flag used to force RTL or LTR string direction.
792          * @protected
793          * @since 2.0.000
794          */
795         protected $tmprtl = false;
797         // --- Variables used for document encryption:
799         /**
800          * IBoolean flag indicating whether document is protected.
801          * @protected
802          * @since 2.0.000 (2008-01-02)
803          */
804         protected $encrypted;
806         /**
807          * Array containing encryption settings.
808          * @protected
809          * @since 5.0.005 (2010-05-11)
810          */
811         protected $encryptdata = array();
813         /**
814          * Last RC4 key encrypted (cached for optimisation).
815          * @protected
816          * @since 2.0.000 (2008-01-02)
817          */
818         protected $last_enc_key;
820         /**
821          * Last RC4 computed key.
822          * @protected
823          * @since 2.0.000 (2008-01-02)
824          */
825         protected $last_enc_key_c;
827         /**
828          * File ID (used on document trailer).
829          * @protected
830          * @since 5.0.005 (2010-05-12)
831          */
832         protected $file_id;
834         // --- bookmark ---
836         /**
837          * Outlines for bookmark.
838          * @protected
839          * @since 2.1.002 (2008-02-12)
840          */
841         protected $outlines = array();
843         /**
844          * Outline root for bookmark.
845          * @protected
846          * @since 2.1.002 (2008-02-12)
847          */
848         protected $OutlineRoot;
850         // --- javascript and form ---
852         /**
853          * Javascript code.
854          * @protected
855          * @since 2.1.002 (2008-02-12)
856          */
857         protected $javascript = '';
859         /**
860          * Javascript counter.
861          * @protected
862          * @since 2.1.002 (2008-02-12)
863          */
864         protected $n_js;
866         /**
867          * line through state
868          * @protected
869          * @since 2.8.000 (2008-03-19)
870          */
871         protected $linethrough;
873         /**
874          * Array with additional document-wide usage rights for the document.
875          * @protected
876          * @since 5.8.014 (2010-08-23)
877          */
878         protected $ur = array();
880         /**
881          * DPI (Dot Per Inch) Document Resolution (do not change).
882          * @protected
883          * @since 3.0.000 (2008-03-27)
884          */
885         protected $dpi = 72;
887         /**
888          * Array of page numbers were a new page group was started (the page numbers are the keys of the array).
889          * @protected
890          * @since 3.0.000 (2008-03-27)
891          */
892         protected $newpagegroup = array();
894         /**
895          * Array that contains the number of pages in each page group.
896          * @protected
897          * @since 3.0.000 (2008-03-27)
898          */
899         protected $pagegroups = array();
901         /**
902          * Current page group number.
903          * @protected
904          * @since 3.0.000 (2008-03-27)
905          */
906         protected $currpagegroup = 0;
908         /**
909          * Array of transparency objects and parameters.
910          * @protected
911          * @since 3.0.000 (2008-03-27)
912          */
913         protected $extgstates;
915         /**
916          * Set the default JPEG compression quality (1-100).
917          * @protected
918          * @since 3.0.000 (2008-03-27)
919          */
920         protected $jpeg_quality;
922         /**
923          * Default cell height ratio.
924          * @protected
925          * @since 3.0.014 (2008-05-23)
926          */
927         protected $cell_height_ratio = K_CELL_HEIGHT_RATIO;
929         /**
930          * PDF viewer preferences.
931          * @protected
932          * @since 3.1.000 (2008-06-09)
933          */
934         protected $viewer_preferences;
936         /**
937          * A name object specifying how the document should be displayed when opened.
938          * @protected
939          * @since 3.1.000 (2008-06-09)
940          */
941         protected $PageMode;
943         /**
944          * Array for storing gradient information.
945          * @protected
946          * @since 3.1.000 (2008-06-09)
947          */
948         protected $gradients = array();
950         /**
951          * Array used to store positions inside the pages buffer (keys are the page numbers).
952          * @protected
953          * @since 3.2.000 (2008-06-26)
954          */
955         protected $intmrk = array();
957         /**
958          * Array used to store positions inside the pages buffer (keys are the page numbers).
959          * @protected
960          * @since 5.7.000 (2010-08-03)
961          */
962         protected $bordermrk = array();
964         /**
965          * Array used to store page positions to track empty pages (keys are the page numbers).
966          * @protected
967          * @since 5.8.007 (2010-08-18)
968          */
969         protected $emptypagemrk = array();
971         /**
972          * Array used to store content positions inside the pages buffer (keys are the page numbers).
973          * @protected
974          * @since 4.6.021 (2009-07-20)
975          */
976         protected $cntmrk = array();
978         /**
979          * Array used to store footer positions of each page.
980          * @protected
981          * @since 3.2.000 (2008-07-01)
982          */
983         protected $footerpos = array();
985         /**
986          * Array used to store footer length of each page.
987          * @protected
988          * @since 4.0.014 (2008-07-29)
989          */
990         protected $footerlen = array();
992         /**
993          * Boolean flag to indicate if a new line is created.
994          * @protected
995          * @since 3.2.000 (2008-07-01)
996          */
997         protected $newline = true;
999         /**
1000          * End position of the latest inserted line.
1001          * @protected
1002          * @since 3.2.000 (2008-07-01)
1003          */
1004         protected $endlinex = 0;
1006         /**
1007          * PDF string for width value of the last line.
1008          * @protected
1009          * @since 4.0.006 (2008-07-16)
1010          */
1011         protected $linestyleWidth = '';
1013         /**
1014          * PDF string for CAP value of the last line.
1015          * @protected
1016          * @since 4.0.006 (2008-07-16)
1017          */
1018         protected $linestyleCap = '0 J';
1020         /**
1021          * PDF string for join value of the last line.
1022          * @protected
1023          * @since 4.0.006 (2008-07-16)
1024          */
1025         protected $linestyleJoin = '0 j';
1027         /**
1028          * PDF string for dash value of the last line.
1029          * @protected
1030          * @since 4.0.006 (2008-07-16)
1031          */
1032         protected $linestyleDash = '[] 0 d';
1034         /**
1035          * Boolean flag to indicate if marked-content sequence is open.
1036          * @protected
1037          * @since 4.0.013 (2008-07-28)
1038          */
1039         protected $openMarkedContent = false;
1041         /**
1042          * Count the latest inserted vertical spaces on HTML.
1043          * @protected
1044          * @since 4.0.021 (2008-08-24)
1045          */
1046         protected $htmlvspace = 0;
1048         /**
1049          * Array of Spot colors.
1050          * @protected
1051          * @since 4.0.024 (2008-09-12)
1052          */
1053         protected $spot_colors = array();
1055         /**
1056          * Symbol used for HTML unordered list items.
1057          * @protected
1058          * @since 4.0.028 (2008-09-26)
1059          */
1060         protected $lisymbol = '';
1062         /**
1063          * String used to mark the beginning and end of EPS image blocks.
1064          * @protected
1065          * @since 4.1.000 (2008-10-18)
1066          */
1067         protected $epsmarker = 'x#!#EPS#!#x';
1069         /**
1070          * Array of transformation matrix.
1071          * @protected
1072          * @since 4.2.000 (2008-10-29)
1073          */
1074         protected $transfmatrix = array();
1076         /**
1077          * Current key for transformation matrix.
1078          * @protected
1079          * @since 4.8.005 (2009-09-17)
1080          */
1081         protected $transfmatrix_key = 0;
1083         /**
1084          * Booklet mode for double-sided pages.
1085          * @protected
1086          * @since 4.2.000 (2008-10-29)
1087          */
1088         protected $booklet = false;
1090         /**
1091          * Epsilon value used for float calculations.
1092          * @protected
1093          * @since 4.2.000 (2008-10-29)
1094          */
1095         protected $feps = 0.005;
1097         /**
1098          * Array used for custom vertical spaces for HTML tags.
1099          * @protected
1100          * @since 4.2.001 (2008-10-30)
1101          */
1102         protected $tagvspaces = array();
1104         /**
1105          * HTML PARSER: custom indent amount for lists. Negative value means disabled.
1106          * @protected
1107          * @since 4.2.007 (2008-11-12)
1108          */
1109         protected $customlistindent = -1;
1111         /**
1112          * Boolean flag to indicate if the border of the cell sides that cross the page should be removed.
1113          * @protected
1114          * @since 4.2.010 (2008-11-14)
1115          */
1116         protected $opencell = true;
1118         /**
1119          * Array of files to embedd.
1120          * @protected
1121          * @since 4.4.000 (2008-12-07)
1122          */
1123         protected $embeddedfiles = array();
1125         /**
1126          * Boolean flag to indicate if we are inside a PRE tag.
1127          * @protected
1128          * @since 4.4.001 (2008-12-08)
1129          */
1130         protected $premode = false;
1132         /**
1133          * Array used to store positions of graphics transformation blocks inside the page buffer.
1134          * keys are the page numbers
1135          * @protected
1136          * @since 4.4.002 (2008-12-09)
1137          */
1138         protected $transfmrk = array();
1140         /**
1141          * Default color for html links.
1142          * @protected
1143          * @since 4.4.003 (2008-12-09)
1144          */
1145         protected $htmlLinkColorArray = array(0, 0, 255);
1147         /**
1148          * Default font style to add to html links.
1149          * @protected
1150          * @since 4.4.003 (2008-12-09)
1151          */
1152         protected $htmlLinkFontStyle = 'U';
1154         /**
1155          * Counts the number of pages.
1156          * @protected
1157          * @since 4.5.000 (2008-12-31)
1158          */
1159         protected $numpages = 0;
1161         /**
1162          * Array containing page lengths in bytes.
1163          * @protected
1164          * @since 4.5.000 (2008-12-31)
1165          */
1166         protected $pagelen = array();
1168         /**
1169          * Counts the number of pages.
1170          * @protected
1171          * @since 4.5.000 (2008-12-31)
1172          */
1173         protected $numimages = 0;
1175         /**
1176          * Store the image keys.
1177          * @protected
1178          * @since 4.5.000 (2008-12-31)
1179          */
1180         protected $imagekeys = array();
1182         /**
1183          * Length of the buffer in bytes.
1184          * @protected
1185          * @since 4.5.000 (2008-12-31)
1186          */
1187         protected $bufferlen = 0;
1189         /**
1190          * Counts the number of fonts.
1191          * @protected
1192          * @since 4.5.000 (2009-01-02)
1193          */
1194         protected $numfonts = 0;
1196         /**
1197          * Store the font keys.
1198          * @protected
1199          * @since 4.5.000 (2009-01-02)
1200          */
1201         protected $fontkeys = array();
1203         /**
1204          * Store the font object IDs.
1205          * @protected
1206          * @since 4.8.001 (2009-09-09)
1207          */
1208         protected $font_obj_ids = array();
1210         /**
1211          * Store the fage status (true when opened, false when closed).
1212          * @protected
1213          * @since 4.5.000 (2009-01-02)
1214          */
1215         protected $pageopen = array();
1217         /**
1218          * Default monospace font.
1219          * @protected
1220          * @since 4.5.025 (2009-03-10)
1221          */
1222         protected $default_monospaced_font = 'courier';
1224         /**
1225          * Cloned copy of the current class object.
1226          * @protected
1227          * @since 4.5.029 (2009-03-19)
1228          */
1229         protected $objcopy;
1231         /**
1232          * Array used to store the lengths of cache files.
1233          * @protected
1234          * @since 4.5.029 (2009-03-19)
1235          */
1236         protected $cache_file_length = array();
1238         /**
1239          * Table header content to be repeated on each new page.
1240          * @protected
1241          * @since 4.5.030 (2009-03-20)
1242          */
1243         protected $thead = '';
1245         /**
1246          * Margins used for table header.
1247          * @protected
1248          * @since 4.5.030 (2009-03-20)
1249          */
1250         protected $theadMargins = array();
1252         /**
1253          * Boolean flag to enable document digital signature.
1254          * @protected
1255          * @since 4.6.005 (2009-04-24)
1256          */
1257         protected $sign = false;
1259         /**
1260          * Digital signature data.
1261          * @protected
1262          * @since 4.6.005 (2009-04-24)
1263          */
1264         protected $signature_data = array();
1266         /**
1267          * Digital signature max length.
1268          * @protected
1269          * @since 4.6.005 (2009-04-24)
1270          */
1271         protected $signature_max_length = 11742;
1273         /**
1274          * Data for digital signature appearance.
1275          * @protected
1276          * @since 5.3.011 (2010-06-16)
1277          */
1278         protected $signature_appearance = array('page' => 1, 'rect' => '0 0 0 0');
1280         /**
1281          * Array of empty digital signature appearances.
1282          * @protected
1283          * @since 5.9.101 (2011-07-06)
1284          */
1285         protected $empty_signature_appearance = array();
1287         /**
1288          * Boolean flag to enable document timestamping with TSA.
1289          * @protected
1290          * @since 6.0.085 (2014-06-19)
1291          */
1292         protected $tsa_timestamp = false;
1294         /**
1295          * Timestamping data.
1296          * @protected
1297          * @since 6.0.085 (2014-06-19)
1298          */
1299         protected $tsa_data = array();
1301         /**
1302          * Regular expression used to find blank characters (required for word-wrapping).
1303          * @protected
1304          * @since 4.6.006 (2009-04-28)
1305          */
1306         protected $re_spaces = '/[^\S\xa0]/';
1308         /**
1309          * Array of $re_spaces parts.
1310          * @protected
1311          * @since 5.5.011 (2010-07-09)
1312          */
1313         protected $re_space = array('p' => '[^\S\xa0]', 'm' => '');
1315         /**
1316          * Digital signature object ID.
1317          * @protected
1318          * @since 4.6.022 (2009-06-23)
1319          */
1320         protected $sig_obj_id = 0;
1322         /**
1323          * ID of page objects.
1324          * @protected
1325          * @since 4.7.000 (2009-08-29)
1326          */
1327         protected $page_obj_id = array();
1329         /**
1330          * List of form annotations IDs.
1331          * @protected
1332          * @since 4.8.000 (2009-09-07)
1333          */
1334         protected $form_obj_id = array();
1336         /**
1337          * 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.
1338          * @protected
1339          * @since 4.8.000 (2009-09-07)
1340          */
1341         protected $default_form_prop = array('lineWidth'=>1, 'borderStyle'=>'solid', 'fillColor'=>array(255, 255, 255), 'strokeColor'=>array(128, 128, 128));
1343         /**
1344          * Javascript objects array.
1345          * @protected
1346          * @since 4.8.000 (2009-09-07)
1347          */
1348         protected $js_objects = array();
1350         /**
1351          * Current form action (used during XHTML rendering).
1352          * @protected
1353          * @since 4.8.000 (2009-09-07)
1354          */
1355         protected $form_action = '';
1357         /**
1358          * Current form encryption type (used during XHTML rendering).
1359          * @protected
1360          * @since 4.8.000 (2009-09-07)
1361          */
1362         protected $form_enctype = 'application/x-www-form-urlencoded';
1364         /**
1365          * Current method to submit forms.
1366          * @protected
1367          * @since 4.8.000 (2009-09-07)
1368          */
1369         protected $form_mode = 'post';
1371         /**
1372          * List of fonts used on form fields (fontname => fontkey).
1373          * @protected
1374          * @since 4.8.001 (2009-09-09)
1375          */
1376         protected $annotation_fonts = array();
1378         /**
1379          * List of radio buttons parent objects.
1380          * @protected
1381          * @since 4.8.001 (2009-09-09)
1382          */
1383         protected $radiobutton_groups = array();
1385         /**
1386          * List of radio group objects IDs.
1387          * @protected
1388          * @since 4.8.001 (2009-09-09)
1389          */
1390         protected $radio_groups = array();
1392         /**
1393          * Text indentation value (used for text-indent CSS attribute).
1394          * @protected
1395          * @since 4.8.006 (2009-09-23)
1396          */
1397         protected $textindent = 0;
1399         /**
1400          * Store page number when startTransaction() is called.
1401          * @protected
1402          * @since 4.8.006 (2009-09-23)
1403          */
1404         protected $start_transaction_page = 0;
1406         /**
1407          * Store Y position when startTransaction() is called.
1408          * @protected
1409          * @since 4.9.001 (2010-03-28)
1410          */
1411         protected $start_transaction_y = 0;
1413         /**
1414          * True when we are printing the thead section on a new page.
1415          * @protected
1416          * @since 4.8.027 (2010-01-25)
1417          */
1418         protected $inthead = false;
1420         /**
1421          * Array of column measures (width, space, starting Y position).
1422          * @protected
1423          * @since 4.9.001 (2010-03-28)
1424          */
1425         protected $columns = array();
1427         /**
1428          * Number of colums.
1429          * @protected
1430          * @since 4.9.001 (2010-03-28)
1431          */
1432         protected $num_columns = 1;
1434         /**
1435          * Current column number.
1436          * @protected
1437          * @since 4.9.001 (2010-03-28)
1438          */
1439         protected $current_column = 0;
1441         /**
1442          * Starting page for columns.
1443          * @protected
1444          * @since 4.9.001 (2010-03-28)
1445          */
1446         protected $column_start_page = 0;
1448         /**
1449          * Maximum page and column selected.
1450          * @protected
1451          * @since 5.8.000 (2010-08-11)
1452          */
1453         protected $maxselcol = array('page' => 0, 'column' => 0);
1455         /**
1456          * Array of: X difference between table cell x start and starting page margin, cellspacing, cellpadding.
1457          * @protected
1458          * @since 5.8.000 (2010-08-11)
1459          */
1460         protected $colxshift = array('x' => 0, 's' => array('H' => 0, 'V' => 0), 'p' => array('L' => 0, 'T' => 0, 'R' => 0, 'B' => 0));
1462         /**
1463          * 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.
1464          * @protected
1465          * @since 4.9.008 (2010-04-03)
1466          */
1467         protected $textrendermode = 0;
1469         /**
1470          * Text stroke width in doc units.
1471          * @protected
1472          * @since 4.9.008 (2010-04-03)
1473          */
1474         protected $textstrokewidth = 0;
1476         /**
1477          * Current stroke color.
1478          * @protected
1479          * @since 4.9.008 (2010-04-03)
1480          */
1481         protected $strokecolor;
1483         /**
1484          * Default unit of measure for document.
1485          * @protected
1486          * @since 5.0.000 (2010-04-22)
1487          */
1488         protected $pdfunit = 'mm';
1490         /**
1491          * Boolean flag true when we are on TOC (Table Of Content) page.
1492          * @protected
1493          */
1494         protected $tocpage = false;
1496         /**
1497          * Boolean flag: if true convert vector images (SVG, EPS) to raster image using GD or ImageMagick library.
1498          * @protected
1499          * @since 5.0.000 (2010-04-26)
1500          */
1501         protected $rasterize_vector_images = false;
1503         /**
1504          * Boolean flag: if true enables font subsetting by default.
1505          * @protected
1506          * @since 5.3.002 (2010-06-07)
1507          */
1508         protected $font_subsetting = true;
1510         /**
1511          * Array of default graphic settings.
1512          * @protected
1513          * @since 5.5.008 (2010-07-02)
1514          */
1515         protected $default_graphic_vars = array();
1517         /**
1518          * Array of XObjects.
1519          * @protected
1520          * @since 5.8.014 (2010-08-23)
1521          */
1522         protected $xobjects = array();
1524         /**
1525          * Boolean value true when we are inside an XObject.
1526          * @protected
1527          * @since 5.8.017 (2010-08-24)
1528          */
1529         protected $inxobj = false;
1531         /**
1532          * Current XObject ID.
1533          * @protected
1534          * @since 5.8.017 (2010-08-24)
1535          */
1536         protected $xobjid = '';
1538         /**
1539          * Percentage of character stretching.
1540          * @protected
1541          * @since 5.9.000 (2010-09-29)
1542          */
1543         protected $font_stretching = 100;
1545         /**
1546          * Increases or decreases the space between characters in a text by the specified amount (tracking).
1547          * @protected
1548          * @since 5.9.000 (2010-09-29)
1549          */
1550         protected $font_spacing = 0;
1552         /**
1553          * Array of no-write regions.
1554          * ('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)
1555          * @protected
1556          * @since 5.9.003 (2010-10-14)
1557          */
1558         protected $page_regions = array();
1560         /**
1561          * Boolean value true when page region check is active.
1562          * @protected
1563          */
1564         protected $check_page_regions = true;
1566         /**
1567          * Array of PDF layers data.
1568          * @protected
1569          * @since 5.9.102 (2011-07-13)
1570          */
1571         protected $pdflayers = array();
1573         /**
1574          * A dictionary of names and corresponding destinations (Dests key on document Catalog).
1575          * @protected
1576          * @since 5.9.097 (2011-06-23)
1577          */
1578         protected $dests = array();
1580         /**
1581          * Object ID for Named Destinations
1582          * @protected
1583          * @since 5.9.097 (2011-06-23)
1584          */
1585         protected $n_dests;
1587         /**
1588          * Embedded Files Names
1589          * @protected
1590          * @since 5.9.204 (2013-01-23)
1591          */
1592         protected $efnames = array();
1594         /**
1595          * Directory used for the last SVG image.
1596          * @protected
1597          * @since 5.0.000 (2010-05-05)
1598          */
1599         protected $svgdir = '';
1601         /**
1602          *  Deafult unit of measure for SVG.
1603          * @protected
1604          * @since 5.0.000 (2010-05-02)
1605          */
1606         protected $svgunit = 'px';
1608         /**
1609          * Array of SVG gradients.
1610          * @protected
1611          * @since 5.0.000 (2010-05-02)
1612          */
1613         protected $svggradients = array();
1615         /**
1616          * ID of last SVG gradient.
1617          * @protected
1618          * @since 5.0.000 (2010-05-02)
1619          */
1620         protected $svggradientid = 0;
1622         /**
1623          * Boolean value true when in SVG defs group.
1624          * @protected
1625          * @since 5.0.000 (2010-05-02)
1626          */
1627         protected $svgdefsmode = false;
1629         /**
1630          * Array of SVG defs.
1631          * @protected
1632          * @since 5.0.000 (2010-05-02)
1633          */
1634         protected $svgdefs = array();
1636         /**
1637          * Boolean value true when in SVG clipPath tag.
1638          * @protected
1639          * @since 5.0.000 (2010-04-26)
1640          */
1641         protected $svgclipmode = false;
1643         /**
1644          * Array of SVG clipPath commands.
1645          * @protected
1646          * @since 5.0.000 (2010-05-02)
1647          */
1648         protected $svgclippaths = array();
1650         /**
1651          * Array of SVG clipPath tranformation matrix.
1652          * @protected
1653          * @since 5.8.022 (2010-08-31)
1654          */
1655         protected $svgcliptm = array();
1657         /**
1658          * ID of last SVG clipPath.
1659          * @protected
1660          * @since 5.0.000 (2010-05-02)
1661          */
1662         protected $svgclipid = 0;
1664         /**
1665          * SVG text.
1666          * @protected
1667          * @since 5.0.000 (2010-05-02)
1668          */
1669         protected $svgtext = '';
1671         /**
1672          * SVG text properties.
1673          * @protected
1674          * @since 5.8.013 (2010-08-23)
1675          */
1676         protected $svgtextmode = array();
1678         /**
1679          * Array of SVG properties.
1680          * @protected
1681          * @since 5.0.000 (2010-05-02)
1682          */
1683         protected $svgstyles = array(array(
1684                 'alignment-baseline' => 'auto',
1685                 'baseline-shift' => 'baseline',
1686                 'clip' => 'auto',
1687                 'clip-path' => 'none',
1688                 'clip-rule' => 'nonzero',
1689                 'color' => 'black',
1690                 'color-interpolation' => 'sRGB',
1691                 'color-interpolation-filters' => 'linearRGB',
1692                 'color-profile' => 'auto',
1693                 'color-rendering' => 'auto',
1694                 'cursor' => 'auto',
1695                 'direction' => 'ltr',
1696                 'display' => 'inline',
1697                 'dominant-baseline' => 'auto',
1698                 'enable-background' => 'accumulate',
1699                 'fill' => 'black',
1700                 'fill-opacity' => 1,
1701                 'fill-rule' => 'nonzero',
1702                 'filter' => 'none',
1703                 'flood-color' => 'black',
1704                 'flood-opacity' => 1,
1705                 'font' => '',
1706                 'font-family' => 'helvetica',
1707                 'font-size' => 'medium',
1708                 'font-size-adjust' => 'none',
1709                 'font-stretch' => 'normal',
1710                 'font-style' => 'normal',
1711                 'font-variant' => 'normal',
1712                 'font-weight' => 'normal',
1713                 'glyph-orientation-horizontal' => '0deg',
1714                 'glyph-orientation-vertical' => 'auto',
1715                 'image-rendering' => 'auto',
1716                 'kerning' => 'auto',
1717                 'letter-spacing' => 'normal',
1718                 'lighting-color' => 'white',
1719                 'marker' => '',
1720                 'marker-end' => 'none',
1721                 'marker-mid' => 'none',
1722                 'marker-start' => 'none',
1723                 'mask' => 'none',
1724                 'opacity' => 1,
1725                 'overflow' => 'auto',
1726                 'pointer-events' => 'visiblePainted',
1727                 'shape-rendering' => 'auto',
1728                 'stop-color' => 'black',
1729                 'stop-opacity' => 1,
1730                 'stroke' => 'none',
1731                 'stroke-dasharray' => 'none',
1732                 'stroke-dashoffset' => 0,
1733                 'stroke-linecap' => 'butt',
1734                 'stroke-linejoin' => 'miter',
1735                 'stroke-miterlimit' => 4,
1736                 'stroke-opacity' => 1,
1737                 'stroke-width' => 1,
1738                 'text-anchor' => 'start',
1739                 'text-decoration' => 'none',
1740                 'text-rendering' => 'auto',
1741                 'unicode-bidi' => 'normal',
1742                 'visibility' => 'visible',
1743                 'word-spacing' => 'normal',
1744                 'writing-mode' => 'lr-tb',
1745                 'text-color' => 'black',
1746                 'transfmatrix' => array(1, 0, 0, 1, 0, 0)
1747                 ));
1749         /**
1750          * If true force sRGB color profile for all document.
1751          * @protected
1752          * @since 5.9.121 (2011-09-28)
1753          */
1754         protected $force_srgb = false;
1756         /**
1757          * If true set the document to PDF/A mode.
1758          * @protected
1759          * @since 5.9.121 (2011-09-27)
1760          */
1761         protected $pdfa_mode = false;
1763         /**
1764          * version of PDF/A mode (1 - 3).
1765          * @protected
1766          * @since 6.2.26 (2019-03-12)
1767          */
1768         protected $pdfa_version = 1;
1770         /**
1771          * Document creation date-time
1772          * @protected
1773          * @since 5.9.152 (2012-03-22)
1774          */
1775         protected $doc_creation_timestamp;
1777         /**
1778          * Document modification date-time
1779          * @protected
1780          * @since 5.9.152 (2012-03-22)
1781          */
1782         protected $doc_modification_timestamp;
1784         /**
1785          * Custom XMP data.
1786          * @protected
1787          * @since 5.9.128 (2011-10-06)
1788          */
1789         protected $custom_xmp = '';
1791         /**
1792          * Custom XMP RDF data.
1793          * @protected
1794          * @since 6.3.0 (2019-09-19)
1795          */
1796         protected $custom_xmp_rdf = '';
1798         /**
1799          * Overprint mode array.
1800          * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008).
1801          * @protected
1802          * @since 5.9.152 (2012-03-23)
1803          */
1804         protected $overprint = array('OP' => false, 'op' => false, 'OPM' => 0);
1806         /**
1807          * Alpha mode array.
1808          * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008).
1809          * @protected
1810          * @since 5.9.152 (2012-03-23)
1811          */
1812         protected $alpha = array('CA' => 1, 'ca' => 1, 'BM' => '/Normal', 'AIS' => false);
1814         /**
1815          * Define the page boundaries boxes to be set on document.
1816          * @protected
1817          * @since 5.9.152 (2012-03-23)
1818          */
1819         protected $page_boxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox');
1821         /**
1822          * If true print TCPDF meta link.
1823          * @protected
1824          * @since 5.9.152 (2012-03-23)
1825          */
1826         protected $tcpdflink = true;
1828         /**
1829          * Cache array for computed GD gamma values.
1830          * @protected
1831          * @since 5.9.1632 (2012-06-05)
1832          */
1833         protected $gdgammacache = array();
1835         //------------------------------------------------------------
1836         // METHODS
1837         //------------------------------------------------------------
1839         /**
1840          * This is the class constructor.
1841          * It allows to set up the page format, the orientation and the measure unit used in all the methods (except for the font sizes).
1842          *
1843          * IMPORTANT: Please note that this method sets the mb_internal_encoding to ASCII, so if you are using the mbstring module functions with TCPDF you need to correctly set/unset the mb_internal_encoding when needed.
1844          *
1845          * @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>
1846          * @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.
1847          * @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().
1848          * @param $unicode (boolean) TRUE means that the input text is unicode (default = true)
1849          * @param $encoding (string) Charset encoding (used only when converting back html entities); default is UTF-8.
1850          * @param $diskcache (boolean) DEPRECATED FEATURE
1851          * @param $pdfa (integer) If not false, set the document to PDF/A mode and the good version (1 or 3).
1852          * @public
1853          * @see getPageSizeFromFormat(), setPageFormat()
1854          */
1855         public function __construct($orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding='UTF-8', $diskcache=false, $pdfa=false) {
1856                 /* Set internal character encoding to ASCII */
1857                 if (function_exists('mb_internal_encoding') AND mb_internal_encoding()) {
1858                         $this->internal_encoding = mb_internal_encoding();
1859                         mb_internal_encoding('ASCII');
1860                 }
1861                 // set file ID for trailer
1862                 $serformat = (is_array($format) ? json_encode($format) : $format);
1863                 $this->file_id = md5(TCPDF_STATIC::getRandomSeed('TCPDF'.$orientation.$unit.$serformat.$encoding));
1864                 $this->font_obj_ids = array();
1865                 $this->page_obj_id = array();
1866                 $this->form_obj_id = array();
1868                 // set pdf/a mode
1869                 if ($pdfa != false) {
1870                         $this->pdfa_mode = true;
1871                         $this->pdfa_version = $pdfa;  // 1 or 3
1872                 } else
1873                         $this->pdfa_mode = false;
1875                 $this->force_srgb = false;
1876                 // set language direction
1877                 $this->rtl = false;
1878                 $this->tmprtl = false;
1879                 // some checks
1880                 $this->_dochecks();
1881                 // initialization of properties
1882                 $this->isunicode = $unicode;
1883                 $this->page = 0;
1884                 $this->transfmrk[0] = array();
1885                 $this->pagedim = array();
1886                 $this->n = 2;
1887                 $this->buffer = '';
1888                 $this->pages = array();
1889                 $this->state = 0;
1890                 $this->fonts = array();
1891                 $this->FontFiles = array();
1892                 $this->diffs = array();
1893                 $this->images = array();
1894                 $this->links = array();
1895                 $this->gradients = array();
1896                 $this->InFooter = false;
1897                 $this->lasth = 0;
1898                 $this->FontFamily = defined('PDF_FONT_NAME_MAIN')?PDF_FONT_NAME_MAIN:'helvetica';
1899                 $this->FontStyle = '';
1900                 $this->FontSizePt = 12;
1901                 $this->underline = false;
1902                 $this->overline = false;
1903                 $this->linethrough = false;
1904                 $this->DrawColor = '0 G';
1905                 $this->FillColor = '0 g';
1906                 $this->TextColor = '0 g';
1907                 $this->ColorFlag = false;
1908                 $this->pdflayers = array();
1909                 // encryption values
1910                 $this->encrypted = false;
1911                 $this->last_enc_key = '';
1912                 // standard Unicode fonts
1913                 $this->CoreFonts = array(
1914                         'courier'=>'Courier',
1915                         'courierB'=>'Courier-Bold',
1916                         'courierI'=>'Courier-Oblique',
1917                         'courierBI'=>'Courier-BoldOblique',
1918                         'helvetica'=>'Helvetica',
1919                         'helveticaB'=>'Helvetica-Bold',
1920                         'helveticaI'=>'Helvetica-Oblique',
1921                         'helveticaBI'=>'Helvetica-BoldOblique',
1922                         'times'=>'Times-Roman',
1923                         'timesB'=>'Times-Bold',
1924                         'timesI'=>'Times-Italic',
1925                         'timesBI'=>'Times-BoldItalic',
1926                         'symbol'=>'Symbol',
1927                         'zapfdingbats'=>'ZapfDingbats'
1928                 );
1929                 // set scale factor
1930                 $this->setPageUnit($unit);
1931                 // set page format and orientation
1932                 $this->setPageFormat($format, $orientation);
1933                 // page margins (1 cm)
1934                 $margin = 28.35 / $this->k;
1935                 $this->SetMargins($margin, $margin);
1936                 $this->clMargin = $this->lMargin;
1937                 $this->crMargin = $this->rMargin;
1938                 // internal cell padding
1939                 $cpadding = $margin / 10;
1940                 $this->setCellPaddings($cpadding, 0, $cpadding, 0);
1941                 // cell margins
1942                 $this->setCellMargins(0, 0, 0, 0);
1943                 // line width (0.2 mm)
1944                 $this->LineWidth = 0.57 / $this->k;
1945                 $this->linestyleWidth = sprintf('%F w', ($this->LineWidth * $this->k));
1946                 $this->linestyleCap = '0 J';
1947                 $this->linestyleJoin = '0 j';
1948                 $this->linestyleDash = '[] 0 d';
1949                 // automatic page break
1950                 $this->SetAutoPageBreak(true, (2 * $margin));
1951                 // full width display mode
1952                 $this->SetDisplayMode('fullwidth');
1953                 // compression
1954                 $this->SetCompression();
1955                 // set default PDF version number
1956                 $this->setPDFVersion();
1957                 $this->tcpdflink = true;
1958                 $this->encoding = $encoding;
1959                 $this->HREF = array();
1960                 $this->getFontsList();
1961                 $this->fgcolor = array('R' => 0, 'G' => 0, 'B' => 0);
1962                 $this->strokecolor = array('R' => 0, 'G' => 0, 'B' => 0);
1963                 $this->bgcolor = array('R' => 255, 'G' => 255, 'B' => 255);
1964                 $this->extgstates = array();
1965                 $this->setTextShadow();
1966                 // signature
1967                 $this->sign = false;
1968                 $this->tsa_timestamp = false;
1969                 $this->tsa_data = array();
1970                 $this->signature_appearance = array('page' => 1, 'rect' => '0 0 0 0', 'name' => 'Signature');
1971                 $this->empty_signature_appearance = array();
1972                 // user's rights
1973                 $this->ur['enabled'] = false;
1974                 $this->ur['document'] = '/FullSave';
1975                 $this->ur['annots'] = '/Create/Delete/Modify/Copy/Import/Export';
1976                 $this->ur['form'] = '/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate';
1977                 $this->ur['signature'] = '/Modify';
1978                 $this->ur['ef'] = '/Create/Delete/Modify/Import';
1979                 $this->ur['formex'] = '';
1980                 // set default JPEG quality
1981                 $this->jpeg_quality = 75;
1982                 // initialize some settings
1983                 TCPDF_FONTS::utf8Bidi(array(), '', false, $this->isunicode, $this->CurrentFont);
1984                 // set default font
1985                 $this->SetFont($this->FontFamily, $this->FontStyle, $this->FontSizePt);
1986                 $this->setHeaderFont(array($this->FontFamily, $this->FontStyle, $this->FontSizePt));
1987                 $this->setFooterFont(array($this->FontFamily, $this->FontStyle, $this->FontSizePt));
1988                 // check if PCRE Unicode support is enabled
1989                 if ($this->isunicode AND (@preg_match('/\pL/u', 'a') == 1)) {
1990                         // PCRE unicode support is turned ON
1991                         // \s     : any whitespace character
1992                         // \p{Z}  : any separator
1993                         // \p{Lo} : Unicode letter or ideograph that does not have lowercase and uppercase variants. Is used to chunk chinese words.
1994                         // \xa0   : Unicode Character 'NO-BREAK SPACE' (U+00A0)
1995                         //$this->setSpacesRE('/(?!\xa0)[\s\p{Z}\p{Lo}]/u');
1996                         $this->setSpacesRE('/(?!\xa0)[\s\p{Z}]/u');
1997                 } else {
1998                         // PCRE unicode support is turned OFF
1999                         $this->setSpacesRE('/[^\S\xa0]/');
2000                 }
2001                 $this->default_form_prop = array('lineWidth'=>1, 'borderStyle'=>'solid', 'fillColor'=>array(255, 255, 255), 'strokeColor'=>array(128, 128, 128));
2002                 // set document creation and modification timestamp
2003                 $this->doc_creation_timestamp = time();
2004                 $this->doc_modification_timestamp = $this->doc_creation_timestamp;
2005                 // get default graphic vars
2006                 $this->default_graphic_vars = $this->getGraphicVars();
2007                 $this->header_xobj_autoreset = false;
2008                 $this->custom_xmp = '';
2009                 $this->custom_xmp_rdf = '';
2010                 // Call cleanup method after script execution finishes or exit() is called.
2011                 // NOTE: This will not be executed if the process is killed with a SIGTERM or SIGKILL signal.
2012                 register_shutdown_function(array($this, '_destroy'), true);
2013         }
2015         /**
2016          * Default destructor.
2017          * @public
2018          * @since 1.53.0.TC016
2019          */
2020         public function __destruct() {
2021                 // cleanup
2022                 $this->_destroy(true);
2023         }
2025         /**
2026          * Set the units of measure for the document.
2027          * @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.
2028          * @public
2029          * @since 3.0.015 (2008-06-06)
2030          */
2031         public function setPageUnit($unit) {
2032                 $unit = strtolower($unit);
2033                 //Set scale factor
2034                 switch ($unit) {
2035                         // points
2036                         case 'px':
2037                         case 'pt': {
2038                                 $this->k = 1;
2039                                 break;
2040                         }
2041                         // millimeters
2042                         case 'mm': {
2043                                 $this->k = $this->dpi / 25.4;
2044                                 break;
2045                         }
2046                         // centimeters
2047                         case 'cm': {
2048                                 $this->k = $this->dpi / 2.54;
2049                                 break;
2050                         }
2051                         // inches
2052                         case 'in': {
2053                                 $this->k = $this->dpi;
2054                                 break;
2055                         }
2056                         // unsupported unit
2057                         default : {
2058                                 $this->Error('Incorrect unit: '.$unit);
2059                                 break;
2060                         }
2061                 }
2062                 $this->pdfunit = $unit;
2063                 if (isset($this->CurOrientation)) {
2064                         $this->setPageOrientation($this->CurOrientation);
2065                 }
2066         }
2068         /**
2069          * Change the format of the current page
2070          * @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>
2071          * <li>['format'] = page format name (one of the above);</li>
2072          * <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>
2073          * <li>['PZ'] : The page's preferred zoom (magnification) factor.</li>
2074          * <li>['MediaBox'] : the boundaries of the physical medium on which the page shall be displayed or printed:</li>
2075          * <li>['MediaBox']['llx'] : lower-left x coordinate</li>
2076          * <li>['MediaBox']['lly'] : lower-left y coordinate</li>
2077          * <li>['MediaBox']['urx'] : upper-right x coordinate</li>
2078          * <li>['MediaBox']['ury'] : upper-right y coordinate</li>
2079          * <li>['CropBox'] : the visible region of default user space:</li>
2080          * <li>['CropBox']['llx'] : lower-left x coordinate</li>
2081          * <li>['CropBox']['lly'] : lower-left y coordinate</li>
2082          * <li>['CropBox']['urx'] : upper-right x coordinate</li>
2083          * <li>['CropBox']['ury'] : upper-right y coordinate</li>
2084          * <li>['BleedBox'] : the region to which the contents of the page shall be clipped when output in a production environment:</li>
2085          * <li>['BleedBox']['llx'] : lower-left x coordinate</li>
2086          * <li>['BleedBox']['lly'] : lower-left y coordinate</li>
2087          * <li>['BleedBox']['urx'] : upper-right x coordinate</li>
2088          * <li>['BleedBox']['ury'] : upper-right y coordinate</li>
2089          * <li>['TrimBox'] : the intended dimensions of the finished page after trimming:</li>
2090          * <li>['TrimBox']['llx'] : lower-left x coordinate</li>
2091          * <li>['TrimBox']['lly'] : lower-left y coordinate</li>
2092          * <li>['TrimBox']['urx'] : upper-right x coordinate</li>
2093          * <li>['TrimBox']['ury'] : upper-right y coordinate</li>
2094          * <li>['ArtBox'] : the extent of the page's meaningful content:</li>
2095          * <li>['ArtBox']['llx'] : lower-left x coordinate</li>
2096          * <li>['ArtBox']['lly'] : lower-left y coordinate</li>
2097          * <li>['ArtBox']['urx'] : upper-right x coordinate</li>
2098          * <li>['ArtBox']['ury'] : upper-right y coordinate</li>
2099          * <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>
2100          * <li>['BoxColorInfo'][BOXTYPE]['C'] : an array of three numbers in the range 0-255, representing the components in the DeviceRGB colour space.</li>
2101          * <li>['BoxColorInfo'][BOXTYPE]['W'] : the guideline width in default user units</li>
2102          * <li>['BoxColorInfo'][BOXTYPE]['S'] : the guideline style: S = Solid; D = Dashed</li>
2103          * <li>['BoxColorInfo'][BOXTYPE]['D'] : dash array defining a pattern of dashes and gaps to be used in drawing dashed guidelines</li>
2104          * <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>
2105          * <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>
2106          * <li>['trans']['S'] : transition style : Split, Blinds, Box, Wipe, Dissolve, Glitter, R, Fly, Push, Cover, Uncover, Fade</li>
2107          * <li>['trans']['D'] : The duration of the transition effect, in seconds.</li>
2108          * <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>
2109          * <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>
2110          * <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>
2111          * <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>
2112          * <li>['trans']['B'] : (Fly transition style only) If true, the area that shall be flown in is rectangular and opaque. Default: false.</li>
2113          * </ul>
2114          * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul>
2115          * <li>P or Portrait (default)</li>
2116          * <li>L or Landscape</li>
2117          * <li>'' (empty string) for automatic orientation</li>
2118          * </ul>
2119          * @protected
2120          * @since 3.0.015 (2008-06-06)
2121          * @see getPageSizeFromFormat()
2122          */
2123         protected function setPageFormat($format, $orientation='P') {
2124                 if (!empty($format) AND isset($this->pagedim[$this->page])) {
2125                         // remove inherited values
2126                         unset($this->pagedim[$this->page]);
2127                 }
2128                 if (is_string($format)) {
2129                         // get page measures from format name
2130                         $pf = TCPDF_STATIC::getPageSizeFromFormat($format);
2131                         $this->fwPt = $pf[0];
2132                         $this->fhPt = $pf[1];
2133                 } else {
2134                         // the boundaries of the physical medium on which the page shall be displayed or printed
2135                         if (isset($format['MediaBox'])) {
2136                                 $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);
2137                                 $this->fwPt = (($format['MediaBox']['urx'] - $format['MediaBox']['llx']) * $this->k);
2138                                 $this->fhPt = (($format['MediaBox']['ury'] - $format['MediaBox']['lly']) * $this->k);
2139                         } else {
2140                                 if (isset($format[0]) AND is_numeric($format[0]) AND isset($format[1]) AND is_numeric($format[1])) {
2141                                         $pf = array(($format[0] * $this->k), ($format[1] * $this->k));
2142                                 } else {
2143                                         if (!isset($format['format'])) {
2144                                                 // default value
2145                                                 $format['format'] = 'A4';
2146                                         }
2147                                         $pf = TCPDF_STATIC::getPageSizeFromFormat($format['format']);
2148                                 }
2149                                 $this->fwPt = $pf[0];
2150                                 $this->fhPt = $pf[1];
2151                                 $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'MediaBox', 0, 0, $this->fwPt, $this->fhPt, true, $this->k, $this->pagedim);
2152                         }
2153                         // the visible region of default user space
2154                         if (isset($format['CropBox'])) {
2155                                 $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);
2156                         }
2157                         // the region to which the contents of the page shall be clipped when output in a production environment
2158                         if (isset($format['BleedBox'])) {
2159                                 $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);
2160                         }
2161                         // the intended dimensions of the finished page after trimming
2162                         if (isset($format['TrimBox'])) {
2163                                 $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);
2164                         }
2165                         // the page's meaningful content (including potential white space)
2166                         if (isset($format['ArtBox'])) {
2167                                 $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);
2168                         }
2169                         // specify the colours and other visual characteristics that should be used in displaying guidelines on the screen for the various page boundaries
2170                         if (isset($format['BoxColorInfo'])) {
2171                                 $this->pagedim[$this->page]['BoxColorInfo'] = $format['BoxColorInfo'];
2172                         }
2173                         if (isset($format['Rotate']) AND (($format['Rotate'] % 90) == 0)) {
2174                                 // The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90.
2175                                 $this->pagedim[$this->page]['Rotate'] = intval($format['Rotate']);
2176                         }
2177                         if (isset($format['PZ'])) {
2178                                 // The page's preferred zoom (magnification) factor
2179                                 $this->pagedim[$this->page]['PZ'] = floatval($format['PZ']);
2180                         }
2181                         if (isset($format['trans'])) {
2182                                 // The style and duration of the visual transition to use when moving from another page to the given page during a presentation
2183                                 if (isset($format['trans']['Dur'])) {
2184                                         // The page's display duration
2185                                         $this->pagedim[$this->page]['trans']['Dur'] = floatval($format['trans']['Dur']);
2186                                 }
2187                                 $stansition_styles = array('Split', 'Blinds', 'Box', 'Wipe', 'Dissolve', 'Glitter', 'R', 'Fly', 'Push', 'Cover', 'Uncover', 'Fade');
2188                                 if (isset($format['trans']['S']) AND in_array($format['trans']['S'], $stansition_styles)) {
2189                                         // The transition style that shall be used when moving to this page from another during a presentation
2190                                         $this->pagedim[$this->page]['trans']['S'] = $format['trans']['S'];
2191                                         $valid_effect = array('Split', 'Blinds');
2192                                         $valid_vals = array('H', 'V');
2193                                         if (isset($format['trans']['Dm']) AND in_array($format['trans']['S'], $valid_effect) AND in_array($format['trans']['Dm'], $valid_vals)) {
2194                                                 $this->pagedim[$this->page]['trans']['Dm'] = $format['trans']['Dm'];
2195                                         }
2196                                         $valid_effect = array('Split', 'Box', 'Fly');
2197                                         $valid_vals = array('I', 'O');
2198                                         if (isset($format['trans']['M']) AND in_array($format['trans']['S'], $valid_effect) AND in_array($format['trans']['M'], $valid_vals)) {
2199                                                 $this->pagedim[$this->page]['trans']['M'] = $format['trans']['M'];
2200                                         }
2201                                         $valid_effect = array('Wipe', 'Glitter', 'Fly', 'Cover', 'Uncover', 'Push');
2202                                         if (isset($format['trans']['Di']) AND in_array($format['trans']['S'], $valid_effect)) {
2203                                                 if (((($format['trans']['Di'] == 90) OR ($format['trans']['Di'] == 180)) AND ($format['trans']['S'] == 'Wipe'))
2204                                                         OR (($format['trans']['Di'] == 315) AND ($format['trans']['S'] == 'Glitter'))
2205                                                         OR (($format['trans']['Di'] == 0) OR ($format['trans']['Di'] == 270))) {
2206                                                         $this->pagedim[$this->page]['trans']['Di'] = intval($format['trans']['Di']);
2207                                                 }
2208                                         }
2209                                         if (isset($format['trans']['SS']) AND ($format['trans']['S'] == 'Fly')) {
2210                                                 $this->pagedim[$this->page]['trans']['SS'] = floatval($format['trans']['SS']);
2211                                         }
2212                                         if (isset($format['trans']['B']) AND ($format['trans']['B'] === true) AND ($format['trans']['S'] == 'Fly')) {
2213                                                 $this->pagedim[$this->page]['trans']['B'] = 'true';
2214                                         }
2215                                 } else {
2216                                         $this->pagedim[$this->page]['trans']['S'] = 'R';
2217                                 }
2218                                 if (isset($format['trans']['D'])) {
2219                                         // The duration of the transition effect, in seconds
2220                                         $this->pagedim[$this->page]['trans']['D'] = floatval($format['trans']['D']);
2221                                 } else {
2222                                         $this->pagedim[$this->page]['trans']['D'] = 1;
2223                                 }
2224                         }
2225                 }
2226                 $this->setPageOrientation($orientation);
2227         }
2229         /**
2230          * Set page orientation.
2231          * @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>
2232          * @param $autopagebreak (boolean) Boolean indicating if auto-page-break mode should be on or off.
2233          * @param $bottommargin (float) bottom margin of the page.
2234          * @public
2235          * @since 3.0.015 (2008-06-06)
2236          */
2237         public function setPageOrientation($orientation, $autopagebreak='', $bottommargin='') {
2238                 if (!isset($this->pagedim[$this->page]['MediaBox'])) {
2239                         // the boundaries of the physical medium on which the page shall be displayed or printed
2240                         $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'MediaBox', 0, 0, $this->fwPt, $this->fhPt, true, $this->k, $this->pagedim);
2241                 }
2242                 if (!isset($this->pagedim[$this->page]['CropBox'])) {
2243                         // the visible region of default user space
2244                         $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);
2245                 }
2246                 if (!isset($this->pagedim[$this->page]['BleedBox'])) {
2247                         // the region to which the contents of the page shall be clipped when output in a production environment
2248                         $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);
2249                 }
2250                 if (!isset($this->pagedim[$this->page]['TrimBox'])) {
2251                         // the intended dimensions of the finished page after trimming
2252                         $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);
2253                 }
2254                 if (!isset($this->pagedim[$this->page]['ArtBox'])) {
2255                         // the page's meaningful content (including potential white space)
2256                         $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);
2257                 }
2258                 if (!isset($this->pagedim[$this->page]['Rotate'])) {
2259                         // The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90.
2260                         $this->pagedim[$this->page]['Rotate'] = 0;
2261                 }
2262                 if (!isset($this->pagedim[$this->page]['PZ'])) {
2263                         // The page's preferred zoom (magnification) factor
2264                         $this->pagedim[$this->page]['PZ'] = 1;
2265                 }
2266                 if ($this->fwPt > $this->fhPt) {
2267                         // landscape
2268                         $default_orientation = 'L';
2269                 } else {
2270                         // portrait
2271                         $default_orientation = 'P';
2272                 }
2273                 $valid_orientations = array('P', 'L');
2274                 if (empty($orientation)) {
2275                         $orientation = $default_orientation;
2276                 } else {
2277                         $orientation = strtoupper($orientation[0]);
2278                 }
2279                 if (in_array($orientation, $valid_orientations) AND ($orientation != $default_orientation)) {
2280                         $this->CurOrientation = $orientation;
2281                         $this->wPt = $this->fhPt;
2282                         $this->hPt = $this->fwPt;
2283                 } else {
2284                         $this->CurOrientation = $default_orientation;
2285                         $this->wPt = $this->fwPt;
2286                         $this->hPt = $this->fhPt;
2287                 }
2288                 if ((abs($this->pagedim[$this->page]['MediaBox']['urx'] - $this->hPt) < $this->feps) AND (abs($this->pagedim[$this->page]['MediaBox']['ury'] - $this->wPt) < $this->feps)){
2289                         // swap X and Y coordinates (change page orientation)
2290                         $this->pagedim = TCPDF_STATIC::swapPageBoxCoordinates($this->page, $this->pagedim);
2291                 }
2292                 $this->w = ($this->wPt / $this->k);
2293                 $this->h = ($this->hPt / $this->k);
2294                 if (TCPDF_STATIC::empty_string($autopagebreak)) {
2295                         if (isset($this->AutoPageBreak)) {
2296                                 $autopagebreak = $this->AutoPageBreak;
2297                         } else {
2298                                 $autopagebreak = true;
2299                         }
2300                 }
2301                 if (TCPDF_STATIC::empty_string($bottommargin)) {
2302                         if (isset($this->bMargin)) {
2303                                 $bottommargin = $this->bMargin;
2304                         } else {
2305                                 // default value = 2 cm
2306                                 $bottommargin = 2 * 28.35 / $this->k;
2307                         }
2308                 }
2309                 $this->SetAutoPageBreak($autopagebreak, $bottommargin);
2310                 // store page dimensions
2311                 $this->pagedim[$this->page]['w'] = $this->wPt;
2312                 $this->pagedim[$this->page]['h'] = $this->hPt;
2313                 $this->pagedim[$this->page]['wk'] = $this->w;
2314                 $this->pagedim[$this->page]['hk'] = $this->h;
2315                 $this->pagedim[$this->page]['tm'] = $this->tMargin;
2316                 $this->pagedim[$this->page]['bm'] = $bottommargin;
2317                 $this->pagedim[$this->page]['lm'] = $this->lMargin;
2318                 $this->pagedim[$this->page]['rm'] = $this->rMargin;
2319                 $this->pagedim[$this->page]['pb'] = $autopagebreak;
2320                 $this->pagedim[$this->page]['or'] = $this->CurOrientation;
2321                 $this->pagedim[$this->page]['olm'] = $this->original_lMargin;
2322                 $this->pagedim[$this->page]['orm'] = $this->original_rMargin;
2323         }
2325         /**
2326          * Set regular expression to detect withespaces or word separators.
2327          * The pattern delimiter must be the forward-slash character "/".
2328          * Some example patterns are:
2329          * <pre>
2330          * Non-Unicode or missing PCRE unicode support: "/[^\S\xa0]/"
2331          * Unicode and PCRE unicode support: "/(?!\xa0)[\s\p{Z}]/u"
2332          * Unicode and PCRE unicode support in Chinese mode: "/(?!\xa0)[\s\p{Z}\p{Lo}]/u"
2333          * if PCRE unicode support is turned ON ("\P" is the negate class of "\p"):
2334          *      \s     : any whitespace character
2335          *      \p{Z}  : any separator
2336          *      \p{Lo} : Unicode letter or ideograph that does not have lowercase and uppercase variants. Is used to chunk chinese words.
2337          *      \xa0   : Unicode Character 'NO-BREAK SPACE' (U+00A0)
2338          * </pre>
2339          * @param $re (string) regular expression (leave empty for default).
2340          * @public
2341          * @since 4.6.016 (2009-06-15)
2342          */
2343         public function setSpacesRE($re='/[^\S\xa0]/') {
2344                 $this->re_spaces = $re;
2345                 $re_parts = explode('/', $re);
2346                 // get pattern parts
2347                 $this->re_space = array();
2348                 if (isset($re_parts[1]) AND !empty($re_parts[1])) {
2349                         $this->re_space['p'] = $re_parts[1];
2350                 } else {
2351                         $this->re_space['p'] = '[\s]';
2352                 }
2353                 // set pattern modifiers
2354                 if (isset($re_parts[2]) AND !empty($re_parts[2])) {
2355                         $this->re_space['m'] = $re_parts[2];
2356                 } else {
2357                         $this->re_space['m'] = '';
2358                 }
2359         }
2361         /**
2362          * Enable or disable Right-To-Left language mode
2363          * @param $enable (Boolean) if true enable Right-To-Left language mode.
2364          * @param $resetx (Boolean) if true reset the X position on direction change.
2365          * @public
2366          * @since 2.0.000 (2008-01-03)
2367          */
2368         public function setRTL($enable, $resetx=true) {
2369                 $enable = $enable ? true : false;
2370                 $resetx = ($resetx AND ($enable != $this->rtl));
2371                 $this->rtl = $enable;
2372                 $this->tmprtl = false;
2373                 if ($resetx) {
2374                         $this->Ln(0);
2375                 }
2376         }
2378         /**
2379          * Return the RTL status
2380          * @return boolean
2381          * @public
2382          * @since 4.0.012 (2008-07-24)
2383          */
2384         public function getRTL() {
2385                 return $this->rtl;
2386         }
2388         /**
2389          * Force temporary RTL language direction
2390          * @param $mode (mixed) can be false, 'L' for LTR or 'R' for RTL
2391          * @public
2392          * @since 2.1.000 (2008-01-09)
2393          */
2394         public function setTempRTL($mode) {
2395                 $newmode = false;
2396                 switch (strtoupper($mode)) {
2397                         case 'LTR':
2398                         case 'L': {
2399                                 if ($this->rtl) {
2400                                         $newmode = 'L';
2401                                 }
2402                                 break;
2403                         }
2404                         case 'RTL':
2405                         case 'R': {
2406                                 if (!$this->rtl) {
2407                                         $newmode = 'R';
2408                                 }
2409                                 break;
2410                         }
2411                         case false:
2412                         default: {
2413                                 $newmode = false;
2414                                 break;
2415                         }
2416                 }
2417                 $this->tmprtl = $newmode;
2418         }
2420         /**
2421          * Return the current temporary RTL status
2422          * @return boolean
2423          * @public
2424          * @since 4.8.014 (2009-11-04)
2425          */
2426         public function isRTLTextDir() {
2427                 return ($this->rtl OR ($this->tmprtl == 'R'));
2428         }
2430         /**
2431          * Set the last cell height.
2432          * @param $h (float) cell height.
2433          * @author Nicola Asuni
2434          * @public
2435          * @since 1.53.0.TC034
2436          */
2437         public function setLastH($h) {
2438                 $this->lasth = $h;
2439         }
2441         /**
2442          * Return the cell height
2443          * @param $fontsize (int) Font size in internal units
2444          * @param $padding (boolean) If true add cell padding
2445          * @public
2446          */
2447         public function getCellHeight($fontsize, $padding=TRUE) {
2448                 $height = ($fontsize * $this->cell_height_ratio);
2449                 if ($padding) {
2450                         $height += ($this->cell_padding['T'] + $this->cell_padding['B']);
2451                 }
2452                 return round($height, 6);
2453         }
2455         /**
2456          * Reset the last cell height.
2457          * @public
2458          * @since 5.9.000 (2010-10-03)
2459          */
2460         public function resetLastH() {
2461                 $this->lasth = $this->getCellHeight($this->FontSize);
2462         }
2464         /**
2465          * Get the last cell height.
2466          * @return last cell height
2467          * @public
2468          * @since 4.0.017 (2008-08-05)
2469          */
2470         public function getLastH() {
2471                 return $this->lasth;
2472         }
2474         /**
2475          * Set the adjusting factor to convert pixels to user units.
2476          * @param $scale (float) adjusting factor to convert pixels to user units.
2477          * @author Nicola Asuni
2478          * @public
2479          * @since 1.5.2
2480          */
2481         public function setImageScale($scale) {
2482                 $this->imgscale = $scale;
2483         }
2485         /**
2486          * Returns the adjusting factor to convert pixels to user units.
2487          * @return float adjusting factor to convert pixels to user units.
2488          * @author Nicola Asuni
2489          * @public
2490          * @since 1.5.2
2491          */
2492         public function getImageScale() {
2493                 return $this->imgscale;
2494         }
2496         /**
2497          * Returns an array of page dimensions:
2498          * <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>
2499          * @param $pagenum (int) page number (empty = current page)
2500          * @return array of page dimensions.
2501          * @author Nicola Asuni
2502          * @public
2503          * @since 4.5.027 (2009-03-16)
2504          */
2505         public function getPageDimensions($pagenum='') {
2506                 if (empty($pagenum)) {
2507                         $pagenum = $this->page;
2508                 }
2509                 return $this->pagedim[$pagenum];
2510         }
2512         /**
2513          * Returns the page width in units.
2514          * @param $pagenum (int) page number (empty = current page)
2515          * @return int page width.
2516          * @author Nicola Asuni
2517          * @public
2518          * @since 1.5.2
2519          * @see getPageDimensions()
2520          */
2521         public function getPageWidth($pagenum='') {
2522                 if (empty($pagenum)) {
2523                         return $this->w;
2524                 }
2525                 return $this->pagedim[$pagenum]['w'];
2526         }
2528         /**
2529          * Returns the page height in units.
2530          * @param $pagenum (int) page number (empty = current page)
2531          * @return int page height.
2532          * @author Nicola Asuni
2533          * @public
2534          * @since 1.5.2
2535          * @see getPageDimensions()
2536          */
2537         public function getPageHeight($pagenum='') {
2538                 if (empty($pagenum)) {
2539                         return $this->h;
2540                 }
2541                 return $this->pagedim[$pagenum]['h'];
2542         }
2544         /**
2545          * Returns the page break margin.
2546          * @param $pagenum (int) page number (empty = current page)
2547          * @return int page break margin.
2548          * @author Nicola Asuni
2549          * @public
2550          * @since 1.5.2
2551          * @see getPageDimensions()
2552          */
2553         public function getBreakMargin($pagenum='') {
2554                 if (empty($pagenum)) {
2555                         return $this->bMargin;
2556                 }
2557                 return $this->pagedim[$pagenum]['bm'];
2558         }
2560         /**
2561          * Returns the scale factor (number of points in user unit).
2562          * @return int scale factor.
2563          * @author Nicola Asuni
2564          * @public
2565          * @since 1.5.2
2566          */
2567         public function getScaleFactor() {
2568                 return $this->k;
2569         }
2571         /**
2572          * Defines the left, top and right margins.
2573          * @param $left (float) Left margin.
2574          * @param $top (float) Top margin.
2575          * @param $right (float) Right margin. Default value is the left one.
2576          * @param $keepmargins (boolean) if true overwrites the default page margins
2577          * @public
2578          * @since 1.0
2579          * @see SetLeftMargin(), SetTopMargin(), SetRightMargin(), SetAutoPageBreak()
2580          */
2581         public function SetMargins($left, $top, $right=-1, $keepmargins=false) {
2582                 //Set left, top and right margins
2583                 $this->lMargin = $left;
2584                 $this->tMargin = $top;
2585                 if ($right == -1) {
2586                         $right = $left;
2587                 }
2588                 $this->rMargin = $right;
2589                 if ($keepmargins) {
2590                         // overwrite original values
2591                         $this->original_lMargin = $this->lMargin;
2592                         $this->original_rMargin = $this->rMargin;
2593                 }
2594         }
2596         /**
2597          * 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.
2598          * @param $margin (float) The margin.
2599          * @public
2600          * @since 1.4
2601          * @see SetTopMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins()
2602          */
2603         public function SetLeftMargin($margin) {
2604                 //Set left margin
2605                 $this->lMargin = $margin;
2606                 if (($this->page > 0) AND ($this->x < $margin)) {
2607                         $this->x = $margin;
2608                 }
2609         }
2611         /**
2612          * Defines the top margin. The method can be called before creating the first page.
2613          * @param $margin (float) The margin.
2614          * @public
2615          * @since 1.5
2616          * @see SetLeftMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins()
2617          */
2618         public function SetTopMargin($margin) {
2619                 //Set top margin
2620                 $this->tMargin = $margin;
2621                 if (($this->page > 0) AND ($this->y < $margin)) {
2622                         $this->y = $margin;
2623                 }
2624         }
2626         /**
2627          * Defines the right margin. The method can be called before creating the first page.
2628          * @param $margin (float) The margin.
2629          * @public
2630          * @since 1.5
2631          * @see SetLeftMargin(), SetTopMargin(), SetAutoPageBreak(), SetMargins()
2632          */
2633         public function SetRightMargin($margin) {
2634                 $this->rMargin = $margin;
2635                 if (($this->page > 0) AND ($this->x > ($this->w - $margin))) {
2636                         $this->x = $this->w - $margin;
2637                 }
2638         }
2640         /**
2641          * Set the same internal Cell padding for top, right, bottom, left-
2642          * @param $pad (float) internal padding.
2643          * @public
2644          * @since 2.1.000 (2008-01-09)
2645          * @see getCellPaddings(), setCellPaddings()
2646          */
2647         public function SetCellPadding($pad) {
2648                 if ($pad >= 0) {
2649                         $this->cell_padding['L'] = $pad;
2650                         $this->cell_padding['T'] = $pad;
2651                         $this->cell_padding['R'] = $pad;
2652                         $this->cell_padding['B'] = $pad;
2653                 }
2654         }
2656         /**
2657          * Set the internal Cell paddings.
2658          * @param $left (float) left padding
2659          * @param $top (float) top padding
2660          * @param $right (float) right padding
2661          * @param $bottom (float) bottom padding
2662          * @public
2663          * @since 5.9.000 (2010-10-03)
2664          * @see getCellPaddings(), SetCellPadding()
2665          */
2666         public function setCellPaddings($left='', $top='', $right='', $bottom='') {
2667                 if (($left !== '') AND ($left >= 0)) {
2668                         $this->cell_padding['L'] = $left;
2669                 }
2670                 if (($top !== '') AND ($top >= 0)) {
2671                         $this->cell_padding['T'] = $top;
2672                 }
2673                 if (($right !== '') AND ($right >= 0)) {
2674                         $this->cell_padding['R'] = $right;
2675                 }
2676                 if (($bottom !== '') AND ($bottom >= 0)) {
2677                         $this->cell_padding['B'] = $bottom;
2678                 }
2679         }
2681         /**
2682          * Get the internal Cell padding array.
2683          * @return array of padding values
2684          * @public
2685          * @since 5.9.000 (2010-10-03)
2686          * @see setCellPaddings(), SetCellPadding()
2687          */
2688         public function getCellPaddings() {
2689                 return $this->cell_padding;
2690         }
2692         /**
2693          * Set the internal Cell margins.
2694          * @param $left (float) left margin
2695          * @param $top (float) top margin
2696          * @param $right (float) right margin
2697          * @param $bottom (float) bottom margin
2698          * @public
2699          * @since 5.9.000 (2010-10-03)
2700          * @see getCellMargins()
2701          */
2702         public function setCellMargins($left='', $top='', $right='', $bottom='') {
2703                 if (($left !== '') AND ($left >= 0)) {
2704                         $this->cell_margin['L'] = $left;
2705                 }
2706                 if (($top !== '') AND ($top >= 0)) {
2707                         $this->cell_margin['T'] = $top;
2708                 }
2709                 if (($right !== '') AND ($right >= 0)) {
2710                         $this->cell_margin['R'] = $right;
2711                 }
2712                 if (($bottom !== '') AND ($bottom >= 0)) {
2713                         $this->cell_margin['B'] = $bottom;
2714                 }
2715         }
2717         /**
2718          * Get the internal Cell margin array.
2719          * @return array of margin values
2720          * @public
2721          * @since 5.9.000 (2010-10-03)
2722          * @see setCellMargins()
2723          */
2724         public function getCellMargins() {
2725                 return $this->cell_margin;
2726         }
2728         /**
2729          * Adjust the internal Cell padding array to take account of the line width.
2730          * @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)))
2731          * @return array of adjustments
2732          * @public
2733          * @since 5.9.000 (2010-10-03)
2734          */
2735         protected function adjustCellPadding($brd=0) {
2736                 if (empty($brd)) {
2737                         return;
2738                 }
2739                 if (is_string($brd)) {
2740                         // convert string to array
2741                         $slen = strlen($brd);
2742                         $newbrd = array();
2743                         for ($i = 0; $i < $slen; ++$i) {
2744                                 $newbrd[$brd[$i]] = true;
2745                         }
2746                         $brd = $newbrd;
2747                 } elseif (($brd === 1) OR ($brd === true) OR (is_numeric($brd) AND (intval($brd) > 0))) {
2748                         $brd = array('LRTB' => true);
2749                 }
2750                 if (!is_array($brd)) {
2751                         return;
2752                 }
2753                 // store current cell padding
2754                 $cp = $this->cell_padding;
2755                 // select border mode
2756                 if (isset($brd['mode'])) {
2757                         $mode = $brd['mode'];
2758                         unset($brd['mode']);
2759                 } else {
2760                         $mode = 'normal';
2761                 }
2762                 // process borders
2763                 foreach ($brd as $border => $style) {
2764                         $line_width = $this->LineWidth;
2765                         if (is_array($style) AND isset($style['width'])) {
2766                                 // get border width
2767                                 $line_width = $style['width'];
2768                         }
2769                         $adj = 0; // line width inside the cell
2770                         switch ($mode) {
2771                                 case 'ext': {
2772                                         $adj = 0;
2773                                         break;
2774                                 }
2775                                 case 'int': {
2776                                         $adj = $line_width;
2777                                         break;
2778                                 }
2779                                 case 'normal':
2780                                 default: {
2781                                         $adj = ($line_width / 2);
2782                                         break;
2783                                 }
2784                         }
2785                         // correct internal cell padding if required to avoid overlap between text and lines
2786                         if ((strpos($border,'T') !== false) AND ($this->cell_padding['T'] < $adj)) {
2787                                 $this->cell_padding['T'] = $adj;
2788                         }
2789                         if ((strpos($border,'R') !== false) AND ($this->cell_padding['R'] < $adj)) {
2790                                 $this->cell_padding['R'] = $adj;
2791                         }
2792                         if ((strpos($border,'B') !== false) AND ($this->cell_padding['B'] < $adj)) {
2793                                 $this->cell_padding['B'] = $adj;
2794                         }
2795                         if ((strpos($border,'L') !== false) AND ($this->cell_padding['L'] < $adj)) {
2796                                 $this->cell_padding['L'] = $adj;
2797                         }
2798                 }
2799                 return array('T' => ($this->cell_padding['T'] - $cp['T']), 'R' => ($this->cell_padding['R'] - $cp['R']), 'B' => ($this->cell_padding['B'] - $cp['B']), 'L' => ($this->cell_padding['L'] - $cp['L']));
2800         }
2802         /**
2803          * 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.
2804          * @param $auto (boolean) Boolean indicating if mode should be on or off.
2805          * @param $margin (float) Distance from the bottom of the page.
2806          * @public
2807          * @since 1.0
2808          * @see Cell(), MultiCell(), AcceptPageBreak()
2809          */
2810         public function SetAutoPageBreak($auto, $margin=0) {
2811                 $this->AutoPageBreak = $auto ? true : false;
2812                 $this->bMargin = $margin;
2813                 $this->PageBreakTrigger = $this->h - $margin;
2814         }
2816         /**
2817          * Return the auto-page-break mode (true or false).
2818          * @return boolean auto-page-break mode
2819          * @public
2820          * @since 5.9.088
2821          */
2822         public function getAutoPageBreak() {
2823                 return $this->AutoPageBreak;
2824         }
2826         /**
2827          * Defines the way the document is to be displayed by the viewer.
2828          * @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>
2829          * @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>
2830          * @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>
2831          * @public
2832          * @since 1.2
2833          */
2834         public function SetDisplayMode($zoom, $layout='SinglePage', $mode='UseNone') {
2835                 if (($zoom == 'fullpage') OR ($zoom == 'fullwidth') OR ($zoom == 'real') OR ($zoom == 'default') OR (!is_string($zoom))) {
2836                         $this->ZoomMode = $zoom;
2837                 } else {
2838                         $this->Error('Incorrect zoom display mode: '.$zoom);
2839                 }
2840                 $this->LayoutMode = TCPDF_STATIC::getPageLayoutMode($layout);
2841                 $this->PageMode = TCPDF_STATIC::getPageMode($mode);
2842         }
2844         /**
2845          * 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.
2846          * Note: the Zlib extension is required for this feature. If not present, compression will be turned off.
2847          * @param $compress (boolean) Boolean indicating if compression must be enabled.
2848          * @public
2849          * @since 1.4
2850          */
2851         public function SetCompression($compress=true) {
2852                 $this->compress = false;
2853                 if (function_exists('gzcompress')) {
2854                         if ($compress) {
2855                                 if ( !$this->pdfa_mode) {
2856                                         $this->compress = true;
2857                                 }
2858                         }
2859                 }
2860         }
2862         /**
2863          * Set flag to force sRGB_IEC61966-2.1 black scaled ICC color profile for the whole document.
2864          * @param $mode (boolean) If true force sRGB output intent.
2865          * @public
2866          * @since 5.9.121 (2011-09-28)
2867          */
2868         public function setSRGBmode($mode=false) {
2869                 $this->force_srgb = $mode ? true : false;
2870         }
2872         /**
2873          * Turn on/off Unicode mode for document information dictionary (meta tags).
2874          * This has effect only when unicode mode is set to false.
2875          * @param $unicode (boolean) if true set the meta information in Unicode
2876          * @since 5.9.027 (2010-12-01)
2877          * @public
2878          */
2879         public function SetDocInfoUnicode($unicode=true) {
2880                 $this->docinfounicode = $unicode ? true : false;
2881         }
2883         /**
2884          * Defines the title of the document.
2885          * @param $title (string) The title.
2886          * @public
2887          * @since 1.2
2888          * @see SetAuthor(), SetCreator(), SetKeywords(), SetSubject()
2889          */
2890         public function SetTitle($title) {
2891                 $this->title = $title;
2892         }
2894         /**
2895          * Defines the subject of the document.
2896          * @param $subject (string) The subject.
2897          * @public
2898          * @since 1.2
2899          * @see SetAuthor(), SetCreator(), SetKeywords(), SetTitle()
2900          */
2901         public function SetSubject($subject) {
2902                 $this->subject = $subject;
2903         }
2905         /**
2906          * Defines the author of the document.
2907          * @param $author (string) The name of the author.
2908          * @public
2909          * @since 1.2
2910          * @see SetCreator(), SetKeywords(), SetSubject(), SetTitle()
2911          */
2912         public function SetAuthor($author) {
2913                 $this->author = $author;
2914         }
2916         /**
2917          * Associates keywords with the document, generally in the form 'keyword1 keyword2 ...'.
2918          * @param $keywords (string) The list of keywords.
2919          * @public
2920          * @since 1.2
2921          * @see SetAuthor(), SetCreator(), SetSubject(), SetTitle()
2922          */
2923         public function SetKeywords($keywords) {
2924                 $this->keywords = $keywords;
2925         }
2927         /**
2928          * Defines the creator of the document. This is typically the name of the application that generates the PDF.
2929          * @param $creator (string) The name of the creator.
2930          * @public
2931          * @since 1.2
2932          * @see SetAuthor(), SetKeywords(), SetSubject(), SetTitle()
2933          */
2934         public function SetCreator($creator) {
2935                 $this->creator = $creator;
2936         }
2938         /**
2939          * Throw an exception or print an error message and die if the K_TCPDF_PARSER_THROW_EXCEPTION_ERROR constant is set to true.
2940          * @param $msg (string) The error message
2941          * @public
2942          * @since 1.0
2943          */
2944         public function Error($msg) {
2945                 // unset all class variables
2946                 $this->_destroy(true);
2947                 if (defined('K_TCPDF_THROW_EXCEPTION_ERROR') AND !K_TCPDF_THROW_EXCEPTION_ERROR) {
2948                         die('<strong>TCPDF ERROR: </strong>'.$msg);
2949                 } else {
2950                         throw new Exception('TCPDF ERROR: '.$msg);
2951                 }
2952         }
2954         /**
2955          * This method begins the generation of the PDF document.
2956          * It is not necessary to call it explicitly because AddPage() does it automatically.
2957          * Note: no page is created by this method
2958          * @public
2959          * @since 1.0
2960          * @see AddPage(), Close()
2961          */
2962         public function Open() {
2963                 $this->state = 1;
2964         }
2966         /**
2967          * Terminates the PDF document.
2968          * It is not necessary to call this method explicitly because Output() does it automatically.
2969          * If the document contains no page, AddPage() is called to prevent from getting an invalid document.
2970          * @public
2971          * @since 1.0
2972          * @see Open(), Output()
2973          */
2974         public function Close() {
2975                 if ($this->state == 3) {
2976                         return;
2977                 }
2978                 if ($this->page == 0) {
2979                         $this->AddPage();
2980                 }
2981                 $this->endLayer();
2982                 if ($this->tcpdflink) {
2983                         // save current graphic settings
2984                         $gvars = $this->getGraphicVars();
2985                         $this->setEqualColumns();
2986                         $this->lastpage(true);
2987                         $this->SetAutoPageBreak(false);
2988                         $this->x = 0;
2989                         $this->y = $this->h - (1 / $this->k);
2990                         $this->lMargin = 0;
2991                         $this->_outSaveGraphicsState();
2992                         $font = defined('PDF_FONT_NAME_MAIN')?PDF_FONT_NAME_MAIN:'helvetica';
2993                         $this->SetFont($font, '', 1);
2994                         $this->setTextRenderingMode(0, false, false);
2995                         $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";
2996                         $lnk = "\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67";
2997                         $this->Cell(0, 0, $msg, 0, 0, 'L', 0, $lnk, 0, false, 'D', 'B');
2998                         $this->_outRestoreGraphicsState();
2999                         // restore graphic settings
3000                         $this->setGraphicVars($gvars);
3001                 }
3002                 // close page
3003                 $this->endPage();
3004                 // close document
3005                 $this->_enddoc();
3006                 // unset all class variables (except critical ones)
3007                 $this->_destroy(false);
3008         }
3010         /**
3011          * Move pointer at the specified document page and update page dimensions.
3012          * @param $pnum (int) page number (1 ... numpages)
3013          * @param $resetmargins (boolean) if true reset left, right, top margins and Y position.
3014          * @public
3015          * @since 2.1.000 (2008-01-07)
3016          * @see getPage(), lastpage(), getNumPages()
3017          */
3018         public function setPage($pnum, $resetmargins=false) {
3019                 if (($pnum == $this->page) AND ($this->state == 2)) {
3020                         return;
3021                 }
3022                 if (($pnum > 0) AND ($pnum <= $this->numpages)) {
3023                         $this->state = 2;
3024                         // save current graphic settings
3025                         //$gvars = $this->getGraphicVars();
3026                         $oldpage = $this->page;
3027                         $this->page = $pnum;
3028                         $this->wPt = $this->pagedim[$this->page]['w'];
3029                         $this->hPt = $this->pagedim[$this->page]['h'];
3030                         $this->w = $this->pagedim[$this->page]['wk'];
3031                         $this->h = $this->pagedim[$this->page]['hk'];
3032                         $this->tMargin = $this->pagedim[$this->page]['tm'];
3033                         $this->bMargin = $this->pagedim[$this->page]['bm'];
3034                         $this->original_lMargin = $this->pagedim[$this->page]['olm'];
3035                         $this->original_rMargin = $this->pagedim[$this->page]['orm'];
3036                         $this->AutoPageBreak = $this->pagedim[$this->page]['pb'];
3037                         $this->CurOrientation = $this->pagedim[$this->page]['or'];
3038                         $this->SetAutoPageBreak($this->AutoPageBreak, $this->bMargin);
3039                         // restore graphic settings
3040                         //$this->setGraphicVars($gvars);
3041                         if ($resetmargins) {
3042                                 $this->lMargin = $this->pagedim[$this->page]['olm'];
3043                                 $this->rMargin = $this->pagedim[$this->page]['orm'];
3044                                 $this->SetY($this->tMargin);
3045                         } else {
3046                                 // account for booklet mode
3047                                 if ($this->pagedim[$this->page]['olm'] != $this->pagedim[$oldpage]['olm']) {
3048                                         $deltam = $this->pagedim[$this->page]['olm'] - $this->pagedim[$this->page]['orm'];
3049                                         $this->lMargin += $deltam;
3050                                         $this->rMargin -= $deltam;
3051                                 }
3052                         }
3053                 } else {
3054                         $this->Error('Wrong page number on setPage() function: '.$pnum);
3055                 }
3056         }
3058         /**
3059          * Reset pointer to the last document page.
3060          * @param $resetmargins (boolean) if true reset left, right, top margins and Y position.
3061          * @public
3062          * @since 2.0.000 (2008-01-04)
3063          * @see setPage(), getPage(), getNumPages()
3064          */
3065         public function lastPage($resetmargins=false) {
3066                 $this->setPage($this->getNumPages(), $resetmargins);
3067         }
3069         /**
3070          * Get current document page number.
3071          * @return int page number
3072          * @public
3073          * @since 2.1.000 (2008-01-07)
3074          * @see setPage(), lastpage(), getNumPages()
3075          */
3076         public function getPage() {
3077                 return $this->page;
3078         }
3080         /**
3081          * Get the total number of insered pages.
3082          * @return int number of pages
3083          * @public
3084          * @since 2.1.000 (2008-01-07)
3085          * @see setPage(), getPage(), lastpage()
3086          */
3087         public function getNumPages() {
3088                 return $this->numpages;
3089         }
3091         /**
3092          * Adds a new TOC (Table Of Content) page to the document.
3093          * @param $orientation (string) page orientation.
3094          * @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().
3095          * @param $keepmargins (boolean) if true overwrites the default page margins with the current margins
3096          * @public
3097          * @since 5.0.001 (2010-05-06)
3098          * @see AddPage(), startPage(), endPage(), endTOCPage()
3099          */
3100         public function addTOCPage($orientation='', $format='', $keepmargins=false) {
3101                 $this->AddPage($orientation, $format, $keepmargins, true);
3102         }
3104         /**
3105          * Terminate the current TOC (Table Of Content) page
3106          * @public
3107          * @since 5.0.001 (2010-05-06)
3108          * @see AddPage(), startPage(), endPage(), addTOCPage()
3109          */
3110         public function endTOCPage() {
3111                 $this->endPage(true);
3112         }
3114         /**
3115          * 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).
3116          * The origin of the coordinate system is at the top-left corner (or top-right for RTL) and increasing ordinates go downwards.
3117          * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or PORTRAIT (default)</li><li>L or LANDSCAPE</li></ul>
3118          * @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().
3119          * @param $keepmargins (boolean) if true overwrites the default page margins with the current margins
3120          * @param $tocpage (boolean) if true set the tocpage state to true (the added page will be used to display Table Of Content).
3121          * @public
3122          * @since 1.0
3123          * @see startPage(), endPage(), addTOCPage(), endTOCPage(), getPageSizeFromFormat(), setPageFormat()
3124          */
3125         public function AddPage($orientation='', $format='', $keepmargins=false, $tocpage=false) {
3126                 if ($this->inxobj) {
3127                         // we are inside an XObject template
3128                         return;
3129                 }
3130                 if (!isset($this->original_lMargin) OR $keepmargins) {
3131                         $this->original_lMargin = $this->lMargin;
3132                 }
3133                 if (!isset($this->original_rMargin) OR $keepmargins) {
3134                         $this->original_rMargin = $this->rMargin;
3135                 }
3136                 // terminate previous page
3137                 $this->endPage();
3138                 // start new page
3139                 $this->startPage($orientation, $format, $tocpage);
3140         }
3142         /**
3143          * Terminate the current page
3144          * @param $tocpage (boolean) if true set the tocpage state to false (end the page used to display Table Of Content).
3145          * @public
3146          * @since 4.2.010 (2008-11-14)
3147          * @see AddPage(), startPage(), addTOCPage(), endTOCPage()
3148          */
3149         public function endPage($tocpage=false) {
3150                 // check if page is already closed
3151                 if (($this->page == 0) OR ($this->numpages > $this->page) OR (!$this->pageopen[$this->page])) {
3152                         return;
3153                 }
3154                 // print page footer
3155                 $this->setFooter();
3156                 // close page
3157                 $this->_endpage();
3158                 // mark page as closed
3159                 $this->pageopen[$this->page] = false;
3160                 if ($tocpage) {
3161                         $this->tocpage = false;
3162                 }
3163         }
3165         /**
3166          * Starts a new page to the document. The page must be closed using the endPage() function.
3167          * The origin of the coordinate system is at the top-left corner and increasing ordinates go downwards.
3168          * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or PORTRAIT (default)</li><li>L or LANDSCAPE</li></ul>
3169          * @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().
3170          * @param $tocpage (boolean) if true the page is designated to contain the Table-Of-Content.
3171          * @since 4.2.010 (2008-11-14)
3172          * @see AddPage(), endPage(), addTOCPage(), endTOCPage(), getPageSizeFromFormat(), setPageFormat()
3173          * @public
3174          */
3175         public function startPage($orientation='', $format='', $tocpage=false) {
3176                 if ($tocpage) {
3177                         $this->tocpage = true;
3178                 }
3179                 // move page numbers of documents to be attached
3180                 if ($this->tocpage) {
3181                         // move reference to unexistent pages (used for page attachments)
3182                         // adjust outlines
3183                         $tmpoutlines = $this->outlines;
3184                         foreach ($tmpoutlines as $key => $outline) {
3185                                 if (!$outline['f'] AND ($outline['p'] > $this->numpages)) {
3186                                         $this->outlines[$key]['p'] = ($outline['p'] + 1);
3187                                 }
3188                         }
3189                         // adjust dests
3190                         $tmpdests = $this->dests;
3191                         foreach ($tmpdests as $key => $dest) {
3192                                 if (!$dest['f'] AND ($dest['p'] > $this->numpages)) {
3193                                         $this->dests[$key]['p'] = ($dest['p'] + 1);
3194                                 }
3195                         }
3196                         // adjust links
3197                         $tmplinks = $this->links;
3198                         foreach ($tmplinks as $key => $link) {
3199                                 if (!$link['f'] AND ($link['p'] > $this->numpages)) {
3200                                         $this->links[$key]['p'] = ($link['p'] + 1);
3201                                 }
3202                         }
3203                 }
3204                 if ($this->numpages > $this->page) {
3205                         // this page has been already added
3206                         $this->setPage($this->page + 1);
3207                         $this->SetY($this->tMargin);
3208                         return;
3209                 }
3210                 // start a new page
3211                 if ($this->state == 0) {
3212                         $this->Open();
3213                 }
3214                 ++$this->numpages;
3215                 $this->swapMargins($this->booklet);
3216                 // save current graphic settings
3217                 $gvars = $this->getGraphicVars();
3218                 // start new page
3219                 $this->_beginpage($orientation, $format);
3220                 // mark page as open
3221                 $this->pageopen[$this->page] = true;
3222                 // restore graphic settings
3223                 $this->setGraphicVars($gvars);
3224                 // mark this point
3225                 $this->setPageMark();
3226                 // print page header
3227                 $this->setHeader();
3228                 // restore graphic settings
3229                 $this->setGraphicVars($gvars);
3230                 // mark this point
3231                 $this->setPageMark();
3232                 // print table header (if any)
3233                 $this->setTableHeader();
3234                 // set mark for empty page check
3235                 $this->emptypagemrk[$this->page]= $this->pagelen[$this->page];
3236         }
3238         /**
3239          * Set start-writing mark on current page stream used to put borders and fills.
3240          * Borders and fills are always created after content and inserted on the position marked by this method.
3241          * This function must be called after calling Image() function for a background image.
3242          * Background images must be always inserted before calling Multicell() or WriteHTMLCell() or WriteHTML() functions.
3243          * @public
3244          * @since 4.0.016 (2008-07-30)
3245          */
3246         public function setPageMark() {
3247                 $this->intmrk[$this->page] = $this->pagelen[$this->page];
3248                 $this->bordermrk[$this->page] = $this->intmrk[$this->page];
3249                 $this->setContentMark();
3250         }
3252         /**
3253          * Set start-writing mark on selected page.
3254          * Borders and fills are always created after content and inserted on the position marked by this method.
3255          * @param $page (int) page number (default is the current page)
3256          * @protected
3257          * @since 4.6.021 (2009-07-20)
3258          */
3259         protected function setContentMark($page=0) {
3260                 if ($page <= 0) {
3261                         $page = $this->page;
3262                 }
3263                 if (isset($this->footerlen[$page])) {
3264                         $this->cntmrk[$page] = $this->pagelen[$page] - $this->footerlen[$page];
3265                 } else {
3266                         $this->cntmrk[$page] = $this->pagelen[$page];
3267                 }
3268         }
3270         /**
3271          * Set header data.
3272          * @param $ln (string) header image logo
3273          * @param $lw (string) header image logo width in mm
3274          * @param $ht (string) string to print as title on document header
3275          * @param $hs (string) string to print on document header
3276          * @param $tc (array) RGB array color for text.
3277          * @param $lc (array) RGB array color for line.
3278          * @public
3279          */
3280         public function setHeaderData($ln='', $lw=0, $ht='', $hs='', $tc=array(0,0,0), $lc=array(0,0,0)) {
3281                 $this->header_logo = $ln;
3282                 $this->header_logo_width = $lw;
3283                 $this->header_title = $ht;
3284                 $this->header_string = $hs;
3285                 $this->header_text_color = $tc;
3286                 $this->header_line_color = $lc;
3287         }
3289         /**
3290          * Set footer data.
3291          * @param $tc (array) RGB array color for text.
3292          * @param $lc (array) RGB array color for line.
3293          * @public
3294          */
3295         public function setFooterData($tc=array(0,0,0), $lc=array(0,0,0)) {
3296                 $this->footer_text_color = $tc;
3297                 $this->footer_line_color = $lc;
3298         }
3300         /**
3301          * Returns header data:
3302          * <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>
3303          * @return array()
3304          * @public
3305          * @since 4.0.012 (2008-07-24)
3306          */
3307         public function getHeaderData() {
3308                 $ret = array();
3309                 $ret['logo'] = $this->header_logo;
3310                 $ret['logo_width'] = $this->header_logo_width;
3311                 $ret['title'] = $this->header_title;
3312                 $ret['string'] = $this->header_string;
3313                 $ret['text_color'] = $this->header_text_color;
3314                 $ret['line_color'] = $this->header_line_color;
3315                 return $ret;
3316         }
3318         /**
3319          * Set header margin.
3320          * (minimum distance between header and top page margin)
3321          * @param $hm (int) distance in user units
3322          * @public
3323          */
3324         public function setHeaderMargin($hm=10) {
3325                 $this->header_margin = $hm;
3326         }
3328         /**
3329          * Returns header margin in user units.
3330          * @return float
3331          * @since 4.0.012 (2008-07-24)
3332          * @public
3333          */
3334         public function getHeaderMargin() {
3335                 return $this->header_margin;
3336         }
3338         /**
3339          * Set footer margin.
3340          * (minimum distance between footer and bottom page margin)
3341          * @param $fm (int) distance in user units
3342          * @public
3343          */
3344         public function setFooterMargin($fm=10) {
3345                 $this->footer_margin = $fm;
3346         }
3348         /**
3349          * Returns footer margin in user units.
3350          * @return float
3351          * @since 4.0.012 (2008-07-24)
3352          * @public
3353          */
3354         public function getFooterMargin() {
3355                 return $this->footer_margin;
3356         }
3357         /**
3358          * Set a flag to print page header.
3359          * @param $val (boolean) set to true to print the page header (default), false otherwise.
3360          * @public
3361          */
3362         public function setPrintHeader($val=true) {
3363                 $this->print_header = $val ? true : false;
3364         }
3366         /**
3367          * Set a flag to print page footer.
3368          * @param $val (boolean) set to true to print the page footer (default), false otherwise.
3369          * @public
3370          */
3371         public function setPrintFooter($val=true) {
3372                 $this->print_footer = $val ? true : false;
3373         }
3375         /**
3376          * Return the right-bottom (or left-bottom for RTL) corner X coordinate of last inserted image
3377          * @return float
3378          * @public
3379          */
3380         public function getImageRBX() {
3381                 return $this->img_rb_x;
3382         }
3384         /**
3385          * Return the right-bottom (or left-bottom for RTL) corner Y coordinate of last inserted image
3386          * @return float
3387          * @public
3388          */
3389         public function getImageRBY() {
3390                 return $this->img_rb_y;
3391         }
3393         /**
3394          * Reset the xobject template used by Header() method.
3395          * @public
3396          */
3397         public function resetHeaderTemplate() {
3398                 $this->header_xobjid = false;
3399         }
3401         /**
3402          * Set a flag to automatically reset the xobject template used by Header() method at each page.
3403          * @param $val (boolean) set to true to reset Header xobject template at each page, false otherwise.
3404          * @public
3405          */
3406         public function setHeaderTemplateAutoreset($val=true) {
3407                 $this->header_xobj_autoreset = $val ? true : false;
3408         }
3410         /**
3411          * This method is used to render the page header.
3412          * It is automatically called by AddPage() and could be overwritten in your own inherited class.
3413          * @public
3414          */
3415         public function Header() {
3416                 if ($this->header_xobjid === false) {
3417                         // start a new XObject Template
3418                         $this->header_xobjid = $this->startTemplate($this->w, $this->tMargin);
3419                         $headerfont = $this->getHeaderFont();
3420                         $headerdata = $this->getHeaderData();
3421                         $this->y = $this->header_margin;
3422                         if ($this->rtl) {
3423                                 $this->x = $this->w - $this->original_rMargin;
3424                         } else {
3425                                 $this->x = $this->original_lMargin;
3426                         }
3427                         if (($headerdata['logo']) AND ($headerdata['logo'] != K_BLANK_IMAGE)) {
3428                                 $imgtype = TCPDF_IMAGES::getImageFileType(K_PATH_IMAGES.$headerdata['logo']);
3429                                 if (($imgtype == 'eps') OR ($imgtype == 'ai')) {
3430                                         $this->ImageEps(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']);
3431                                 } elseif ($imgtype == 'svg') {
3432                                         $this->ImageSVG(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']);
3433                                 } else {
3434                                         $this->Image(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']);
3435                                 }
3436                                 $imgy = $this->getImageRBY();
3437                         } else {
3438                                 $imgy = $this->y;
3439                         }
3440                         $cell_height = $this->getCellHeight($headerfont[2] / $this->k);
3441                         // set starting margin for text data cell
3442                         if ($this->getRTL()) {
3443                                 $header_x = $this->original_rMargin + ($headerdata['logo_width'] * 1.1);
3444                         } else {
3445                                 $header_x = $this->original_lMargin + ($headerdata['logo_width'] * 1.1);
3446                         }
3447                         $cw = $this->w - $this->original_lMargin - $this->original_rMargin - ($headerdata['logo_width'] * 1.1);
3448                         $this->SetTextColorArray($this->header_text_color);
3449                         // header title
3450                         $this->SetFont($headerfont[0], 'B', $headerfont[2] + 1);
3451                         $this->SetX($header_x);
3452                         $this->Cell($cw, $cell_height, $headerdata['title'], 0, 1, '', 0, '', 0);
3453                         // header string
3454                         $this->SetFont($headerfont[0], $headerfont[1], $headerfont[2]);
3455                         $this->SetX($header_x);
3456                         $this->MultiCell($cw, $cell_height, $headerdata['string'], 0, '', 0, 1, '', '', true, 0, false, true, 0, 'T', false);
3457                         // print an ending header line
3458                         $this->SetLineStyle(array('width' => 0.85 / $this->k, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $headerdata['line_color']));
3459                         $this->SetY((2.835 / $this->k) + max($imgy, $this->y));
3460                         if ($this->rtl) {
3461                                 $this->SetX($this->original_rMargin);
3462                         } else {
3463                                 $this->SetX($this->original_lMargin);
3464                         }
3465                         $this->Cell(($this->w - $this->original_lMargin - $this->original_rMargin), 0, '', 'T', 0, 'C');
3466                         $this->endTemplate();
3467                 }
3468                 // print header template
3469                 $x = 0;
3470                 $dx = 0;
3471                 if (!$this->header_xobj_autoreset AND $this->booklet AND (($this->page % 2) == 0)) {
3472                         // adjust margins for booklet mode
3473                         $dx = ($this->original_lMargin - $this->original_rMargin);
3474                 }
3475                 if ($this->rtl) {
3476                         $x = $this->w + $dx;
3477                 } else {
3478                         $x = 0 + $dx;
3479                 }
3480                 $this->printTemplate($this->header_xobjid, $x, 0, 0, 0, '', '', false);
3481                 if ($this->header_xobj_autoreset) {
3482                         // reset header xobject template at each page
3483                         $this->header_xobjid = false;
3484                 }
3485         }
3487         /**
3488          * This method is used to render the page footer.
3489          * It is automatically called by AddPage() and could be overwritten in your own inherited class.
3490          * @public
3491          */
3492         public function Footer() {
3493                 $cur_y = $this->y;
3494                 $this->SetTextColorArray($this->footer_text_color);
3495                 //set style for cell border
3496                 $line_width = (0.85 / $this->k);
3497                 $this->SetLineStyle(array('width' => $line_width, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $this->footer_line_color));
3498                 //print document barcode
3499                 $barcode = $this->getBarcode();
3500                 if (!empty($barcode)) {
3501                         $this->Ln($line_width);
3502                         $barcode_width = round(($this->w - $this->original_lMargin - $this->original_rMargin) / 3);
3503                         $style = array(
3504                                 'position' => $this->rtl?'R':'L',
3505                                 'align' => $this->rtl?'R':'L',
3506                                 'stretch' => false,
3507                                 'fitwidth' => true,
3508                                 'cellfitalign' => '',
3509                                 'border' => false,
3510                                 'padding' => 0,
3511                                 'fgcolor' => array(0,0,0),
3512                                 'bgcolor' => false,
3513                                 'text' => false
3514                         );
3515                         $this->write1DBarcode($barcode, 'C128', '', $cur_y + $line_width, '', (($this->footer_margin / 3) - $line_width), 0.3, $style, '');
3516                 }
3517                 $w_page = isset($this->l['w_page']) ? $this->l['w_page'].' ' : '';
3518                 if (empty($this->pagegroups)) {
3519                         $pagenumtxt = $w_page.$this->getAliasNumPage().' / '.$this->getAliasNbPages();
3520                 } else {
3521                         $pagenumtxt = $w_page.$this->getPageNumGroupAlias().' / '.$this->getPageGroupAlias();
3522                 }
3523                 $this->SetY($cur_y);
3524                 //Print page number
3525                 if ($this->getRTL()) {
3526                         $this->SetX($this->original_rMargin);
3527                         $this->Cell(0, 0, $pagenumtxt, 'T', 0, 'L');
3528                 } else {
3529                         $this->SetX($this->original_lMargin);
3530                         $this->Cell(0, 0, $this->getAliasRightShift().$pagenumtxt, 'T', 0, 'R');
3531                 }
3532         }
3534         /**
3535          * This method is used to render the page header.
3536          * @protected
3537          * @since 4.0.012 (2008-07-24)
3538          */
3539         protected function setHeader() {
3540                 if (!$this->print_header OR ($this->state != 2)) {
3541                         return;
3542                 }
3543                 $this->InHeader = true;
3544                 $this->setGraphicVars($this->default_graphic_vars);
3545                 $temp_thead = $this->thead;
3546                 $temp_theadMargins = $this->theadMargins;
3547                 $lasth = $this->lasth;
3548                 $newline = $this->newline;
3549                 $this->_outSaveGraphicsState();
3550                 $this->rMargin = $this->original_rMargin;
3551                 $this->lMargin = $this->original_lMargin;
3552                 $this->SetCellPadding(0);
3553                 //set current position
3554                 if ($this->rtl) {
3555                         $this->SetXY($this->original_rMargin, $this->header_margin);
3556                 } else {
3557                         $this->SetXY($this->original_lMargin, $this->header_margin);
3558                 }
3559                 $this->SetFont($this->header_font[0], $this->header_font[1], $this->header_font[2]);
3560                 $this->Header();
3561                 //restore position
3562                 if ($this->rtl) {
3563                         $this->SetXY($this->original_rMargin, $this->tMargin);
3564                 } else {
3565                         $this->SetXY($this->original_lMargin, $this->tMargin);
3566                 }
3567                 $this->_outRestoreGraphicsState();
3568                 $this->lasth = $lasth;
3569                 $this->thead = $temp_thead;
3570                 $this->theadMargins = $temp_theadMargins;
3571                 $this->newline = $newline;
3572                 $this->InHeader = false;
3573         }
3575         /**
3576          * This method is used to render the page footer.
3577          * @protected
3578          * @since 4.0.012 (2008-07-24)
3579          */
3580         protected function setFooter() {
3581                 if ($this->state != 2) {
3582                         return;
3583                 }
3584                 $this->InFooter = true;
3585                 // save current graphic settings
3586                 $gvars = $this->getGraphicVars();
3587                 // mark this point
3588                 $this->footerpos[$this->page] = $this->pagelen[$this->page];
3589                 $this->_out("\n");
3590                 if ($this->print_footer) {
3591                         $this->setGraphicVars($this->default_graphic_vars);
3592                         $this->current_column = 0;
3593                         $this->num_columns = 1;
3594                         $temp_thead = $this->thead;
3595                         $temp_theadMargins = $this->theadMargins;
3596                         $lasth = $this->lasth;
3597                         $this->_outSaveGraphicsState();
3598                         $this->rMargin = $this->original_rMargin;
3599                         $this->lMargin = $this->original_lMargin;
3600                         $this->SetCellPadding(0);
3601                         //set current position
3602                         $footer_y = $this->h - $this->footer_margin;
3603                         if ($this->rtl) {
3604                                 $this->SetXY($this->original_rMargin, $footer_y);
3605                         } else {
3606                                 $this->SetXY($this->original_lMargin, $footer_y);
3607                         }
3608                         $this->SetFont($this->footer_font[0], $this->footer_font[1], $this->footer_font[2]);
3609                         $this->Footer();
3610                         //restore position
3611                         if ($this->rtl) {
3612                                 $this->SetXY($this->original_rMargin, $this->tMargin);
3613                         } else {
3614                                 $this->SetXY($this->original_lMargin, $this->tMargin);
3615                         }
3616                         $this->_outRestoreGraphicsState();
3617                         $this->lasth = $lasth;
3618                         $this->thead = $temp_thead;
3619                         $this->theadMargins = $temp_theadMargins;
3620                 }
3621                 // restore graphic settings
3622                 $this->setGraphicVars($gvars);
3623                 $this->current_column = $gvars['current_column'];
3624                 $this->num_columns = $gvars['num_columns'];
3625                 // calculate footer length
3626                 $this->footerlen[$this->page] = $this->pagelen[$this->page] - $this->footerpos[$this->page] + 1;
3627                 $this->InFooter = false;
3628         }
3630         /**
3631          * Check if we are on the page body (excluding page header and footer).
3632          * @return true if we are not in page header nor in page footer, false otherwise.
3633          * @protected
3634          * @since 5.9.091 (2011-06-15)
3635          */
3636         protected function inPageBody() {
3637                 return (($this->InHeader === false) AND ($this->InFooter === false));
3638         }
3640         /**
3641          * This method is used to render the table header on new page (if any).
3642          * @protected
3643          * @since 4.5.030 (2009-03-25)
3644          */
3645         protected function setTableHeader() {
3646                 if ($this->num_columns > 1) {
3647                         // multi column mode
3648                         return;
3649                 }
3650                 if (isset($this->theadMargins['top'])) {
3651                         // restore the original top-margin
3652                         $this->tMargin = $this->theadMargins['top'];
3653                         $this->pagedim[$this->page]['tm'] = $this->tMargin;
3654                         $this->y = $this->tMargin;
3655                 }
3656                 if (!TCPDF_STATIC::empty_string($this->thead) AND (!$this->inthead)) {
3657                         // set margins
3658                         $prev_lMargin = $this->lMargin;
3659                         $prev_rMargin = $this->rMargin;
3660                         $prev_cell_padding = $this->cell_padding;
3661                         $this->lMargin = $this->theadMargins['lmargin'] + ($this->pagedim[$this->page]['olm'] - $this->pagedim[$this->theadMargins['page']]['olm']);
3662                         $this->rMargin = $this->theadMargins['rmargin'] + ($this->pagedim[$this->page]['orm'] - $this->pagedim[$this->theadMargins['page']]['orm']);
3663                         $this->cell_padding = $this->theadMargins['cell_padding'];
3664                         if ($this->rtl) {
3665                                 $this->x = $this->w - $this->rMargin;
3666                         } else {
3667                                 $this->x = $this->lMargin;
3668                         }
3669                         // account for special "cell" mode
3670                         if ($this->theadMargins['cell']) {
3671                                 if ($this->rtl) {
3672                                         $this->x -= $this->cell_padding['R'];
3673                                 } else {
3674                                         $this->x += $this->cell_padding['L'];
3675                                 }
3676                         }
3677                         $gvars = $this->getGraphicVars();
3678                         if (!empty($this->theadMargins['gvars'])) {
3679                                 // set the correct graphic style
3680                                 $this->setGraphicVars($this->theadMargins['gvars']);
3681                                 $this->rMargin = $gvars['rMargin'];
3682                                 $this->lMargin = $gvars['lMargin'];
3683                         }
3684                         // print table header
3685                         $this->writeHTML($this->thead, false, false, false, false, '');
3686                         $this->setGraphicVars($gvars);
3687                         // set new top margin to skip the table headers
3688                         if (!isset($this->theadMargins['top'])) {
3689                                 $this->theadMargins['top'] = $this->tMargin;
3690                         }
3691                         // store end of header position
3692                         if (!isset($this->columns[0]['th'])) {
3693                                 $this->columns[0]['th'] = array();
3694                         }
3695                         $this->columns[0]['th']['\''.$this->page.'\''] = $this->y;
3696                         $this->tMargin = $this->y;
3697                         $this->pagedim[$this->page]['tm'] = $this->tMargin;
3698                         $this->lasth = 0;
3699                         $this->lMargin = $prev_lMargin;
3700                         $this->rMargin = $prev_rMargin;
3701                         $this->cell_padding = $prev_cell_padding;
3702                 }
3703         }
3705         /**
3706          * Returns the current page number.
3707          * @return int page number
3708          * @public
3709          * @since 1.0
3710          * @see getAliasNbPages()
3711          */
3712         public function PageNo() {
3713                 return $this->page;
3714         }
3716         /**
3717          * Returns the array of spot colors.
3718          * @return (array) Spot colors array.
3719          * @public
3720          * @since 6.0.038 (2013-09-30)
3721          */
3722         public function getAllSpotColors() {
3723                 return $this->spot_colors;
3724         }
3726         /**
3727          * Defines a new spot color.