3 // ******************************************************************************
4 // Software: mPDF, Unicode-HTML Free PDF generator *
5 // Version: 5.7 based on *
6 // FPDF by Olivier PLATHEY *
7 // HTML2FPDF by Renato Coelho *
9 // Author: Ian Back <ianb@bpm1.com> *
12 // Changes: See changelog.txt *
13 // ******************************************************************************
16 define('mPDF_VERSION','5.7');
19 define('_MPDFK', (72/25.4));
22 define('AUTOFONT_CJK',1);
23 define('AUTOFONT_THAIVIET',2);
24 define('AUTOFONT_RTL',4);
25 define('AUTOFONT_INDIC',8);
26 define('AUTOFONT_ALL',15);
28 define('_BORDER_ALL',15);
29 define('_BORDER_TOP',8);
30 define('_BORDER_RIGHT',4);
31 define('_BORDER_BOTTOM',2);
32 define('_BORDER_LEFT',1);
33 /*-- END HTML-CSS --*/
35 if (!defined('_MPDF_PATH')) define('_MPDF_PATH', dirname(preg_replace('/\\\\/','/',__FILE__
)) . '/');
36 if (!defined('_MPDF_URI')) define('_MPDF_URI',_MPDF_PATH
);
38 require_once(_MPDF_PATH
.'includes/functions.php');
39 require_once(_MPDF_PATH
.'config_cp.php');
41 if (!defined('_JPGRAPH_PATH')) define("_JPGRAPH_PATH", _MPDF_PATH
.'jpgraph/');
43 if (!defined('_MPDF_TEMP_PATH')) define("_MPDF_TEMP_PATH", _MPDF_PATH
.'tmp/');
45 if (!defined('_MPDF_TTFONTPATH')) { define('_MPDF_TTFONTPATH',_MPDF_PATH
.'ttfonts/'); }
46 if (!defined('_MPDF_TTFONTDATAPATH')) { define('_MPDF_TTFONTDATAPATH',_MPDF_PATH
.'ttfontdata/'); }
48 $errorlevel=error_reporting();
49 $errorlevel=error_reporting($errorlevel & ~E_NOTICE
);
51 //error_reporting(E_ALL);
53 if(function_exists("date_default_timezone_set")) {
54 if (ini_get("date.timezone")=="") { date_default_timezone_set("Europe/London"); }
56 if (!function_exists("mb_strlen")) { die("Error - mPDF requires mb_string functions. Ensure that PHP is compiled with php_mbstring.dll enabled."); }
58 if (!defined('PHP_VERSION_ID')) {
59 $version = explode('.', PHP_VERSION
);
60 define('PHP_VERSION_ID', ($version[0] * 10000 +
$version[1] * 100 +
$version[2]));
62 // Machine dependent number of bytes used to pack "double" into binary (used in cacheTables)
63 $test = pack("d", 134455.474557333333666);
64 define("_DSIZE", strlen($test));
69 ///////////////////////////////
70 // EXTERNAL (PUBLIC) VARIABLES
71 // Define these in config.php
72 ///////////////////////////////
73 var $CJKforceend; // mPDF 5.6.40
77 var $decimal_align; // mPDF 5.6.13
78 var $margBuffer; // mPDF 5.4.04
79 var $splitTableBorderWidth; // mPDF 5.4.16
87 var $allowCJKoverflow;
90 var $restrictColorSpace;
105 var $iterationCounter;
117 var $tableMinSizePriority;
120 var $watermarkImgAlphaBlend;
121 var $watermarkImgBehind;
130 var $setAutoTopMargin;
131 var $setAutoBottomMargin;
132 var $autoMarginPadding;
133 var $collapseBlockMargins;
134 var $falseBoldWeight;
135 var $normalLineheight;
148 // PageNumber Conditional Text
153 var $showImageErrors;
154 var $allow_output_buffering;
157 var $autoFontGroupSize;
160 var $restoreBlockPagebreaks;
161 var $watermarkTextAlpha;
162 var $watermarkImageAlpha;
170 var $keep_table_proportions;
171 var $ignore_table_widths;
172 var $ignore_table_percents;
173 var $list_align_style;
174 var $list_number_suffix;
175 var $useSubstitutions;
178 var $forcePortraitHeaders;
179 var $forcePortraitMargins;
180 var $displayDefaultOrientation;
181 var $ignore_invalid_utf8;
184 var $allow_charset_conversion;
191 var $max_colH_correction;
194 var $table_error_report;
195 var $table_error_report_param;
197 var $text_input_as_HTML;
198 var $anchor2Bookmark;
199 var $list_indent_first_level;
200 var $shrink_tables_to_fit;
202 var $allow_html_optional_endtags;
206 var $defaultheaderfontsize;
207 var $defaultheaderfontstyle;
208 var $defaultheaderline;
209 var $defaultfooterfontsize;
210 var $defaultfooterfontstyle;
211 var $defaultfooterline;
212 var $header_line_spacing;
213 var $footer_line_spacing;
218 var $pregASCIIchars1;
219 var $pregASCIIchars2;
220 var $pregASCIIchars3;
222 var $pregVIETPluschars;
226 var $pregARABICchars;
227 var $pregNonARABICchars;
242 var $default_lineheight_correction;
245 var $showWatermarkText;
246 var $showWatermarkImage;
250 // Aliases for backward compatability
251 var $UnvalidatedText; // alias = $watermarkText
252 var $TopicIsUnvalidated; // alias = $showWatermarkText
253 var $useOddEven; // alias = $mirrorMargins
254 var $useSubstitutionsMB; // alias = $useSubstitutions
258 //////////////////////
260 //////////////////////
269 //////////////////////
270 // INTERNAL VARIABLES
271 //////////////////////
272 var $writingToC; // mPDF 5.6.38
276 var $open_layer_pane;
277 var $decimal_offset; // mPDF 5.6.13
278 var $inMeter; // mPDF 5.5.09
292 var $useRC128encryption;
309 var $tableBackgrounds;
310 var $inlineDisplayOff;
319 var $watermarkImgAlpha;
322 var $OutputIntentRoot;
324 var $current_filename;
329 var $_current_obj_id;
337 var $lastblockbottommargin;
343 var $forceExactLineheight;
346 var $fullImageHeight;
347 var $inFixedPosBlock; // Internal flag for position:fixed block
348 var $fixedPosBlock; // Buffer string for position:fixed block
349 var $fixedPosBlockDepth;
350 var $fixedPosBlockBBox;
351 var $fixedPosBlockSave;
357 var $extraFontSubsets;
358 var $docTemplateStart; // Internal flag for page (page no. -1) that docTemplate starts on
366 var $loadedSHYpatterns;
367 var $loadedSHYdictionary;
369 var $SHYdictionaryWords;
371 var $spanbgcolorarray;
373 var $list_lineheight;
375 var $lastblocklevelchange;
376 var $nestedtablejustfinished;
377 var $linebreakjustfinished;
378 var $cell_border_dominance_L;
379 var $cell_border_dominance_R;
380 var $cell_border_dominance_T;
381 var $cell_border_dominance_B;
382 var $table_keep_together;
383 var $plainCell_properties;
384 var $inherit_lineheight;
394 var $pageBackgrounds;
396 var $bodyBackgroundGradient;
397 var $bodyBackgroundImage;
398 var $bodyBackgroundColor;
400 var $writingHTMLheader; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
401 var $writingHTMLfooter;
411 var $tbrot_Reference;
412 var $tbrot_BMoutlines;
428 var $rtlAsArabicFarsi; // DEPRACATED
432 var $default_available_fonts;
435 var $docTemplateContinue;
446 var $formobjects; // array of Form Objects for WMF
447 var $InlineProperties;
457 var $pageDim; // Keep track of page wxh for orientation changes - set in _beginpage, used in _putannots
463 var $innermostTableLevel;
464 var $saveTableCounter;
465 var $cellBorderBuffer;
467 var $saveHTMLFooter_height;
468 var $saveHTMLFooterE_height;
470 var $firstPageBoxHeader;
471 var $firstPageBoxHeaderEven;
472 var $firstPageBoxFooter;
473 var $firstPageBoxFooterEven;
476 var $show_marks; // crop or cross marks
478 var $basepathIsLocal;
490 var $PageNumSubstitutions;
492 var $table_borders_separate;
493 var $base_table_properties;
496 var $listjustfinished;
497 var $blockjustfinished;
509 var $pageHTMLheaders;
510 var $pageHTMLfooters;
515 var $HTMLheaderPageLinks;
516 var $HTMLheaderPageAnnots;
517 var $HTMLheaderPageForms;
519 // See config_fonts.php for these next 5 values
520 var $available_unifonts;
524 var $defaultSubsFont;
526 // List of ALL available CJK fonts (incl. styles) (Adobe add-ons) hw removed
527 var $available_CJK_fonts;
535 var $showdefaultpagenos; // DEPRACATED -left for backward compatability
545 var $encrypted; //whether document is protected
546 var $Uvalue; //U entry in pdf document
547 var $Ovalue; //O entry in pdf document
548 var $Pvalue; //P entry in pdf document
549 var $enc_obj_id; //encryption object id
550 var $last_rc4_key; //last RC4 key encrypted (cached for optimisation)
551 var $last_rc4_key_c; //last RC4 computed key
553 var $padding; //used for encryption
564 var $y0; //Top ordinate of columns
576 var $substitute; // Array of substitution strings e.g. <ttz>112</ttz>
577 var $entsearch; // Array of HTML entities (>ASCII 127) to substitute
578 var $entsubstitute; // Array of substitution decimal unicode for the Hi entities
581 // Default values if no style sheet offered (cf. http://www.w3.org/TR/CSS21/sample.html)
584 var $linemaxfontsize;
585 var $lineheight_correction;
586 var $lastoptionaltag; // Save current block item which HTML specifies optionsl endtag
592 var $ws; // Word spacing
599 var $U; //underlining flag
600 var $S; // SmallCaps flag
625 var $ignorefollowingspaces;
638 var $currentfontstyle;
639 var $currentfontfamily;
640 var $currentfontsize;
662 var $divbuffer; // Buffer used when keeping DIV on one page
663 var $keep_block_together; // Keep a Block from page-break-inside: avoid
664 var $ktLinks; // Keep-together Block links array
665 var $ktBlock; // Keep-together Block array
679 var $extgstates; // Used for alpha channel - Transparency (Watermark)
692 // Best to alter the below variables using default stylesheet above
693 var $page_break_after_avoid;
694 var $margin_bottom_collapse;
697 var $list_margin_bottom;
698 var $default_font_size; // in pts
699 var $original_default_font_size; // used to save default sizes when using table default
700 var $original_default_font;
705 var $defaultTableAlign;
707 var $thead_font_weight;
708 var $thead_font_style;
709 var $thead_font_smCaps;
710 var $thead_valign_default;
711 var $thead_textalign_default;
713 var $tfoot_font_weight;
714 var $tfoot_font_style;
715 var $tfoot_font_smCaps;
716 var $tfoot_valign_default;
717 var $tfoot_textalign_default;
719 var $trow_text_rotate;
725 var $table_lineheight;
726 var $table_border_attr_set;
727 var $table_border_css_set;
729 var $shrin_k; // factor with which to shrink tables - used internally - do not change
730 var $shrink_this_table_to_fit; // 0 or false to disable; value (if set) gives maximum factor to reduce fontsize
731 var $MarginCorrection; // corrects for OddEven Margins
735 var $tabletheadjustfinished;
739 //Private properties FROM FPDF
740 var $DisplayPreferences;
741 var $flowingBlockAttr;
742 var $page; //current page number
743 var $n; //current object number
744 var $offsets; //array of object offsets
745 var $buffer; //buffer holding in-memory PDF
746 var $pages; //array containing pages
747 var $state; //current document state
748 var $compress; //compression flag
749 var $DefOrientation; //default orientation
750 var $CurOrientation; //current orientation
751 var $OrientationChanges; //array indicating orientation changes
752 var $k; //scale factor (number of points in user unit)
754 var $fhPt; //dimensions of page format in points
756 var $fh; //dimensions of page format in user unit
758 var $hPt; //current dimensions of page in points
760 var $h; //current dimensions of page in user unit
761 var $lMargin; //left margin
762 var $tMargin; //top margin
763 var $rMargin; //right margin
764 var $bMargin; //page break margin
765 var $cMarginL; //cell margin Left
766 var $cMarginR; //cell margin Right
767 var $cMarginT; //cell margin Left
768 var $cMarginB; //cell margin Right
769 var $DeflMargin; //Default left margin
770 var $DefrMargin; //Default right margin
772 var $y; //current position in user unit for cell positioning
773 var $lasth; //height of last cell printed
774 var $LineWidth; //line width in user unit
775 var $CoreFonts; //array of standard font names
776 var $fonts; //array of used fonts
777 var $FontFiles; //array of font files
778 var $images; //array of used images
779 var $PageLinks; //array of links in pages
780 var $links; //array of internal links
781 var $FontFamily; //current font family
782 var $FontStyle; //current font style
783 var $CurrentFont; //current font info
784 var $FontSizePt; //current font size in points
785 var $FontSize; //current font size in user unit
786 var $DrawColor; //commands for drawing color
787 var $FillColor; //commands for filling color
788 var $TextColor; //commands for text color
789 var $ColorFlag; //indicates whether fill and text colors are different
790 var $autoPageBreak; //automatic page breaking
791 var $PageBreakTrigger; //threshold used to trigger page breaks
792 var $InFooter; //flag set when processing footer
795 var $processingFooter; //flag set when processing footer - added for columns
796 var $processingHeader; //flag set when processing header - added for columns
797 var $ZoomMode; //zoom display mode
798 var $LayoutMode; //layout display mode
800 var $subject; //subject
801 var $author; //author
802 var $keywords; //keywords
803 var $creator; //creator
805 var $aliasNbPg; //alias for total number of pages
806 var $aliasNbPgGp; //alias for total number of pages in page group
816 // **********************************
817 // **********************************
818 // **********************************
819 // **********************************
820 // **********************************
821 // **********************************
822 // **********************************
823 // **********************************
824 // **********************************
826 function mPDF($mode='',$format='A4',$default_font_size=0,$default_font='',$mgl=15,$mgr=15,$mgt=16,$mgb=16,$mgh=9,$mgf=9, $orientation='P') {
828 /*-- BACKGROUNDS --*/
829 if (!class_exists('grad', false)) { include(_MPDF_PATH
.'classes/grad.php'); }
830 if (empty($this->grad
)) { $this
->grad
= new grad($this
); }
831 /*-- END BACKGROUNDS --*/
833 if (!class_exists('form', false)) { include(_MPDF_PATH
.'classes/form.php'); }
834 if (empty($this->form
)) { $this
->form
= new form($this
); }
837 $this->time0
= microtime(true);
841 // Set up Aliases for backwards compatability
842 $this->UnvalidatedText
=& $this->watermarkText
;
843 $this->TopicIsUnvalidated
=& $this->showWatermarkText
;
844 $this->AliasNbPg
=& $this->aliasNbPg
;
845 $this->AliasNbPgGp
=& $this->aliasNbPgGp
;
846 $this->BiDirectional
=& $this->biDirectional
;
847 $this->Anchor2Bookmark
=& $this->anchor2Bookmark
;
848 $this->KeepColumns
=& $this->keepColumns
;
849 $this->useOddEven
=& $this->mirrorMargins
;
850 $this->useSubstitutionsMB
=& $this->useSubstitutions
;
852 $this->writingToC
= false; // mPDF 5.6.38
854 $this->layers
= array();
855 $this->current_layer
= 0;
856 $this->open_layer_pane
= false;
858 $this->visibility
='visible';
860 //Initialization of properties
861 $this->spotColors
=array();
862 $this->spotColorIDs
= array();
863 $this->tableBackgrounds
= array();
867 $this->iterationCounter
= false;
868 $this->BMPonly
= array();
872 $this->objectbuffer
= array();
873 $this->pages
=array();
874 $this->OrientationChanges
=array();
876 $this->fonts
=array();
877 $this->FontFiles
=array();
878 $this->images
=array();
879 $this->links
=array();
880 $this->InFooter
=false;
881 $this->processingFooter
=false;
882 $this->processingHeader
=false;
884 $this->FontFamily
='';
889 $this->upperCase
= array();
891 $this->smCapsScale
= 1;
892 $this->smCapsStretch
= 100;
893 $this->margBuffer
= 0; // mPDF 5.4.04
894 $this->inMeter
= false; // mPDF 5.5.09
895 $this->decimal_offset
= 0;
897 $this->defTextColor
= $this->TextColor
= $this->SetTColor($this->ConvertColor(0),true);
898 $this->defDrawColor
= $this->DrawColor
= $this->SetDColor($this->ConvertColor(0),true);
899 $this->defFillColor
= $this->FillColor
= $this->SetFColor($this->ConvertColor(255),true);
901 //SVG color names array
902 //http://www.w3schools.com/css/css_colornames.asp
903 $this->SVGcolors
= array('antiquewhite'=>'#FAEBD7','aqua'=>'#00FFFF','aquamarine'=>'#7FFFD4','beige'=>'#F5F5DC','black'=>'#000000',
904 'blue'=>'#0000FF','brown'=>'#A52A2A','cadetblue'=>'#5F9EA0','chocolate'=>'#D2691E','cornflowerblue'=>'#6495ED','crimson'=>'#DC143C',
905 'darkblue'=>'#00008B','darkgoldenrod'=>'#B8860B','darkgreen'=>'#006400','darkmagenta'=>'#8B008B','darkorange'=>'#FF8C00',
906 'darkred'=>'#8B0000','darkseagreen'=>'#8FBC8F','darkslategray'=>'#2F4F4F','darkviolet'=>'#9400D3','deepskyblue'=>'#00BFFF',
907 'dodgerblue'=>'#1E90FF','firebrick'=>'#B22222','forestgreen'=>'#228B22','fuchsia'=>'#FF00FF','gainsboro'=>'#DCDCDC','gold'=>'#FFD700',
908 'gray'=>'#808080','green'=>'#008000','greenyellow'=>'#ADFF2F','hotpink'=>'#FF69B4','indigo'=>'#4B0082','khaki'=>'#F0E68C',
909 'lavenderblush'=>'#FFF0F5','lemonchiffon'=>'#FFFACD','lightcoral'=>'#F08080','lightgoldenrodyellow'=>'#FAFAD2','lightgreen'=>'#90EE90',
910 'lightsalmon'=>'#FFA07A','lightskyblue'=>'#87CEFA','lightslategray'=>'#778899','lightyellow'=>'#FFFFE0','lime'=>'#00FF00','limegreen'=>'#32CD32',
911 'magenta'=>'#FF00FF','maroon'=>'#800000','mediumaquamarine'=>'#66CDAA','mediumorchid'=>'#BA55D3','mediumseagreen'=>'#3CB371',
912 'mediumspringgreen'=>'#00FA9A','mediumvioletred'=>'#C71585','midnightblue'=>'#191970','mintcream'=>'#F5FFFA','moccasin'=>'#FFE4B5','navy'=>'#000080',
913 'olive'=>'#808000','orange'=>'#FFA500','orchid'=>'#DA70D6','palegreen'=>'#98FB98',
914 'palevioletred'=>'#D87093','peachpuff'=>'#FFDAB9','pink'=>'#FFC0CB','powderblue'=>'#B0E0E6','purple'=>'#800080',
915 'red'=>'#FF0000','royalblue'=>'#4169E1','salmon'=>'#FA8072','seagreen'=>'#2E8B57','sienna'=>'#A0522D','silver'=>'#C0C0C0','skyblue'=>'#87CEEB',
916 'slategray'=>'#708090','springgreen'=>'#00FF7F','steelblue'=>'#4682B4','tan'=>'#D2B48C','teal'=>'#008080','thistle'=>'#D8BFD8','turquoise'=>'#40E0D0',
917 'violetred'=>'#D02090','white'=>'#FFFFFF','yellow'=>'#FFFF00',
918 'aliceblue'=>'#f0f8ff', 'azure'=>'#f0ffff', 'bisque'=>'#ffe4c4', 'blanchedalmond'=>'#ffebcd', 'blueviolet'=>'#8a2be2', 'burlywood'=>'#deb887',
919 'chartreuse'=>'#7fff00', 'coral'=>'#ff7f50', 'cornsilk'=>'#fff8dc', 'cyan'=>'#00ffff', 'darkcyan'=>'#008b8b', 'darkgray'=>'#a9a9a9',
920 'darkgrey'=>'#a9a9a9', 'darkkhaki'=>'#bdb76b', 'darkolivegreen'=>'#556b2f', 'darkorchid'=>'#9932cc', 'darksalmon'=>'#e9967a',
921 'darkslateblue'=>'#483d8b', 'darkslategrey'=>'#2f4f4f', 'darkturquoise'=>'#00ced1', 'deeppink'=>'#ff1493', 'dimgray'=>'#696969',
922 'dimgrey'=>'#696969', 'floralwhite'=>'#fffaf0', 'ghostwhite'=>'#f8f8ff', 'goldenrod'=>'#daa520', 'grey'=>'#808080', 'honeydew'=>'#f0fff0',
923 'indianred'=>'#cd5c5c', 'ivory'=>'#fffff0', 'lavender'=>'#e6e6fa', 'lawngreen'=>'#7cfc00', 'lightblue'=>'#add8e6', 'lightcyan'=>'#e0ffff',
924 'lightgray'=>'#d3d3d3', 'lightgrey'=>'#d3d3d3', 'lightpink'=>'#ffb6c1', 'lightseagreen'=>'#20b2aa', 'lightslategrey'=>'#778899',
925 'lightsteelblue'=>'#b0c4de', 'linen'=>'#faf0e6', 'mediumblue'=>'#0000cd', 'mediumpurple'=>'#9370db', 'mediumslateblue'=>'#7b68ee',
926 'mediumturquoise'=>'#48d1cc', 'mistyrose'=>'#ffe4e1', 'navajowhite'=>'#ffdead', 'oldlace'=>'#fdf5e6', 'olivedrab'=>'#6b8e23', 'orangered'=>'#ff4500',
927 'palegoldenrod'=>'#eee8aa', 'paleturquoise'=>'#afeeee', 'papayawhip'=>'#ffefd5', 'peru'=>'#cd853f', 'plum'=>'#dda0dd', 'rosybrown'=>'#bc8f8f',
928 'saddlebrown'=>'#8b4513', 'sandybrown'=>'#f4a460', 'seashell'=>'#fff5ee', 'slateblue'=>'#6a5acd', 'slategrey'=>'#708090', 'snow'=>'#fffafa',
929 'tomato'=>'#ff6347', 'violet'=>'#ee82ee', 'wheat'=>'#f5deb3', 'whitesmoke'=>'#f5f5f5', 'yellowgreen'=>'#9acd32');
931 $this->ColorFlag
=false;
932 $this->extgstates
= array();
934 $this->mb_enc
='windows-1252';
935 $this->directionality
='ltr';
936 $this->defaultAlign
= 'L';
937 $this->defaultTableAlign
= 'L';
939 $this->fixedPosBlockSave
= array();
940 $this->extraFontSubsets
= 0;
942 $this->SHYpatterns
= array();
943 $this->loadedSHYdictionary
= false;
944 $this->SHYdictionary
= array();
945 $this->SHYdictionaryWords
= array();
946 $this->blockContext
= 1;
947 $this->floatDivs
= array();
948 $this->DisplayPreferences
='';
950 $this->patterns
= array(); // Tiling patterns used for backgrounds
951 $this->pageBackgrounds
= array();
952 $this->writingHTMLheader
= false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
953 $this->writingHTMLfooter
= false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
954 $this->gradients
= array();
956 $this->kwt_Reference
= array();
957 $this->kwt_BMoutlines
= array();
958 $this->kwt_toc
= array();
960 $this->tbrot_Reference
= array();
961 $this->tbrot_BMoutlines
= array();
962 $this->tbrot_toc
= array();
964 $this->col_Reference
= array();
965 $this->col_BMoutlines
= array();
966 $this->col_toc
= array();
967 $this->graphs
= array();
969 $this->pgsIns
= array();
970 $this->PDFAXwarnings
= array();
971 $this->inlineDisplayOff
= false;
972 $this->kerning
= false;
973 $this->lSpacingCSS
= '';
974 $this->wSpacingCSS
= '';
975 $this->fixedlSpacing
= false;
976 $this->minwSpacing
= 0;
979 $this->baselineC
= 0.35; // Baseline for text
980 $this->noImageFile
= str_replace("\\","/",dirname(__FILE__
)) . '/includes/no_image.jpg';
982 $this->forceExactLineheight
= false;
984 $this->normalLineheight
= 1.3;
985 // These are intended as configuration variables, and should be set in config.php - which will override these values;
986 // set here as failsafe as will cause an error if not defined
987 $this->incrementFPR1
= 10;
988 $this->incrementFPR2
= 10;
989 $this->incrementFPR3
= 10;
990 $this->incrementFPR4
= 10;
992 $this->fullImageHeight
= false;
993 $this->floatbuffer
= array();
994 $this->floatmargins
= array();
995 $this->autoFontGroups
= 0;
996 $this->formobjects
=array(); // array of Form Objects for WMF
997 $this->InlineProperties
=array();
998 $this->InlineAnnots
=array();
999 $this->ktAnnots
=array();
1000 $this->tbrot_Annots
=array();
1001 $this->kwt_Annots
=array();
1002 $this->columnAnnots
=array();
1003 $this->pageDim
=array();
1004 $this->breakpoints
= array(); // used in columnbuffer
1005 $this->tableLevel
=0;
1006 $this->tbctr
=array(); // counter for nested tables at each level
1007 $this->page_box
= array();
1008 $this->show_marks
= ''; // crop or cross marks
1010 $this->kwt_height
= 0;
1013 $this->kwt_buffer
= array();
1014 $this->kwt_Links
= array();
1015 $this->kwt_moved
= false;
1016 $this->kwt_saved
= false;
1017 $this->PageNumSubstitutions
= array();
1018 $this->base_table_properties
=array();
1019 $this->borderstyles
= array('inset','groove','outset','ridge','dotted','dashed','solid','double');
1020 $this->tbrot_align
= 'C';
1021 $this->pageheaders
=array();
1022 $this->pagefooters
=array();
1024 $this->pageHTMLheaders
=array();
1025 $this->pageHTMLfooters
=array();
1026 $this->HTMLheaderPageLinks
= array();
1027 $this->HTMLheaderPageAnnots
= array();
1029 $this->ktForms
= array();
1030 $this->HTMLheaderPageForms
= array();
1031 $this->columnForms
= array();
1032 $this->tbrotForms
= array();
1033 $this->useRC128encryption
= false;
1036 $this->bufferoutput
= false;
1037 $this->encrypted
=false; //whether document is protected
1038 $this->BMoutlines
=array();
1039 $this->ColActive
=0; //Flag indicating that columns are on (the index is being processed)
1040 $this->Reference
=array(); //Array containing the references
1041 $this->CurrCol
=0; //Current column number
1042 $this->ColL
= array(0); // Array of Left pos of columns - absolute - needs Margin correction for Odd-Even
1043 $this->ColR
= array(0); // Array of Right pos of columns - absolute pos - needs Margin correction for Odd-Even
1044 $this->ChangeColumn
= 0;
1045 $this->columnbuffer
= array();
1046 $this->ColDetails
= array(); // Keeps track of some column details
1047 $this->columnLinks
= array(); // Cross references PageLinks
1048 $this->substitute
= array(); // Array of substitution strings e.g. <ttz>112</ttz>
1049 $this->entsearch
= array(); // Array of HTML entities (>ASCII 127) to substitute
1050 $this->entsubstitute
= array(); // Array of substitution decimal unicode for the Hi entities
1051 $this->lastoptionaltag
= '';
1052 $this->charset_in
= '';
1053 $this->blk
= array();
1060 $this->checkSIP
= false;
1061 $this->checkSMP
= false;
1062 $this->checkCJK
= false;
1063 $this->tableCJK
= false;
1065 $this->headerDetails
=array();
1066 $this->footerDetails
=array();
1067 $this->page_break_after_avoid
= false;
1068 $this->margin_bottom_collapse
= false;
1069 $this->tablethead
= 0;
1070 $this->tabletfoot
= 0;
1071 $this->table_border_attr_set
= 0;
1072 $this->table_border_css_set
= 0;
1073 $this->shrin_k
= 1.0;
1074 $this->shrink_this_table_to_fit
= 0;
1075 $this->MarginCorrection
= 0;
1077 $this->tabletheadjustfinished
= false;
1078 $this->usingCoreFont
= false;
1079 $this->charspacing
=0;
1081 $this->autoPageBreak
= true;
1083 require(_MPDF_PATH
.'config.php'); // config data
1085 $this->_setPageSize($format, $orientation);
1086 $this->DefOrientation
=$orientation;
1088 $this->margin_header
=$mgh;
1089 $this->margin_footer
=$mgf;
1093 $this->DeflMargin
= $mgl;
1094 $this->DefrMargin
= $mgr;
1096 $this->orig_tMargin
= $mgt;
1097 $this->orig_bMargin
= $bmargin;
1098 $this->orig_lMargin
= $this->DeflMargin
;
1099 $this->orig_rMargin
= $this->DefrMargin
;
1100 $this->orig_hMargin
= $this->margin_header
;
1101 $this->orig_fMargin
= $this->margin_footer
;
1103 if ($this->setAutoTopMargin
=='pad') { $mgt +
= $this
->margin_header
; }
1104 if ($this->setAutoBottomMargin
=='pad') { $mgb +
= $this
->margin_footer
; }
1105 $this->SetMargins($this->DeflMargin
,$this->DefrMargin
,$mgt); // sets l r t margin
1106 //Automatic page break
1107 $this->SetAutoPageBreak($this->autoPageBreak
,$bmargin); // sets $this->bMargin & PageBreakTrigger
1109 $this->pgwidth
= $this->w
- $this->lMargin
- $this->rMargin
;
1111 //Interior cell margin (1 mm) ? not used
1112 $this->cMarginL
= 1;
1113 $this->cMarginR
= 1;
1114 //Line width (0.2 mm)
1115 $this->LineWidth
=.567/_MPDFK
;
1117 //To make the function Footer() work - replaces {nb} with page number
1118 $this->AliasNbPages();
1119 $this->AliasNbPageGroups();
1121 $this->aliasNbPgHex
= '{nbHEXmarker}';
1122 $this->aliasNbPgGpHex
= '{nbpgHEXmarker}';
1124 //Enable all tags as default
1125 $this->DisableTags();
1126 //Full width display mode
1127 $this->SetDisplayMode(100); // fullwidth? 'fullpage'
1129 $this->SetCompression(true);
1130 //Set default display preferences
1131 $this->SetDisplayPreferences('');
1134 require(_MPDF_PATH
.'config_fonts.php');
1136 $this->available_unifonts
= array();
1137 foreach ($this->fontdata
AS $f => $fs) {
1138 if (isset($fs['R']) && $fs['R']) { $this
->available_unifonts
[] = $f
; }
1139 if (isset($fs['B']) && $fs['B']) { $this
->available_unifonts
[] = $f
.'B'; }
1140 if (isset($fs['I']) && $fs['I']) { $this
->available_unifonts
[] = $f
.'I'; }
1141 if (isset($fs['BI']) && $fs['BI']) { $this
->available_unifonts
[] = $f
.'BI'; }
1144 $this->default_available_fonts
= $this->available_unifonts
;
1147 $onlyCoreFonts = false;
1148 if (preg_match('/([\-+])aCJK/i',$mode, $m)) {
1149 preg_replace('/([\-+])aCJK/i','',$mode);
1150 if ($m[1]=='+') { $this
->useAdobeCJK
= true; }
1151 else { $this
->useAdobeCJK
= false; }
1154 if (strlen($mode)==1) {
1155 if ($mode=='s') { $this
->percentSubset
= 100; $mode
= ''; }
1156 else if ($mode=='c') { $onlyCoreFonts
= true; $mode
= ''; }
1158 else if (substr($mode,-2)=='-s') {
1159 $this->percentSubset
= 100;
1160 $mode = substr($mode,0,strlen($mode)-2);
1162 else if (substr($mode,-2)=='-c') {
1163 $onlyCoreFonts = true;
1164 $mode = substr($mode,0,strlen($mode)-2);
1166 else if (substr($mode,-2)=='-x') {
1168 $mode = substr($mode,0,strlen($mode)-2);
1171 // Autodetect if mode is a language_country string (en-GB or en_GB or en)
1172 if ((strlen($mode) == 5 && $mode != 'UTF-8') || strlen($mode) == 2) {
1173 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($mode, $this->useAdobeCJK
);
1174 if ($coreSuitable && $optcore) { $onlyCoreFonts
= true; }
1175 if ($mpdf_pdf_unifonts) {
1176 $this->RestrictUnicodeFonts($mpdf_pdf_unifonts);
1177 $this->default_available_fonts
= $mpdf_pdf_unifonts;
1179 $this->currentLang
= $mode;
1180 $this->default_lang
= $mode;
1183 $this->onlyCoreFonts
= $onlyCoreFonts;
1185 if ($this->onlyCoreFonts
) {
1186 $this->setMBencoding('windows-1252'); // sets $this->mb_enc
1189 $this->setMBencoding('UTF-8'); // sets $this->mb_enc
1191 @mb_regex_encoding('UTF-8'); // required only for mb_ereg... and mb_split functions
1195 $this->available_CJK_fonts
= array('gb','big5','sjis','uhc','gbB','big5B','sjisB','uhcB','gbI','big5I','sjisI','uhcI',
1196 'gbBI','big5BI','sjisBI','uhcBI');
1200 $this->CoreFonts
=array('ccourier'=>'Courier','ccourierB'=>'Courier-Bold','ccourierI'=>'Courier-Oblique','ccourierBI'=>'Courier-BoldOblique',
1201 'chelvetica'=>'Helvetica','chelveticaB'=>'Helvetica-Bold','chelveticaI'=>'Helvetica-Oblique','chelveticaBI'=>'Helvetica-BoldOblique',
1202 'ctimes'=>'Times-Roman','ctimesB'=>'Times-Bold','ctimesI'=>'Times-Italic','ctimesBI'=>'Times-BoldItalic',
1203 'csymbol'=>'Symbol','czapfdingbats'=>'ZapfDingbats');
1204 $this->fontlist
=array("ctimes","ccourier","chelvetica","csymbol","czapfdingbats");
1207 $this->setHiEntitySubstitutions();
1209 if ($this->onlyCoreFonts
) {
1210 $this->useSubstitutions
= true;
1211 $this->SetSubstitutions();
1213 else { $this
->useSubstitutions
= false; }
1217 if (!class_exists('cssmgr', false)) { include(_MPDF_PATH
.'classes/cssmgr.php'); }
1218 $this->cssmgr
= new cssmgr($this);
1219 if (file_exists(_MPDF_PATH
.'mpdf.css')) {
1220 $css = file_get_contents(_MPDF_PATH
.'mpdf.css');
1221 $css2 = $this->cssmgr
->ReadDefaultCSS($css);
1222 $this->defaultCSS
= $this->cssmgr
->array_merge_recursive_unique($this->defaultCSS
,$css2);
1224 /*-- END HTML-CSS --*/
1226 if ($default_font=='') {
1227 if ($this->onlyCoreFonts
) {
1228 if (in_array(strtolower($this->defaultCSS
['BODY']['FONT-FAMILY']),$this->mono_fonts
)) { $default_font
= 'ccourier'; }
1229 else if (in_array(strtolower($this->defaultCSS
['BODY']['FONT-FAMILY']),$this->sans_fonts
)) { $default_font
= 'chelvetica'; }
1230 else { $default_font
= 'ctimes'; }
1232 else { $default_font
= $this
->defaultCSS
['BODY']['FONT-FAMILY']; }
1234 if (!$default_font_size) {
1235 $mmsize = $this->ConvertSize($this->defaultCSS
['BODY']['FONT-SIZE']);
1236 $default_font_size = $mmsize*(_MPDFK
);
1239 if ($default_font) { $this
->SetDefaultFont($default_font
); }
1240 if ($default_font_size) { $this
->SetDefaultFontSize($default_font_size
); }
1242 $this->SetLineHeight(); // lineheight is in mm
1244 $this->SetFColor($this->ConvertColor(255));
1255 $this->listoccur
=array();
1256 $this->listlist
=array();
1257 $this->listitem
=array();
1259 $this->tdbegin
=false;
1260 $this->table
=array();
1261 $this->cell
=array();
1264 $this->cellBorderBuffer
= array();
1266 $this->divbegin
=false;
1270 $this->spanbgcolor
=false;
1271 $this->divrevert
=false;
1272 $this->spanborder
=false;
1273 $this->spanborddet
=array();
1275 $this->blockjustfinished
=false;
1276 $this->listjustfinished
=false;
1277 $this->ignorefollowingspaces
= true; //in order to eliminate exceeding left-side spaces
1278 $this->toupper
=false;
1279 $this->tolower
=false;
1280 $this->capitalize
=false;
1281 $this->dash_on
=false;
1282 $this->dotted_on
=false;
1285 $this->strike
=false;
1286 $this->textshadow
='';
1288 $this->currentfontfamily
='';
1289 $this->currentfontsize
='';
1290 $this->currentfontstyle
='';
1291 $this->colorarray
=array();
1292 $this->spanbgcolorarray
=array();
1293 $this->textbuffer
=array();
1294 $this->internallink
=array();
1295 $this->basepath
= "";
1297 $this->SetBasePath('');
1299 $this->textparam
= array();
1301 $this->specialcontent
= '';
1302 $this->selectoption
= array();
1306 $this->tpls
= array();
1308 $this->tplprefix
= "/TPL";
1309 $this->res
= array();
1310 if ($this->enableImports
) {
1311 $this->SetImportUse();
1313 /*-- END IMPORTS --*/
1315 if ($this->progressBar
) { $this
->StartProgressBarOutput($this
->progressBar
) ; } // *PROGRESS-BAR*
1319 function _setPageSize($format, &$orientation) {
1321 if(is_string($format))
1323 if ($format=='') { $format
= 'A4'; }
1325 if(preg_match('/([0-9a-zA-Z]*)-L/i',$format,$m)) { // e.g. A4-L = A4 landscape
1329 $format = $this->_getPageFormat($format);
1330 if (!$format) { $this
->Error('Unknown page format: '.$format
); }
1331 else { $orientation
= $pfo
; }
1333 $this->fwPt
=$format[0];
1334 $this->fhPt
=$format[1];
1338 if (!$format[0] || !$format[1]) { $this
->Error('Invalid page format: '.$format
[0].' '.$format
[1]); }
1339 $this->fwPt
=$format[0]*_MPDFK
;
1340 $this->fhPt
=$format[1]*_MPDFK
;
1342 $this->fw
=$this->fwPt
/_MPDFK
;
1343 $this->fh
=$this->fhPt
/_MPDFK
;
1345 $orientation=strtolower($orientation);
1346 if($orientation=='p' or $orientation=='portrait')
1349 $this->wPt
=$this->fwPt
;
1350 $this->hPt
=$this->fhPt
;
1352 elseif($orientation=='l' or $orientation=='landscape')
1355 $this->wPt
=$this->fhPt
;
1356 $this->hPt
=$this->fwPt
;
1358 else $this->Error('Incorrect orientation: '.$orientation);
1359 $this->CurOrientation
=$orientation;
1361 $this->w
=$this->wPt
/_MPDFK
;
1362 $this->h
=$this->hPt
/_MPDFK
;
1365 function _getPageFormat($format) {
1366 switch (strtoupper($format)) {
1367 case '4A0': {$format
= array(4767.87,6740.79); break;}
1368 case '2A0': {$format
= array(3370.39,4767.87); break;}
1369 case 'A0': {$format
= array(2383.94,3370.39); break;}
1370 case 'A1': {$format
= array(1683.78,2383.94); break;}
1371 case 'A2': {$format
= array(1190.55,1683.78); break;}
1372 case 'A3': {$format
= array(841.89,1190.55); break;}
1373 case 'A4': default: {$format
= array(595.28,841.89); break;}
1374 case 'A5': {$format
= array(419.53,595.28); break;}
1375 case 'A6': {$format
= array(297.64,419.53); break;}
1376 case 'A7': {$format
= array(209.76,297.64); break;}
1377 case 'A8': {$format
= array(147.40,209.76); break;}
1378 case 'A9': {$format
= array(104.88,147.40); break;}
1379 case 'A10': {$format
= array(73.70,104.88); break;}
1380 case 'B0': {$format
= array(2834.65,4008.19); break;}
1381 case 'B1': {$format
= array(2004.09,2834.65); break;}
1382 case 'B2': {$format
= array(1417.32,2004.09); break;}
1383 case 'B3': {$format
= array(1000.63,1417.32); break;}
1384 case 'B4': {$format
= array(708.66,1000.63); break;}
1385 case 'B5': {$format
= array(498.90,708.66); break;}
1386 case 'B6': {$format
= array(354.33,498.90); break;}
1387 case 'B7': {$format
= array(249.45,354.33); break;}
1388 case 'B8': {$format
= array(175.75,249.45); break;}
1389 case 'B9': {$format
= array(124.72,175.75); break;}
1390 case 'B10': {$format
= array(87.87,124.72); break;}
1391 case 'C0': {$format
= array(2599.37,3676.54); break;}
1392 case 'C1': {$format
= array(1836.85,2599.37); break;}
1393 case 'C2': {$format
= array(1298.27,1836.85); break;}
1394 case 'C3': {$format
= array(918.43,1298.27); break;}
1395 case 'C4': {$format
= array(649.13,918.43); break;}
1396 case 'C5': {$format
= array(459.21,649.13); break;}
1397 case 'C6': {$format
= array(323.15,459.21); break;}
1398 case 'C7': {$format
= array(229.61,323.15); break;}
1399 case 'C8': {$format
= array(161.57,229.61); break;}
1400 case 'C9': {$format
= array(113.39,161.57); break;}
1401 case 'C10': {$format
= array(79.37,113.39); break;}
1402 case 'RA0': {$format
= array(2437.80,3458.27); break;}
1403 case 'RA1': {$format
= array(1729.13,2437.80); break;}
1404 case 'RA2': {$format
= array(1218.90,1729.13); break;}
1405 case 'RA3': {$format
= array(864.57,1218.90); break;}
1406 case 'RA4': {$format
= array(609.45,864.57); break;}
1407 case 'SRA0': {$format
= array(2551.18,3628.35); break;}
1408 case 'SRA1': {$format
= array(1814.17,2551.18); break;}
1409 case 'SRA2': {$format
= array(1275.59,1814.17); break;}
1410 case 'SRA3': {$format
= array(907.09,1275.59); break;}
1411 case 'SRA4': {$format
= array(637.80,907.09); break;}
1412 case 'LETTER': {$format
= array(612.00,792.00); break;}
1413 case 'LEGAL': {$format
= array(612.00,1008.00); break;}
1414 case 'LEDGER': {$format
= array(279.00,432.00); break;}
1415 case 'TABLOID': {$format
= array(279.00,432.00); break;}
1416 case 'EXECUTIVE': {$format
= array(521.86,756.00); break;}
1417 case 'FOLIO': {$format
= array(612.00,936.00); break;}
1418 case 'B': {$format
=array(362.83,561.26 ); break;} // 'B' format paperback size 128x198mm
1419 case 'A': {$format
=array(314.65,504.57 ); break;} // 'A' format paperback size 111x178mm
1420 case 'DEMY': {$format
=array(382.68,612.28 ); break;} // 'Demy' format paperback size 135x216mm
1421 case 'ROYAL': {$format
=array(433.70,663.30 ); break;} // 'Royal' format paperback size 153x234mm
1422 default: $format = false;
1428 /*-- PROGRESS-BAR --*/
1429 function StartProgressBarOutput($mode=1) {
1430 // must be relative path, or URI (not a file system path)
1431 if (!defined('_MPDF_URI')) {
1432 $this->progressBar
= false;
1433 if ($this->debug
) { $this
->Error("You need to define _MPDF_URI to use the progress bar!"); }
1436 $this->progressBar
= $mode;
1437 if ($this->progbar_altHTML
) {
1438 echo $this->progbar_altHTML
;
1443 <title>mPDF File Progress</title>
1444 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1445 <link rel="stylesheet" type="text/css" href="'._MPDF_URI
.'progbar.css" />
1449 <div class="heading">'.$this->progbar_heading
.'</div>
1452 if ($this->progressBar
==2) { echo ' <table width="100%"><tr><td style="width: 50%;">
1453 <span class="barheading">Writing HTML code</span> <br/>
1455 <div class="progressBar">
1456 <div id="element1" class="innerBar"> </div>
1458 <span class="code" id="box1"></span>
1459 </td><td style="width: 50%;">
1460 <span class="barheading">Autosizing elements</span> <br/>
1461 <div class="progressBar">
1462 <div id="element4" class="innerBar"> </div>
1464 <span class="code" id="box4"></span>
1466 <span class="barheading">Writing Tables</span> <br/>
1467 <div class="progressBar">
1468 <div id="element7" class="innerBar"> </div>
1470 <span class="code" id="box7"></span>
1472 <tr><td><br /><br /></td><td></td></tr>
1473 <tr><td style="width: 50%;">
1475 echo ' <span class="barheading">Writing PDF file</span> <br/>
1476 <div class="progressBar">
1477 <div id="element2" class="innerBar"> </div>
1479 <span class="code" id="box2"></span>
1481 if ($this->progressBar
==2) { echo '
1482 </td><td style="width: 50%;">
1483 <span class="barheading">Memory usage</span> <br/>
1484 <div class="progressBar">
1485 <div id="element5" class="innerBar"> </div>
1487 <span id="box5">0</span> '.ini_get("memory_limit").'<br />
1489 <span class="barheading">Memory usage (peak)</span> <br/>
1490 <div class="progressBar">
1491 <div id="element6" class="innerBar"> </div>
1493 <span id="box6">0</span> '.ini_get("memory_limit").'<br />
1498 <span id="box3"></span>
1507 function UpdateProgressBar($el,$val,$txt='') {
1508 // $val should be a string - 5 = actual value, +15 = increment
1510 if ($this->progressBar
<2) {
1511 if ($el>3) { return; }
1512 else if ($el ==1) { $el
= 2; }
1514 echo '<script type="text/javascript">';
1515 if ($val) { echo ' document.getElementById(\'element'.$el
.'\').style.width=\''.$val
.'%\'; '; }
1516 if ($txt) { echo ' document.getElementById(\'box'.$el
.'\').innerHTML=\''.$txt
.'\'; '; }
1517 if ($this->progressBar
==2) {
1518 $m = round(memory_get_usage(true)/1048576);
1519 $m2 = round(memory_get_peak_usage(true)/1048576);
1520 $mem = $m * 100 / (ini_get("memory_limit")+
0);
1521 $mem2 = $m2 * 100 / (ini_get("memory_limit")+
0);
1522 echo ' document.getElementById(\'element5\').style.width=\''.$mem.'%\'; ';
1523 echo ' document.getElementById(\'element6\').style.width=\''.$mem2.'%\'; ';
1524 echo ' document.getElementById(\'box5\').innerHTML=\''.$m.'MB / \'; ';
1525 echo ' document.getElementById(\'box6\').innerHTML=\''.$m2.'MB / \'; ';
1527 echo '</script>'."\n";
1531 /*-- END PROGRESS-BAR --*/
1535 function RestrictUnicodeFonts($res) {
1536 // $res = array of (Unicode) fonts to restrict to: e.g. norasi|norasiB - language specific
1537 if (count($res)) { // Leave full list of available fonts if passed blank array
1538 $this->available_unifonts
= $res;
1540 else { $this
->available_unifonts
= $this
->default_available_fonts
; }
1541 if (count($this->available_unifonts
) == 0) { $this
->available_unifonts
[] = $this
->default_available_fonts
[0]; }
1542 $this->available_unifonts
= array_values($this->available_unifonts
);
1546 function setMBencoding($enc) {
1547 if ($this->mb_enc
!= $enc) {
1548 $this->mb_enc
= $enc;
1549 mb_internal_encoding($this->mb_enc
);
1554 function SetMargins($left,$right,$top) {
1555 //Set left, top and right margins
1556 $this->lMargin
=$left;
1557 $this->rMargin
=$right;
1558 $this->tMargin
=$top;
1561 function ResetMargins() {
1562 //ReSet left, top margins
1563 if (($this->forcePortraitHeaders
|| $this->forcePortraitMargins
) && $this->DefOrientation
=='P' && $this->CurOrientation
=='L') {
1564 if (($this->mirrorMargins
) && (($this->page
)%
2==0)) { // EVEN
1565 $this->tMargin
=$this->orig_rMargin
;
1566 $this->bMargin
=$this->orig_lMargin
;
1568 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS
1569 $this->tMargin
=$this->orig_lMargin
;
1570 $this->bMargin
=$this->orig_rMargin
;
1572 $this->lMargin
=$this->DeflMargin
;
1573 $this->rMargin
=$this->DefrMargin
;
1574 $this->MarginCorrection
= 0;
1575 $this->PageBreakTrigger
=$this->h
-$this->bMargin
;
1577 else if (($this->mirrorMargins
) && (($this->page
)%
2==0)) { // EVEN
1578 $this->lMargin
=$this->DefrMargin
;
1579 $this->rMargin
=$this->DeflMargin
;
1580 $this->MarginCorrection
= $this->DefrMargin
-$this->DeflMargin
;
1583 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS
1584 $this->lMargin
=$this->DeflMargin
;
1585 $this->rMargin
=$this->DefrMargin
;
1586 if ($this->mirrorMargins
) { $this
->MarginCorrection
= $this
->DeflMargin
-$this
->DefrMargin
; }
1588 $this->x
=$this->lMargin
;
1592 function SetLeftMargin($margin) {
1594 $this->lMargin
=$margin;
1595 if($this->page
>0 and $this->x
<$margin) $this->x
=$margin;
1598 function SetTopMargin($margin) {
1600 $this->tMargin
=$margin;
1603 function SetRightMargin($margin) {
1605 $this->rMargin
=$margin;
1608 function SetAutoPageBreak($auto,$margin=0) {
1609 //Set auto page break mode and triggering margin
1610 $this->autoPageBreak
=$auto;
1611 $this->bMargin
=$margin;
1612 $this->PageBreakTrigger
=$this->h
-$margin;
1615 function SetDisplayMode($zoom,$layout='continuous') {
1616 //Set display mode in viewer
1617 if($zoom=='fullpage' or $zoom=='fullwidth' or $zoom=='real' or $zoom=='default' or !is_string($zoom))
1618 $this->ZoomMode
=$zoom;
1620 $this->Error('Incorrect zoom display mode: '.$zoom);
1621 if($layout=='single' or $layout=='continuous' or $layout=='two' or $layout=='twoleft' or $layout=='tworight' or $layout=='default')
1622 $this->LayoutMode
=$layout;
1624 $this->Error('Incorrect layout display mode: '.$layout);
1627 function SetCompression($compress) {
1628 //Set page compression
1629 if(function_exists('gzcompress')) $this->compress
=$compress;
1630 else $this->compress
=false;
1633 function SetTitle($title) {
1634 //Title of document // Arrives as UTF-8
1635 $this->title
= $title;
1638 function SetSubject($subject) {
1639 //Subject of document
1640 $this->subject
= $subject;
1643 function SetAuthor($author) {
1644 //Author of document
1645 $this->author
= $author;
1648 function SetKeywords($keywords) {
1649 //Keywords of document
1650 $this->keywords
= $keywords;
1653 function SetCreator($creator) {
1654 //Creator of document
1655 $this->creator
= $creator;
1659 function SetAnchor2Bookmark($x) {
1660 $this->anchor2Bookmark
= $x;
1663 function AliasNbPages($alias='{nb}') {
1664 //Define an alias for total number of pages
1665 $this->aliasNbPg
=$alias;
1668 function AliasNbPageGroups($alias='{nbpg}') {
1669 //Define an alias for total number of pages in a group
1670 $this->aliasNbPgGp
=$alias;
1673 function SetAlpha($alpha, $bm='Normal', $return=false, $mode='B') {
1674 // alpha: real value from 0 (transparent) to 1 (opaque)
1675 // bm: blend mode, one of the following:
1676 // Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn,
1677 // HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity
1678 // set alpha for stroking (CA) and non-stroking (ca) operations
1679 // mode determines F (fill) S (stroke) B (both)
1680 if (($this->PDFA
|| $this->PDFX
) && $alpha!=1) {
1681 if (($this->PDFA
&& !$this->PDFAauto
) || ($this->PDFX
&& !$this->PDFXauto
)) { $this
->PDFAXwarnings
[] = "Image opacity must be 100% (Opacity changed to 100%)"; }
1684 $a = array('BM'=>'/'.$bm);
1685 if ($mode=='F' || $mode='B') $a['ca'] = $alpha;
1686 if ($mode=='S' || $mode='B') $a['CA'] = $alpha;
1687 $gs = $this->AddExtGState($a);
1688 if ($return) { return sprintf('/GS%d gs', $gs
); }
1689 else { $this
->_out(sprintf('/GS%d gs', $gs
)); }
1692 function AddExtGState($parms) {
1693 $n = count($this->extgstates
);
1694 // check if graphics state already exists
1695 for ($i=1; $i<=$n; $i++
) {
1696 if (count($this->extgstates
[$i]['parms']) == count($parms)) {
1698 foreach($this->extgstates
[$i]['parms'] AS $k=>$v) {
1699 if (!isset($parms[$k]) || $parms[$k] != $v) { $same
= false; break; }
1701 if ($same) { return $i
; }
1705 $this->extgstates
[$n]['parms'] = $parms;
1709 function SetVisibility($v) {
1710 if (($this->PDFA
|| $this->PDFX
) && $this->visibility
!='visible') { $this
->PDFAXwarnings
[] = "Cannot set visibility to anything other than full when using PDFA or PDFX"; return ''; }
1711 else if (!$this->PDFA
&& !$this->PDFX
)
1712 $this->pdf_version
='1.5';
1713 if($this->visibility
!='visible') {
1715 $this->hasOC
=intval($this->hasOC
); // mPDF 5.6.01
1717 if($v=='printonly') {
1718 $this->_out('/OC /OC1 BDC');
1719 $this->hasOC
=($this->hasOC
| 1); // mPDF 5.6.01
1721 elseif($v=='screenonly') {
1722 $this->_out('/OC /OC2 BDC');
1723 $this->hasOC
=($this->hasOC
| 2); // mPDF 5.6.01
1725 elseif($v=='hidden') {
1726 $this->_out('/OC /OC3 BDC');
1727 $this->hasOC
=($this->hasOC
| 4); // mPDF 5.6.01
1729 elseif($v!='visible')
1730 $this->Error('Incorrect visibility: '.$v);
1731 $this->visibility
=$v;
1734 function Error($msg) {
1736 header('Content-Type: text/html; charset=utf-8');
1737 die('<B>mPDF error: </B>'.$msg);
1742 if($this->state
==0) $this->_begindoc();
1746 if ($this->progressBar
) { $this
->UpdateProgressBar(2,'2','Closing last page'); } // *PROGRESS-BAR*
1747 //Terminate document
1748 if($this->state
==3) return;
1749 if($this->page
==0) $this->AddPage($this->CurOrientation
);
1750 if (count($this->cellBorderBuffer
)) { $this
->printcellbuffer(); } // *TABLES*
1751 if ($this->tablebuffer
) { $this
->printtablebuffer(); } // *TABLES*
1754 if ($this->ColActive
) {
1755 $this->SetColumns(0);
1756 $this->ColActive
= 0;
1757 if (count($this->columnbuffer
)) { $this
->printcolumnbuffer(); }
1759 /*-- END COLUMNS --*/
1760 if (count($this->divbuffer
)) { $this
->printdivbuffer(); }
1765 $s .= $this->PrintBodyBackgrounds();
1767 $s .= $this->PrintPageBackgrounds();
1768 $this->pages
[$this->page
] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', "\n".$s."\n".'\\1', $this->pages
[$this->page
]);
1769 $this->pageBackgrounds
= array();
1771 if($this->visibility
!='visible')
1772 $this->SetVisibility('visible');
1773 // mPDF 5.6.01 - LAYERS
1776 if (!$this->tocontents
|| !$this->tocontents
->TOCmark
) { //Page footer
1777 $this->InFooter
=true;
1779 $this->InFooter
=false;
1781 if ($this->tocontents
&& ($this->tocontents
->TOCmark
|| count($this->tocontents
->m_TOC
))) { $this
->tocontents
->insertTOC(); } // *TOC*
1790 /*-- BACKGROUNDS --*/
1791 function _resizeBackgroundImage($imw, $imh, $cw, $ch, $resize=0, $repx, $repy, $pba=array(), $size=array()) { // mPDF 5.6.10
1792 // pba is background positioning area (from CSS background-origin) may not always be set [x,y,w,h]
1793 // size is from CSS3 background-size - takes precendence over old resize
1794 // $w - absolute length or % or auto or cover | contain
1795 // $h - absolute length or % or auto or cover | contain
1797 if (isset($pba['w'])) $cw = $pba['w'];
1798 if (isset($pba['h'])) $ch = $pba['h'];
1802 if (empty($size) && !$resize) { return array($imw
, $imh
, $repx
, $repy
); }
1805 if (isset($size['w']) && $size['w']) {
1806 if ($size['w']=='contain') {
1807 // Scale the image, while preserving its intrinsic aspect ratio (if any), to the largest size such that both its width and its height can fit inside the background positioning area.
1808 // Same as resize==3
1809 $h = $imh * $cw/$imw;
1816 else if ($size['w']=='cover') {
1817 // Scale the image, while preserving its intrinsic aspect ratio (if any), to the smallest size such that both its width and its height can completely cover the background positioning area.
1818 $h = $imh * $cw/$imw;
1826 if (stristr($size['w'] ,'%')) {
1829 $size['w'] = ($cw * $size['w']);
1831 if (stristr($size['h'] ,'%')) {
1834 $size['h'] = ($ch * $size['h']);
1836 if ($size['w']=='auto' && $size['h']=='auto') {
1840 else if ($size['w']=='auto' && $size['h']!='auto') {
1841 $w = $imw * $size['h']/$imh;
1844 else if ($size['w']!='auto' && $size['h']=='auto') {
1845 $h = $imh * $size['w']/$imw;
1853 return array($w, $h, $repx, $repy);
1855 else if ($resize==1 && $imw > $cw) {
1856 $h = $imh * $cw/$imw;
1857 return array($cw, $h, $repx, $repy);
1859 else if ($resize==2 && $imh > $ch) {
1860 $w = $imw * $ch/$imh;
1861 return array($w, $ch, $repx, $repy);
1863 else if ($resize==3) {
1874 return array($w, $h, $repx, $repy);
1876 else if ($resize==4) {
1877 $h = $imh * $cw/$imw;
1878 return array($cw, $h, $repx, $repy);
1880 else if ($resize==5) {
1881 $w = $imw * $ch/$imh;
1882 return array($w, $ch, $repx, $repy);
1884 else if ($resize==6) {
1885 return array($cw, $ch, $repx, $repy);
1887 return array($imw, $imh, $repx, $repy);
1891 function SetBackground(&$properties, &$maxwidth) {
1892 // mPDF 5.6.10 5.6.11
1893 if (isset($properties['BACKGROUND-ORIGIN']) && ($properties['BACKGROUND-ORIGIN']=='border-box' || $properties['BACKGROUND-ORIGIN']== 'content-box')) { $origin
= $properties
['BACKGROUND-ORIGIN']; }
1894 else { $origin
= 'padding-box'; }
1896 if (isset($properties['BACKGROUND-SIZE'])) {
1897 if (stristr($properties['BACKGROUND-SIZE'] ,'contain') ) { $bsw
= $bsh
= 'contain'; }
1898 else if (stristr($properties['BACKGROUND-SIZE'] ,'cover') ) { $bsw
= $bsh
= 'cover'; }
1900 $bsw = $bsh = 'auto';
1901 $sz = preg_split('/\s+/',trim($properties['BACKGROUND-SIZE']));
1902 if (count($sz)==2) { $bsw
= $sz
[0]; $bsh
= $sz
[1]; }
1903 else { $bsw
= $sz
[0]; }
1904 if (!stristr($bsw ,'%') && !stristr($bsw ,'auto') ) { $bsw
= $this
->ConvertSize($bsw
,$maxwidth
,$this
->FontSize
); }
1905 if (!stristr($bsh ,'%') && !stristr($bsh ,'auto') ) { $bsh
= $this
->ConvertSize($bsh
,$maxwidth
,$this
->FontSize
); }
1907 $size = array('w'=>$bsw, 'h'=>$bsh);
1909 if (preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/',$properties['BACKGROUND-IMAGE'])) {
1910 return array('gradient'=>$properties['BACKGROUND-IMAGE'], 'origin'=>$origin, 'size'=>$size ); // mPDF 5.6.10
1913 $file = $properties['BACKGROUND-IMAGE'];
1914 $sizesarray = $this->Image($file,0,0,0,0,'','',false, false, false, false, true);
1915 if (isset($sizesarray['IMAGE_ID'])) {
1916 $image_id = $sizesarray['IMAGE_ID'];
1917 $orig_w = $sizesarray['WIDTH']*_MPDFK
; // in user units i.e. mm
1918 $orig_h = $sizesarray['HEIGHT']*_MPDFK
; // (using $this->img_dpi)
1919 if (isset($properties['BACKGROUND-IMAGE-RESOLUTION'])) {
1920 if (preg_match('/from-image/i', $properties['BACKGROUND-IMAGE-RESOLUTION']) && isset($sizesarray['set-dpi']) && $sizesarray['set-dpi']>0) {
1921 $orig_w *= $this->img_dpi
/ $sizesarray['set-dpi'];
1922 $orig_h *= $this->img_dpi
/ $sizesarray['set-dpi'];
1924 else if (preg_match('/(\d+)dpi/i', $properties['BACKGROUND-IMAGE-RESOLUTION'], $m)) {
1927 $orig_w *= $this->img_dpi
/ $dpi;
1928 $orig_h *= $this->img_dpi
/ $dpi;
1934 if (isset($properties['BACKGROUND-REPEAT'])) {
1935 if ($properties['BACKGROUND-REPEAT']=='no-repeat' || $properties['BACKGROUND-REPEAT']=='repeat-x') { $y_repeat
= false; }
1936 if ($properties['BACKGROUND-REPEAT']=='no-repeat' || $properties['BACKGROUND-REPEAT']=='repeat-y') { $x_repeat
= false; }
1940 if (isset($properties['BACKGROUND-POSITION'])) {
1941 $ppos = preg_split('/\s+/',$properties['BACKGROUND-POSITION']);
1944 if (!stristr($x_pos ,'%') ) { $x_pos
= $this
->ConvertSize($x_pos
,$maxwidth
,$this
->FontSize
); }
1945 if (!stristr($y_pos ,'%') ) { $y_pos
= $this
->ConvertSize($y_pos
,$maxwidth
,$this
->FontSize
); }
1947 if (isset($properties['BACKGROUND-IMAGE-RESIZE'])) { $resize
= $properties
['BACKGROUND-IMAGE-RESIZE']; }
1948 else { $resize
= 0; }
1949 if (isset($properties['BACKGROUND-IMAGE-OPACITY'])) { $opacity
= $properties
['BACKGROUND-IMAGE-OPACITY']; }
1950 else { $opacity
= 1; }
1951 return array('image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$sizesarray['itype'], 'origin'=>$origin, 'size'=>$size );
1956 /*-- END BACKGROUNDS --*/
1958 function PrintBodyBackgrounds() {
1964 // If using bleed and trim margins in paged media
1965 if ($this->pageDim
[$this->page
]['outer_width_LR'] || $this->pageDim
[$this->page
]['outer_width_TB']) {
1966 $clx = $this->pageDim
[$this->page
]['outer_width_LR'] - $this->pageDim
[$this->page
]['bleedMargin'];
1967 $cly = $this->pageDim
[$this->page
]['outer_width_TB'] - $this->pageDim
[$this->page
]['bleedMargin'];
1968 $clw = $this->w
- 2*$clx;
1969 $clh = $this->h
- 2*$cly;
1972 if ($this->bodyBackgroundColor
) {
1973 $s .= 'q ' .$this->SetFColor($this->bodyBackgroundColor
, true)."\n";
1974 if ($this->bodyBackgroundColor{
0}==5) { // RGBa
1975 $s .= $this->SetAlpha(ord($this->bodyBackgroundColor{
4})/100, 'Normal', true, 'F')."\n";
1977 else if ($this->bodyBackgroundColor{
0}==6) { // CMYKa
1978 $s .= $this->SetAlpha(ord($this->bodyBackgroundColor{
5})/100, 'Normal', true, 'F')."\n";
1980 $s .= sprintf('%.3F %.3F %.3F %.3F re f Q', ($clx*_MPDFK
), ($cly*_MPDFK
),$clw*_MPDFK
,$clh*_MPDFK
)."\n";
1983 /*-- BACKGROUNDS --*/
1984 if ($this->bodyBackgroundGradient
) {
1985 $g = $this->grad
->parseBackgroundGradient($this->bodyBackgroundGradient
);
1987 $s .= $this->grad
->Gradient($clx, $cly, $clw, $clh, (isset($g['gradtype']) ? $g['gradtype'] : null), $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
1990 if ($this->bodyBackgroundImage
) {
1991 if ( $this->bodyBackgroundImage
['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->bodyBackgroundImage
['gradient'])) {
1992 $g = $this->grad
->parseMozGradient( $this->bodyBackgroundImage
['gradient']);
1994 $s .= $this->grad
->Gradient($clx, $cly, $clw, $clh, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
1997 else if ($this->bodyBackgroundImage
['image_id']) { // Background pattern
1998 $n = count($this->patterns
)+
1;
1999 // If using resize, uses TrimBox (not including the bleed)
2000 list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($this->bodyBackgroundImage
['orig_w'], $this->bodyBackgroundImage
['orig_h'], $clw, $clh, $this->bodyBackgroundImage
['resize'], $this->bodyBackgroundImage
['x_repeat'], $this->bodyBackgroundImage
['y_repeat']);
2002 $this->patterns
[$n] = array('x'=>$clx, 'y'=>$cly, 'w'=>$clw, 'h'=>$clh, 'pgh'=>$this->h
, 'image_id'=>$this->bodyBackgroundImage
['image_id'], 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$this->bodyBackgroundImage
['x_pos'], 'y_pos'=>$this->bodyBackgroundImage
['y_pos'], 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'itype'=>$this->bodyBackgroundImage
['itype']);
2003 if (($this->bodyBackgroundImage
['opacity']>0 || $this->bodyBackgroundImage
['opacity']==='0') && $this->bodyBackgroundImage
['opacity']<1) { $opac
= $this
->SetAlpha($this
->bodyBackgroundImage
['opacity'],'Normal',true); }
2004 else { $opac
= ''; }
2005 $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, ($clx*_MPDFK
), ($cly*_MPDFK
),$clw*_MPDFK
, $clh*_MPDFK
) ."\n";
2008 /*-- END BACKGROUNDS --*/
2013 function PrintPageBackgrounds($adjustmenty=0) {
2016 ksort($this->pageBackgrounds
);
2017 foreach($this->pageBackgrounds
AS $bl=>$pbs) {
2018 foreach ($pbs AS $pb) {
2019 if ((!isset($pb['image_id']) && !isset($pb['gradient'])) || isset($pb['shadowonly'])) { // Background colour or boxshadow
2020 // mPDF 5.6.01 - LAYERS
2021 if($pb['z-index']>0) {
2022 $this->current_layer
= $pb['z-index'];
2023 $s .= "\n".'/OCBZ-index /ZI'.$pb['z-index'].' BDC'."\n";
2026 if($pb['visibility']!='visible') {
2027 if($pb['visibility']=='printonly')
2028 $s .= '/OC /OC1 BDC'."\n";
2029 else if($pb['visibility']=='screenonly')
2030 $s .= '/OC /OC2 BDC'."\n";
2031 else if($pb['visibility']=='hidden')
2032 $s .= '/OC /OC3 BDC'."\n";
2035 if (isset($pb['shadow']) && $pb['shadow']) { $s
.= $pb
['shadow']."\n"; }
2036 if (isset($pb['clippath']) && $pb['clippath']) { $s
.= $pb
['clippath']."\n"; }
2037 $s .= 'q '.$this->SetFColor($pb['col'], true)."\n";
2038 if ($pb['col']{0}==5) { // RGBa
2039 $s .= $this->SetAlpha(ord($pb['col']{4})/100, 'Normal', true, 'F')."\n";
2041 else if ($pb['col']{0}==6) { // CMYKa
2042 $s .= $this->SetAlpha(ord($pb['col']{5})/100, 'Normal', true, 'F')."\n";
2044 $s .= sprintf('%.3F %.3F %.3F %.3F re f Q',$pb['x']*_MPDFK
,($this->h
-$pb['y'])*_MPDFK
,$pb['w']*_MPDFK
,-$pb['h']*_MPDFK
)."\n";
2045 if (isset($pb['clippath']) && $pb['clippath']) { $s
.= 'Q'."\n"; }
2046 if($pb['visibility']!='visible')
2049 // mPDF 5.6.01 - LAYERS
2050 if($pb['z-index']>0) {
2051 $s .= "\n".'EMCBZ-index'."\n";
2052 $this->current_layer
= 0;
2056 /*-- BACKGROUNDS --*/
2057 foreach ($pbs AS $pb) {
2058 // mPDF 5.6.01 - LAYERS
2059 if ((isset($pb['gradient']) && $pb['gradient']) || (isset($pb['image_id']) && $pb['image_id'])) {
2060 if($pb['z-index']>0) {
2061 $this->current_layer
= $pb['z-index'];
2062 $s .= "\n".'/OCGZ-index /ZI'.$pb['z-index'].' BDC'."\n";
2064 if($pb['visibility']!='visible') {
2065 if($pb['visibility']=='printonly')
2066 $s .= '/OC /OC1 BDC'."\n";
2067 else if($pb['visibility']=='screenonly')
2068 $s .= '/OC /OC2 BDC'."\n";
2069 else if($pb['visibility']=='hidden')
2070 $s .= '/OC /OC3 BDC'."\n";
2073 if (isset($pb['gradient']) && $pb['gradient']) {
2074 if (isset($pb['clippath']) && $pb['clippath']) { $s
.= $pb
['clippath']."\n"; }
2075 $s .= $this->grad
->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
2076 if (isset($pb['clippath']) && $pb['clippath']) { $s
.= 'Q'."\n"; }
2078 else if (isset($pb['image_id']) && $pb['image_id']) { // Background Image
2079 $pb['y'] -= $adjustmenty;
2080 $pb['h'] +
= $adjustmenty;
2081 $n = count($this->patterns
)+
1;
2082 list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($pb['orig_w'], $pb['orig_h'], $pb['w'], $pb['h'], $pb['resize'], $pb['x_repeat'], $pb['y_repeat'], $pb['bpa'], $pb['size']); // mPDF 5.6.10
2083 $this->patterns
[$n] = array('x'=>$pb['x'], 'y'=>$pb['y'], 'w'=>$pb['w'], 'h'=>$pb['h'], 'pgh'=>$this->h
, 'image_id'=>$pb['image_id'], 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$pb['x_pos'], 'y_pos'=>$pb['y_pos'], 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'itype'=>$pb['itype'], 'bpa'=>$pb['bpa']); // mPDF 5.6.10
2084 $x = $pb['x']*_MPDFK
;
2085 $y = ($this->h
- $pb['y'])*_MPDFK
;
2086 $w = $pb['w']*_MPDFK
;
2087 $h = -$pb['h']*_MPDFK
;
2088 if (isset($pb['clippath']) && $pb['clippath']) { $s
.= $pb
['clippath']."\n"; }
2089 if ($this->writingHTMLfooter
|| $this->writingHTMLheader
) { // Write each (tiles) image rather than use as a pattern
2090 $iw = $pb['orig_w']/_MPDFK
;
2091 $ih = $pb['orig_h']/_MPDFK
;
2099 if (isset($pb['bpa']) && $pb['bpa']) {
2100 $w = $pb['bpa']['w'];
2101 $h = $pb['bpa']['h'];
2102 $x0 = $pb['bpa']['x'];
2103 $y0 = $pb['bpa']['y'];
2107 if (isset($pb['size']['w']) && $pb['size']['w']) {
2108 $size = $pb['size'];
2110 if ($size['w']=='contain') {
2111 // Scale the image, while preserving its intrinsic aspect ratio (if any), to the largest size such that both its width and its height can fit inside the background positioning area.
2112 // Same as resize==3
2113 $ih = $ih * $pb['bpa']['w']/$iw;
2114 $iw = $pb['bpa']['w'];
2115 if ($ih > $pb['bpa']['h']) {
2116 $iw = $iw * $pb['bpa']['h']/$ih;
2117 $ih = $pb['bpa']['h'];
2120 else if ($size['w']=='cover') {
2121 // Scale the image, while preserving its intrinsic aspect ratio (if any), to the smallest size such that both its width and its height can completely cover the background positioning area.
2122 $ih = $ih * $pb['bpa']['w']/$iw;
2123 $iw = $pb['bpa']['w'];
2124 if ($ih < $pb['bpa']['h']) {
2125 $iw = $iw * $ih/$pb['bpa']['h'];
2126 $ih = $pb['bpa']['h'];
2130 if (stristr($size['w'] ,'%')) {
2133 $size['w'] = ($pb['bpa']['w'] * $size['w']);
2135 if (stristr($size['h'] ,'%')) {
2138 $size['h'] = ($pb['bpa']['h'] * $size['h']);
2140 if ($size['w']=='auto' && $size['h']=='auto') {
2144 else if ($size['w']=='auto' && $size['h']!='auto') {
2145 $iw = $iw * $size['h']/$ih;
2148 else if ($size['w']!='auto' && $size['h']=='auto') {
2149 $ih = $ih * $size['w']/$iw;
2160 if ($pb['x_repeat']) { $nx
= ceil($pb
['w']/$iw
)+
1; } // mPDF 5.6.11
2162 if ($pb['y_repeat']) { $ny
= ceil($pb
['h']/$ih
)+
1; } // mPDF 5.6.11
2165 $x_pos = $pb['x_pos'];
2166 if (stristr($x_pos ,'%') ) {
2169 $x_pos = ($pb['bpa']['w'] * $x_pos) - ($iw * $x_pos); // mPDF 5.6.11
2171 $y_pos = $pb['y_pos'];
2172 if (stristr($y_pos ,'%') ) {
2175 $y_pos = ($pb['bpa']['h'] * $y_pos) - ($ih * $y_pos); // mPDF 5.6.11
2178 while($x_pos>($pb['x']-$pb['bpa']['x'])) { $x_pos
-= $iw
; } // mPDF 5.6.11
2181 while($y_pos>($pb['y']-$pb['bpa']['y'])) { $y_pos
-= $ih
; } // mPDF 5.6.11
2183 for($xi=0;$xi<$nx;$xi++
) {
2184 for($yi=0;$yi<$ny;$yi++
) {
2185 $x = $x0 +
$x_pos +
($iw*$xi);
2186 $y = $y0 +
$y_pos +
($ih*$yi);
2187 if ($pb['opacity']>0 && $pb['opacity']<1) { $opac
= $this
->SetAlpha($pb
['opacity'],'Normal',true); }
2188 else { $opac
= ''; }
2189 $s .= sprintf("q %s %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q", $opac,$iw*_MPDFK
,$ih*_MPDFK
,$x*_MPDFK
,($this->h
-($y+
$ih))*_MPDFK
,$pb['image_id']) ."\n";
2194 if (($pb['opacity']>0 || $pb['opacity']==='0') && $pb['opacity']<1) { $opac
= $this
->SetAlpha($pb
['opacity'],'Normal',true); }
2195 else { $opac
= ''; }
2196 $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $x, $y, $w, $h) ."\n";
2198 if (isset($pb['clippath']) && $pb['clippath']) { $s
.= 'Q'."\n"; }
2200 if ((isset($pb['gradient']) && $pb['gradient']) || (isset($pb['image_id']) && $pb['image_id'])) {
2201 if($pb['visibility']!='visible')
2204 // mPDF 5.6.01 - LAYERS
2205 if($pb['z-index']>0) {
2206 $s .= "\n".'EMCGZ-index'."\n";
2207 $this->current_layer
= 0;
2212 /*-- END BACKGROUNDS --*/
2217 function PrintTableBackgrounds($adjustmenty=0) {
2219 /*-- BACKGROUNDS --*/
2220 ksort($this->tableBackgrounds
);
2221 foreach($this->tableBackgrounds
AS $bl=>$pbs) {
2222 foreach ($pbs AS $pb) {
2223 if ((!isset($pb['gradient']) || !$pb['gradient']) && (!isset($pb['image_id']) || !$pb['image_id'])) {
2224 $s .= 'q '.$this->SetFColor($pb['col'], true)."\n";
2225 if ($pb['col']{0}==5) { // RGBa
2226 $s .= $this->SetAlpha(ord($pb['col']{4})/100, 'Normal', true, 'F')."\n";
2228 else if ($pb['col']{0}==6) { // CMYKa
2229 $s .= $this->SetAlpha(ord($pb['col']{5})/100, 'Normal', true, 'F')."\n";
2231 $s .= sprintf('%.3F %.3F %.3F %.3F re %s Q',$pb['x']*_MPDFK
,($this->h
-$pb['y'])*_MPDFK
,$pb['w']*_MPDFK
,-$pb['h']*_MPDFK
,'f')."\n";
2233 if (isset($pb['gradient']) && $pb['gradient']) {
2234 if (isset($pb['clippath']) && $pb['clippath']) { $s
.= $pb
['clippath']."\n"; }
2235 $s .= $this->grad
->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
2236 if (isset($pb['clippath']) && $pb['clippath']) { $s
.= 'Q'."\n"; }
2238 if (isset($pb['image_id']) && $pb['image_id']) { // Background pattern
2239 $pb['y'] -= $adjustmenty;
2240 $pb['h'] +
= $adjustmenty;
2241 $n = count($this->patterns
)+
1;
2242 list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($pb['orig_w'], $pb['orig_h'], $pb['w'], $pb['h'], $pb['resize'], $pb['x_repeat'], $pb['y_repeat']);
2243 $this->patterns
[$n] = array('x'=>$pb['x'], 'y'=>$pb['y'], 'w'=>$pb['w'], 'h'=>$pb['h'], 'pgh'=>$this->h
, 'image_id'=>$pb['image_id'], 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$pb['x_pos'], 'y_pos'=>$pb['y_pos'], 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'itype'=>$pb['itype']);
2244 $x = $pb['x']*_MPDFK
;
2245 $y = ($this->h
- $pb['y'])*_MPDFK
;
2246 $w = $pb['w']*_MPDFK
;
2247 $h = -$pb['h']*_MPDFK
;
2248 if (isset($pb['clippath']) && $pb['clippath']) { $s
.= $pb
['clippath']."\n"; }
2249 if ($pb['opacity']>0 && $pb['opacity']<1) { $opac
= $this
->SetAlpha($pb
['opacity'],'Normal',true); }
2250 else { $opac
= ''; }
2251 $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $x, $y, $w, $h) ."\n";
2252 if (isset($pb['clippath']) && $pb['clippath']) { $s
.= 'Q'."\n"; }
2256 /*-- END BACKGROUNDS --*/
2260 // mPDF 5.6.01 - LAYERS
2261 function BeginLayer($id) {
2262 if($this->current_layer
>0) $this->EndLayer();
2263 if ($id < 1) { return false; }
2264 if (!isset($this->layers
[$id])) {
2265 $this->layers
[$id] = array('name'=>'Layer '.($id) );
2266 if (($this->PDFA
|| $this->PDFX
)) { $this
->PDFAXwarnings
[] = "Cannot use layers when using PDFA or PDFX"; return ''; }
2267 else if (!$this->PDFA
&& !$this->PDFX
) { $this
->pdf_version
='1.5'; }
2269 $this->current_layer
= $id;
2270 $this->_out('/OCZ-index /ZI'.$id.' BDC');
2272 $this->pageoutput
[$this->page
] = array();
2275 function EndLayer() {
2276 if($this->current_layer
>0) {
2277 $this->_out('EMCZ-index');
2278 $this->current_layer
= 0;
2284 // Depracated - can use AddPage for all
2285 function AddPages($orientation='',$condition='', $resetpagenum='', $pagenumstyle='', $suppress='',$mgl='',$mgr='',$mgt='',$mgb='',$mgh='',$mgf='',$ohname='',$ehname='',$ofname='',$efname='',$ohvalue=0,$ehvalue=0,$ofvalue=0,$efvalue=0,$pagesel='',$newformat='')
2287 $this->AddPage($orientation,$condition,$resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue,$pagesel,$newformat);
2291 function AddPageByArray($a) {
2292 if (!is_array($a)) { $a
= array(); }
2293 $orientation = (isset($a['orientation']) ? $a['orientation'] : '');
2294 $condition = (isset($a['condition']) ? $a['condition'] : (isset($a['type']) ? $a['type'] : ''));
2295 $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : '');
2296 $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : '');
2297 $suppress = (isset($a['suppress']) ? $a['suppress'] : '');
2298 $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
2299 $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
2300 $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
2301 $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
2302 $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
2303 $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
2304 $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
2305 $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
2306 $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
2307 $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
2308 $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
2309 $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
2310 $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
2311 $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
2312 $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : ''));
2313 $newformat = (isset($a['newformat']) ? $a['newformat'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
2315 $this->AddPage($orientation,$condition,$resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue,$pagesel,$newformat);
2320 function AddPage($orientation='',$condition='', $resetpagenum='', $pagenumstyle='', $suppress='',$mgl='',$mgr='',$mgt='',$mgb='',$mgh='',$mgf='',$ohname='',$ehname='',$ofname='',$efname='',$ohvalue=0,$ehvalue=0,$ofvalue=0,$efvalue=0,$pagesel='',$newformat='')
2324 // Cannot do with columns on, or if any change in page orientation/margins etc.
2325 // If next page already exists - i.e background /headers and footers already written
2326 if ($this->state
> 0 && $this->page
< count($this->pages
)) {
2327 $bak_cml = $this->cMarginL
;
2328 $bak_cmr = $this->cMarginR
;
2329 $bak_dw = $this->divwidth
;
2330 // Paint Div Border if necessary
2331 if ($this->blklvl
> 0) {
2332 $save_tr = $this->table_rotate
; // *TABLES*
2333 $this->table_rotate
= 0; // *TABLES*
2334 if ($this->y
== $this->blk
[$this->blklvl
]['y0']) { $this
->blk
[$this
->blklvl
]['startpage']++
; }
2335 if (($this->y
> $this->blk
[$this->blklvl
]['y0']) || $this->flowingBlockAttr
['is_table'] ) { $toplvl
= $this
->blklvl
; }
2336 else { $toplvl
= $this
->blklvl
-1; }
2338 for ($bl=1;$bl<=$toplvl;$bl++
) {
2339 $this->PaintDivBB('pagebottom',0,$bl);
2342 $this->table_rotate
= $save_tr; // *TABLES*
2344 $s = $this->PrintPageBackgrounds();
2346 // Writes after the marker so not overwritten later by page background etc.
2347 $this->pages
[$this->page
] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages
[$this->page
]);
2348 $this->pageBackgrounds
= array();
2349 $family=$this->FontFamily
;
2350 $style=$this->FontStyle
.($this->U
? 'U' : '').($this->S
? 'S' : '');
2351 $size=$this->FontSizePt
;
2352 $lw=$this->LineWidth
;
2353 $dc=$this->DrawColor
;
2354 $fc=$this->FillColor
;
2355 $tc=$this->TextColor
;
2356 $cf=$this->ColorFlag
;
2358 $this->printfloatbuffer();
2362 $this->ResetMargins();
2363 $this->SetAutoPageBreak($this->autoPageBreak
,$this->bMargin
);
2364 $this->x
=$this->lMargin
;
2365 $this->y
=$this->tMargin
;
2366 $this->FontFamily
='';
2368 $this->LineWidth
=$lw;
2369 $this->_out(sprintf('%.3F w',$lw*_MPDFK
));
2370 if($family) $this->SetFont($family,$style,$size,true,true);
2371 $this->DrawColor
=$dc;
2372 if($dc!=$this->defDrawColor
) $this->_out($dc);
2373 $this->FillColor
=$fc;
2374 if($fc!=$this->defFillColor
) $this->_out($fc);
2375 $this->TextColor
=$tc;
2376 $this->ColorFlag
=$cf;
2377 for($bl=1;$bl<=$this->blklvl
;$bl++
) {
2378 $this->blk
[$bl]['y0'] = $this->y
;
2379 // Don't correct more than once for background DIV containing a Float
2380 if (!isset($this->blk
[$bl]['marginCorrected'][$this->page
])) { $this
->blk
[$bl
]['x0'] +
= $this
->MarginCorrection
; }
2381 $this->blk
[$bl]['marginCorrected'][$this->page
] = true;
2383 $this->cMarginL
= $bak_cml;
2384 $this->cMarginR
= $bak_cmr;
2385 $this->divwidth
= $bak_dw;
2388 /*-- END CSS-FLOAT --*/
2391 if($this->state
==0) $this->Open();
2393 $bak_cml = $this->cMarginL
;
2394 $bak_cmr = $this->cMarginR
;
2395 $bak_dw = $this->divwidth
;
2398 $bak_lh = $this->lineheight
;
2400 $orientation = substr(strtoupper($orientation),0,1);
2401 $condition = strtoupper($condition);
2404 if ($condition == 'NEXT-EVEN') { // always adds at least one new page to create an Even page
2405 if (!$this->mirrorMargins
) { $condition
= ''; }
2407 if ($pagesel) { $pbch
= $pagesel
; $pagesel
= ''; } // *CSS-PAGE*
2408 else { $pbch
= false; } // *CSS-PAGE*
2409 $this->AddPage($this->CurOrientation
,'O');
2410 if ($pbch ) { $pagesel
= $pbch
; } // *CSS-PAGE*
2414 if ($condition == 'NEXT-ODD') { // always adds at least one new page to create an Odd page
2415 if (!$this->mirrorMargins
) { $condition
= ''; }
2417 if ($pagesel) { $pbch
= $pagesel
; $pagesel
= ''; } // *CSS-PAGE*
2418 else { $pbch
= false; } // *CSS-PAGE*
2419 $this->AddPage($this->CurOrientation
,'E');
2420 if ($pbch ) { $pagesel
= $pbch
; } // *CSS-PAGE*
2426 if ($condition == 'E') { // only adds new page if needed to create an Even page
2427 if (!$this->mirrorMargins
|| ($this->page
)%
2==0) { return false; }
2429 if ($condition == 'O') { // only adds new page if needed to create an Odd page
2430 if (!$this->mirrorMargins
|| ($this->page
)%
2==1) { return false; }
2433 if ($resetpagenum || $pagenumstyle || $suppress) {
2434 $this->PageNumSubstitutions
[] = array('from'=>($this->page+
1), 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=>$suppress);
2438 $save_tr = $this->table_rotate
; // *TABLES*
2439 $this->table_rotate
= 0; // *TABLES*
2440 $save_kwt = $this->kwt
;
2442 // mPDF 5.6.01 - LAYERS
2443 $save_layer = $this->current_layer
;
2444 $save_vis = $this->visibility
;
2446 if($this->visibility
!='visible')
2447 $this->SetVisibility('visible');
2448 // mPDF 5.6.01 - LAYERS
2451 // Paint Div Border if necessary
2452 //PAINTS BACKGROUND COLOUR OR BORDERS for DIV - DISABLED FOR COLUMNS (cf. AcceptPageBreak) AT PRESENT in ->PaintDivBB
2453 if (!$this->ColActive
&& $this->blklvl
> 0) {
2454 if (isset($this->blk
[$this->blklvl
]['y0']) && $this->y
== $this->blk
[$this->blklvl
]['y0']) {
2455 if (isset($this->blk
[$this->blklvl
]['startpage'])) { $this
->blk
[$this
->blklvl
]['startpage']++
; }
2456 else { $this
->blk
[$this
->blklvl
]['startpage'] = 1; }
2458 if ((isset($this->blk
[$this->blklvl
]['y0']) && $this->y
> $this->blk
[$this->blklvl
]['y0']) || $this->flowingBlockAttr
['is_table'] ) { $toplvl
= $this
->blklvl
; }
2459 else { $toplvl
= $this
->blklvl
-1; }
2461 for ($bl=1;$bl<=$toplvl;$bl++
) {
2463 // mPDF 5.6.01 - LAYERS
2464 if ($this->blk
[$bl]['z-index']>0) {
2465 $this->BeginLayer($this->blk
[$bl]['z-index']);
2467 if (isset($this->blk
[$bl]['visibility']) && $this->blk
[$bl]['visibility'] && $this->blk
[$bl]['visibility']!='visible') {
2468 $this->SetVisibility($this->blk
[$bl]['visibility']);
2471 $this->PaintDivBB('pagebottom',0,$bl);
2474 // RESET block y0 and x0 - see below
2477 if($this->visibility
!='visible')
2478 $this->SetVisibility('visible');
2479 // mPDF 5.6.01 - LAYERS
2483 if ($this->page
> 0) {
2485 $s .= $this->PrintBodyBackgrounds();
2487 $s .= $this->PrintPageBackgrounds();
2488 $this->pages
[$this->page
] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', "\n".$s."\n".'\\1', $this->pages
[$this->page
]);
2489 $this->pageBackgrounds
= array();
2492 $save_kt = $this->keep_block_together
;
2493 $this->keep_block_together
= 0;
2497 if ($this->ColActive
) {
2499 $save_nbcol = $this->NbCol
; // other values of gap and vAlign will not change by setting Columns off
2500 $this->SetColumns(0);
2502 /*-- END COLUMNS --*/
2505 $family=$this->FontFamily
;
2506 $style=$this->FontStyle
.($this->U
? 'U' : '').($this->S
? 'S' : '');
2507 $size=$this->FontSizePt
;
2508 $this->ColumnAdjust
= true; // enables column height adjustment for the page
2509 $lw=$this->LineWidth
;
2510 $dc=$this->DrawColor
;
2511 $fc=$this->FillColor
;
2512 $tc=$this->TextColor
;
2513 $cf=$this->ColorFlag
;
2517 $this->InFooter
=true;
2520 $this->pageoutput
[$this->page
] = array();
2529 $this->_beginpage($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat);
2530 if ($this->docTemplate
) {
2531 $pagecount = $this->SetSourceFile($this->docTemplate
);
2532 if (($this->page
- $this->docTemplateStart
) > $pagecount) {
2533 if ($this->docTemplateContinue
) {
2534 $tplIdx = $this->ImportPage($pagecount);
2535 $this->UseTemplate($tplIdx);
2539 $tplIdx = $this->ImportPage(($this->page
- $this->docTemplateStart
));
2540 $this->UseTemplate($tplIdx);
2543 if ($this->pageTemplate
) {
2544 $this->UseTemplate($this->pageTemplate
);
2548 $this->_out('___PAGE___START'.date('jY'));
2549 $this->_out('___BACKGROUND___PATTERNS'.date('jY'));
2550 $this->_out('___HEADER___MARKER'.date('jY'));
2551 $this->pageBackgrounds
= array();
2553 //Set line cap style to square
2554 $this->SetLineCap(2);
2556 $this->LineWidth
=$lw;
2557 $this->_out(sprintf('%.3F w',$lw*_MPDFK
));
2559 if($family) $this->SetFont($family,$style,$size,true,true); // forces write
2561 $this->DrawColor
=$dc;
2562 if($dc!=$this->defDrawColor
) $this->_out($dc);
2563 $this->FillColor
=$fc;
2564 if($fc!=$this->defFillColor
) $this->_out($fc);
2565 $this->TextColor
=$tc;
2566 $this->ColorFlag
=$cf;
2571 //Restore line width
2572 if($this->LineWidth
!=$lw)
2574 $this->LineWidth
=$lw;
2575 $this->_out(sprintf('%.3F w',$lw*_MPDFK
));
2578 if($family) $this->SetFont($family,$style,$size,true,true); // forces write
2580 if($this->DrawColor
!=$dc)
2582 $this->DrawColor
=$dc;
2585 if($this->FillColor
!=$fc)
2587 $this->FillColor
=$fc;
2590 $this->TextColor
=$tc;
2591 $this->ColorFlag
=$cf;
2592 $this->InFooter
=false;
2594 // mPDF 5.6.01 - LAYERS
2596 $this->BeginLayer($save_layer);
2598 if($save_vis!='visible')
2599 $this->SetVisibility($save_vis);
2604 $this->SetColumns($save_nbcol,$this->colvAlign
,$this->ColGap
);
2606 if ($this->ColActive
) { $this
->SetCol(0); }
2607 /*-- END COLUMNS --*/
2610 //RESET BLOCK BORDER TOP
2611 if (!$this->ColActive
) {
2612 for($bl=1;$bl<=$this->blklvl
;$bl++
) {
2613 $this->blk
[$bl]['y0'] = $this->y
;
2614 if (isset($this->blk
[$bl]['x0'])) { $this
->blk
[$bl
]['x0'] +
= $this
->MarginCorrection
; }
2615 else { $this
->blk
[$bl
]['x0'] = $this
->MarginCorrection
; }
2616 // Added mPDF 3.0 Float DIV
2617 $this->blk
[$bl]['marginCorrected'][$this->page
] = true;
2622 $this->table_rotate
= $save_tr; // *TABLES*
2623 $this->kwt
= $save_kwt;
2625 $this->keep_block_together
= $save_kt ;
2627 $this->cMarginL
= $bak_cml;
2628 $this->cMarginR
= $bak_cmr;
2629 $this->divwidth
= $bak_dw;
2631 $this->lineheight
= $bak_lh;
2636 //Get current page number
2640 function AddSpotColorsFromFile($file) {
2641 $colors = @file($file) or die("Cannot load spot colors file - ".$file);
2642 foreach($colors AS $sc) {
2643 list($name, $c, $m, $y, $k) = preg_split("/\t/",$sc);
2648 $this->AddSpotColor($name, $c, $m, $y, $k);
2652 function AddSpotColor($name, $c, $m, $y, $k) {
2653 $name = strtoupper(trim($name));
2654 if(!isset($this->spotColors
[$name])) {
2655 $i=count($this->spotColors
)+
1;
2656 $this->spotColors
[$name]=array('i'=>$i,'c'=>$c,'m'=>$m,'y'=>$y,'k'=>$k);
2657 $this->spotColorIDs
[$i]=$name;
2661 function SetColor($col, $type='') {
2663 if ($col{0}==3 || $col{0}==5) { // RGB / RGBa
2664 $out = sprintf('%.3F %.3F %.3F rg',ord($col{1})/255,ord($col{2})/255,ord($col{3})/255);
2666 else if ($col{0}==1) { // GRAYSCALE
2667 $out = sprintf('%.3F g',ord($col{1})/255);
2669 else if ($col{0}==2) { // SPOT COLOR
2670 $out = sprintf('/CS%d cs %.3F scn',ord($col{1}),ord($col{2})/100);
2672 else if ($col{0}==4 || $col{0}==6) { // CMYK / CMYKa
2673 $out = sprintf('%.3F %.3F %.3F %.3F k', ord($col{1})/100, ord($col{2})/100, ord($col{3})/100, ord($col{4})/100);
2675 if ($type=='Draw') { $out
= strtoupper($out
); } // e.g. rg => RG
2676 else if ($type=='CodeOnly') { $out
= preg_replace('/\s(rg|g|k)/','',$out
); }
2681 function SetDColor($col, $return=false) {
2682 $out = $this->SetColor($col, 'Draw');
2683 if ($return) { return $out
; }
2684 if ($out=='') { return ''; }
2685 $this->DrawColor
= $out;
2686 if($this->page
>0 && ((isset($this->pageoutput
[$this->page
]['DrawColor']) && $this->pageoutput
[$this->page
]['DrawColor'] != $this->DrawColor
) || !isset($this->pageoutput
[$this->page
]['DrawColor']) || $this->keep_block_together
)) { $this
->_out($this
->DrawColor
); }
2687 $this->pageoutput
[$this->page
]['DrawColor'] = $this->DrawColor
;
2690 function SetFColor($col, $return=false) {
2691 $out = $this->SetColor($col, 'Fill');
2692 if ($return) { return $out
; }
2693 if ($out=='') { return ''; }
2694 $this->FillColor
= $out;
2695 $this->ColorFlag
= ($out != $this->TextColor
);
2696 if($this->page
>0 && ((isset($this->pageoutput
[$this->page
]['FillColor']) && $this->pageoutput
[$this->page
]['FillColor'] != $this->FillColor
) || !isset($this->pageoutput
[$this->page
]['FillColor']) || $this->keep_block_together
)) { $this
->_out($this
->FillColor
); }
2697 $this->pageoutput
[$this->page
]['FillColor'] = $this->FillColor
;
2700 function SetTColor($col, $return=false) {
2701 $out = $this->SetColor($col, 'Text');
2702 if ($return) { return $out
; }
2703 if ($out=='') { return ''; }
2704 $this->TextColor
= $out;
2705 $this->ColorFlag
= ($this->FillColor
!= $out);
2709 function SetDrawColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2710 //Set color for all stroking operations
2712 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col
= $this
->ConvertColor($r
); }
2713 else if ($col4 == -1) { $col
= $this
->ConvertColor('rgb('.$r
.','.$g
.','.$b
.')'); }
2714 else { $col
= $this
->ConvertColor('cmyk('.$r
.','.$g
.','.$b
.','.$col4
.')'); }
2715 $out = $this->SetDColor($col, $return);
2719 function SetFillColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2720 //Set color for all filling operations
2722 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col
= $this
->ConvertColor($r
); }
2723 else if ($col4 == -1) { $col
= $this
->ConvertColor('rgb('.$r
.','.$g
.','.$b
.')'); }
2724 else { $col
= $this
->ConvertColor('cmyk('.$r
.','.$g
.','.$b
.','.$col4
.')'); }
2725 $out = $this->SetFColor($col, $return);
2729 function SetTextColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2730 //Set color for text
2732 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col
= $this
->ConvertColor($r
); }
2733 else if ($col4 == -1) { $col
= $this
->ConvertColor('rgb('.$r
.','.$g
.','.$b
.')'); }
2734 else { $col
= $this
->ConvertColor('cmyk('.$r
.','.$g
.','.$b
.','.$col4
.')'); }
2735 $out = $this->SetTColor($col, $return);
2739 function _getCharWidth(&$cw, $u, $isdef=true) {
2740 if ($u==0) { $w
= false; }
2741 else { $w
= (ord($cw
[$u
*2]) << 8) +
ord($cw
[$u
*2+
1]); }
2742 if ($w == 65535) { return 0; }
2743 else if ($w) { return $w
; }
2744 else if ($isdef) { return false; }
2748 function _charDefined(&$cw, $u) {
2749 if ($u==0) { return false; }
2750 $w = (ord($cw[$u*2]) << 8) +
ord($cw[$u*2+
1]);
2751 if ($w) { return true; }
2752 else {
return false; }
2755 function GetCharWidthCore($c) {
2756 //Get width of a single character in the current Core font
2759 // Soft Hyphens chr(173)
2760 if ($c == chr(173) && $this->FontFamily
!='csymbol' && $this->FontFamily
!='czapfdingbats') {
2763 else if ($this->S
&& isset($this->upperCase
[ord($c)])) {
2764 $charw = $this->CurrentFont
['cw'][chr($this->upperCase
[ord($c)])];
2765 if ($charw!==false) {
2766 $charw = $charw*$this->smCapsScale
* $this->smCapsStretch
/100;
2770 else if (isset($this->CurrentFont
['cw'][$c])) {
2771 $w +
= $this->CurrentFont
['cw'][$c];
2773 else if (isset($this->CurrentFont
['cw'][ord($c)])) {
2774 $w +
= $this->CurrentFont
['cw'][ord($c)];
2776 $w *= ($this->FontSize
/ 1000);
2777 if ($this->minwSpacing
|| $this->fixedlSpacing
) {
2778 if ($c==' ') $nb_spaces = 1;
2779 else $nb_spaces = 0;
2780 $w +
= $this->fixedlSpacing +
($nb_spaces * $this->minwSpacing
);
2785 function GetCharWidthNonCore($c, $addSubset=true) {
2786 //Get width of a single character in the current Non-Core font
2789 $unicode = $this->UTF8StringToArray($c, $addSubset);
2790 $char = $unicode[0];
2792 if ($this->CurrentFont
['type'] == 'Type0') { // CJK Adobe fonts
2793 if ($char == 173) { return 0; } // Soft Hyphens
2794 elseif (isset($this->CurrentFont
['cw'][$char])) { $w+
=$this
->CurrentFont
['cw'][$char
]; }
2795 elseif(isset($this->CurrentFont
['MissingWidth'])) { $w +
= $this
->CurrentFont
['MissingWidth']; }
2799 /*-- END CJK-FONTS --*/
2800 if ($char == 173) { return 0; } // Soft Hyphens
2801 else if ($this->S
&& isset($this->upperCase
[$char])) {
2802 $charw = $this->_getCharWidth($this->CurrentFont
['cw'],$this->upperCase
[$char]);
2803 if ($charw!==false) {
2804 $charw = $charw*$this->smCapsScale
* $this->smCapsStretch
/100;
2807 elseif(isset($this->CurrentFont
['desc']['MissingWidth'])) { $w +
= $this
->CurrentFont
['desc']['MissingWidth']; }
2808 elseif(isset($this->CurrentFont
['MissingWidth'])) { $w +
= $this
->CurrentFont
['MissingWidth']; }
2812 $charw = $this->_getCharWidth($this->CurrentFont
['cw'],$char);
2813 if ($charw!==false) { $w+
=$charw
; }
2814 elseif(isset($this->CurrentFont
['desc']['MissingWidth'])) { $w +
= $this
->CurrentFont
['desc']['MissingWidth']; }
2815 elseif(isset($this->CurrentFont
['MissingWidth'])) { $w +
= $this
->CurrentFont
['MissingWidth']; }
2819 $w *= ($this->FontSize
/ 1000);
2820 if ($this->minwSpacing
|| $this->fixedlSpacing
) {
2821 if ($c==' ') $nb_spaces = 1;
2822 else $nb_spaces = 0;
2823 $w +
= $this->fixedlSpacing +
($nb_spaces * $this->minwSpacing
);
2829 function GetCharWidth($c, $addSubset=true) {
2830 if (!$this->usingCoreFont
) {
2831 return $this->GetCharWidthNonCore($c, $addSubset);
2834 return $this->GetCharWidthCore($c);
2838 function GetStringWidth($s, $addSubset=true) {
2839 //Get width of a string in the current font
2841 $cw = &$this->CurrentFont
['cw'];
2848 if ($this->iterationCounter
) $s = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/', '\\1', $s);
2850 if (!$this->usingCoreFont
) {
2851 $s = str_replace("\xc2\xad",'',$s );
2852 $unicode = $this->UTF8StringToArray($s, $addSubset);
2853 if ($this->minwSpacing
|| $this->fixedlSpacing
) {
2854 $nb_carac = count($unicode);
2855 $nb_spaces = mb_substr_count($s,' ', $this->mb_enc
);
2858 if ($this->CurrentFont
['type'] == 'Type0') { // CJK Adobe fonts
2859 foreach($unicode as $char) {
2860 if (isset($cw[$char])) { $w+
=$cw
[$char
]; }
2861 elseif(isset($this->CurrentFont
['MissingWidth'])) { $w +
= $this
->CurrentFont
['MissingWidth']; }
2866 /*-- END CJK-FONTS --*/
2867 foreach($unicode as $char) {
2868 if ($this->S
&& isset($this->upperCase
[$char])) {
2869 $charw = $this->_getCharWidth($cw,$this->upperCase
[$char]);
2870 if ($charw!==false) {
2871 $charw = $charw*$this->smCapsScale
* $this->smCapsStretch
/100;
2874 elseif(isset($this->CurrentFont
['desc']['MissingWidth'])) { $w +
= $this
->CurrentFont
['desc']['MissingWidth']; }
2875 elseif(isset($this->CurrentFont
['MissingWidth'])) { $w +
= $this
->CurrentFont
['MissingWidth']; }
2879 $charw = $this->_getCharWidth($cw,$char);
2880 if ($charw!==false) { $w+
=$charw
; }
2881 elseif(isset($this->CurrentFont
['desc']['MissingWidth'])) { $w +
= $this
->CurrentFont
['desc']['MissingWidth']; }
2882 elseif(isset($this->CurrentFont
['MissingWidth'])) { $w +
= $this
->CurrentFont
['MissingWidth']; }
2884 if ($this->kerning
&& $this->useKerning
&& $lastchar) {
2885 if (isset($this->CurrentFont
['kerninfo'][$lastchar][$char])) {
2886 $kerning +
= $this->CurrentFont
['kerninfo'][$lastchar][$char];
2896 if ($this->FontFamily
!='csymbol' && $this->FontFamily
!='czapfdingbats') {
2897 $s = str_replace(chr(173),'',$s );
2899 $nb_carac = $l = strlen($s);
2900 if ($this->minwSpacing
|| $this->fixedlSpacing
) {
2901 $nb_spaces = substr_count($s,' ');
2903 for($i=0; $i<$l; $i++
) {
2904 if ($this->S
&& isset($this->upperCase
[ord($s[$i])])) {
2905 $charw = $cw[chr($this->upperCase
[ord($s[$i])])];
2906 if ($charw!==false) {
2907 $charw = $charw*$this->smCapsScale
* $this->smCapsStretch
/100;
2911 else if (isset($cw[$s[$i]])) {
2914 else if (isset($cw[ord($s[$i])])) {
2915 $w +
= $cw[ord($s[$i])];
2917 if ($this->kerning
&& $this->useKerning
&& $i>0) {
2918 if (isset($this->CurrentFont
['kerninfo'][$s[($i-1)]][$s[$i]])) {
2919 $kerning +
= $this->CurrentFont
['kerninfo'][$s[($i-1)]][$s[$i]];
2925 if ($this->kerning
&& $this->useKerning
) { $w +
= $kerning
; }
2926 $w *= ($this->FontSize
/ 1000);
2927 $w +
= (($nb_carac +
$nb_spaces) * $this->fixedlSpacing
) +
($nb_spaces * $this->minwSpacing
);
2931 function SetLineWidth($width) {
2933 $this->LineWidth
=$width;
2934 $lwout = (sprintf('%.3F w',$width*_MPDFK
));
2935 if($this->page
>0 && ((isset($this->pageoutput
[$this->page
]['LineWidth']) && $this->pageoutput
[$this->page
]['LineWidth'] != $lwout) || !isset($this->pageoutput
[$this->page
]['LineWidth']) || $this->keep_block_together
)) {
2936 $this->_out($lwout);
2938 $this->pageoutput
[$this->page
]['LineWidth'] = $lwout;
2941 function Line($x1,$y1,$x2,$y2) {
2943 $this->_out(sprintf('%.3F %.3F m %.3F %.3F l S',$x1*_MPDFK
,($this->h
-$y1)*_MPDFK
,$x2*_MPDFK
,($this->h
-$y2)*_MPDFK
));
2946 function Arrow($x1,$y1,$x2,$y2,$headsize=3,$fill='B',$angle=25) {
2947 //F == fill //S == stroke //B == stroke and fill
2948 // angle = splay of arrowhead - 1 - 89 degrees
2949 if($fill=='F') $fill='f';
2950 elseif($fill=='FD' or $fill=='DF' or $fill=='B') $fill='B';
2952 $a = atan2(($y2-$y1),($x2-$x1));
2953 $b = $a +
deg2rad($angle);
2954 $c = $a - deg2rad($angle);
2955 $x3 = $x2 - ($headsize* cos($b));
2956 $y3 = $this->h
-($y2 - ($headsize* sin($b)));
2957 $x4 = $x2 - ($headsize* cos($c));
2958 $y4 = $this->h
-($y2 - ($headsize* sin($c)));
2960 $x5 = $x3-($x3-$x4)/2; // mid point of base of arrowhead - to join arrow line to
2961 $y5 = $y3-($y3-$y4)/2;
2964 $s.=sprintf('%.3F %.3F m %.3F %.3F l S',$x1*_MPDFK
,($this->h
-$y1)*_MPDFK
,$x5*_MPDFK
,$y5*_MPDFK
);
2968 $s.=sprintf('%.3F %.3F m %.3F %.3F l %.3F %.3F l %.3F %.3F l %.3F %.3F l ',$x5*_MPDFK
,$y5*_MPDFK
,$x3*_MPDFK
,$y3*_MPDFK
,$x2*_MPDFK
,($this->h
-$y2)*_MPDFK
,$x4*_MPDFK
,$y4*_MPDFK
,$x5*_MPDFK
,$y5*_MPDFK
);
2974 function Rect($x,$y,$w,$h,$style='') {
2976 if($style=='F') $op='f';
2977 elseif($style=='FD' or $style=='DF') $op='B';
2979 $this->_out(sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK
,($this->h
-$y)*_MPDFK
,$w*_MPDFK
,-$h*_MPDFK
,$op));
2982 function AddFont($family,$style='') {
2983 if(empty($family)) { return; }
2984 $family = strtolower($family);
2985 $style=strtoupper($style);
2986 $style=str_replace('U','',$style);
2987 if($style=='IB') $style='BI';
2988 $fontkey = $family.$style;
2989 // check if the font has been already added
2990 if(isset($this->fonts
[$fontkey])) {
2995 if (in_array($family,$this->available_CJK_fonts
)) {
2996 if (empty($this->Big5_widths
)) { require(_MPDF_PATH
. 'includes/CJKdata.php'); }
2997 $this->AddCJKFont($family); // don't need to add style
3000 /*-- END CJK-FONTS --*/
3002 if ($this->usingCoreFont
) { die("mPDF Error - problem with Font management"); }
3005 if (!$style) { $stylekey
= 'R'; }
3007 if (!isset($this->fontdata
[$family][$stylekey]) || !$this->fontdata
[$family][$stylekey]) {
3008 die('mPDF Error - Font is not supported - '.$family.' '.$style);
3015 $unAGlyphs = false; // mPDF 5.4.05
3016 $haskerninfo = false;
3017 $BMPselected = false;
3018 @include(_MPDF_TTFONTDATAPATH
.$fontkey.'.mtx.php');
3021 if (defined('_MPDF_SYSTEM_TTFONTS')) {
3022 $ttffile = _MPDF_SYSTEM_TTFONTS
.$this->fontdata
[$family][$stylekey];
3023 if (!file_exists($ttffile)) { $ttffile
= ''; }
3026 $ttffile = _MPDF_TTFONTPATH
.$this->fontdata
[$family][$stylekey];
3027 if (!file_exists($ttffile)) { die("mPDF Error - cannot find TTF TrueType font file - ".$ttffile
); }
3029 $ttfstat = stat($ttffile);
3031 if (isset($this->fontdata
[$family]['TTCfontID'][$stylekey])) { $TTCfontID
= $this
->fontdata
[$family
]['TTCfontID'][$stylekey
]; }
3032 else { $TTCfontID
= 0; }
3036 if (in_array($family,$this->BMPonly
)) { $BMPonly
= true; }
3037 $regenerate = false;
3038 if ($BMPonly && !$BMPselected) { $regenerate
= true; }
3039 else if (!$BMPonly && $BMPselected) { $regenerate
= true; }
3040 if ($this->useKerning
&& !$haskerninfo) { $regenerate
= true; }
3042 if (isset($this->fontdata
[$family]['unAGlyphs']) && $this->fontdata
[$family]['unAGlyphs'] && !$unAGlyphs) {
3046 else if ((!isset($this->fontdata
[$family]['unAGlyphs']) || !$this->fontdata
[$family]['unAGlyphs']) && $unAGlyphs) {
3050 if (!isset($name) || $originalsize != $ttfstat['size'] || $regenerate) {
3051 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH
.'classes/ttfontsuni.php'); }
3052 $ttf = new TTFontFile();
3053 $ttf->getMetrics($ttffile, $TTCfontID, $this->debugfonts
, $BMPonly, $this->useKerning
, $unAGlyphs); // mPDF 5.4.05
3054 $cw = $ttf->charWidths
;
3055 $kerninfo = $ttf->kerninfo
;
3056 $haskerninfo = true;
3057 $name = preg_replace('/[ ()]/','',$ttf->fullName
);
3058 $sip = $ttf->sipset
;
3059 $smp = $ttf->smpset
;
3061 $desc= array('Ascent'=>round($ttf->ascent
),
3062 'Descent'=>round($ttf->descent
),
3063 'CapHeight'=>round($ttf->capHeight
),
3064 'Flags'=>$ttf->flags
,
3065 'FontBBox'=>'['.round($ttf->bbox
[0])." ".round($ttf->bbox
[1])." ".round($ttf->bbox
[2])." ".round($ttf->bbox
[3]).']',
3066 'ItalicAngle'=>$ttf->italicAngle
,
3067 'StemV'=>round($ttf->stemV
),
3068 'MissingWidth'=>round($ttf->defaultWidth
));
3071 if (count($ttf->panose
)) {
3072 $panoseArray = array_merge(array($ttf->sFamilyClass
, $ttf->sFamilySubClass
), $ttf->panose
);
3073 foreach($panoseArray as $value)
3074 $panose .= ' '.dechex($value);
3076 $up = round($ttf->underlinePosition
);
3077 $ut = round($ttf->underlineThickness
);
3078 $originalsize = $ttfstat['size']+
0;
3080 //Generate metrics .php file
3082 $s.='$name=\''.$name."';\n";
3083 $s.='$type=\''.$type."';\n";
3084 $s.='$desc='.var_export($desc,true).";\n";
3085 $s.='$up='.$up.";\n";
3086 $s.='$ut='.$ut.";\n";
3087 $s.='$ttffile=\''.$ttffile."';\n";
3088 $s.='$TTCfontID=\''.$TTCfontID."';\n";
3089 $s.='$originalsize='.$originalsize.";\n";
3090 if ($sip) $s.='$sip=true;'."\n";
3091 else $s.='$sip=false;'."\n";
3092 if ($smp) $s.='$smp=true;'."\n";
3093 else $s.='$smp=false;'."\n";
3094 if ($BMPonly) $s.='$BMPselected=true;'."\n";
3095 else $s.='$BMPselected=false;'."\n";
3096 $s.='$fontkey=\''.$fontkey."';\n";
3097 $s.='$panose=\''.$panose."';\n";
3098 if ($this->useKerning
) {
3099 $s.='$kerninfo='.var_export($kerninfo,true).";\n";
3100 $s.='$haskerninfo=true;'."\n";
3102 else $s.='$haskerninfo=false;'."\n";
3104 if ($this->fontdata
[$family]['unAGlyphs']) {
3105 $s.='$unAGlyphs=true;'."\n";
3107 else $s.='$unAGlyphs=false;'."\n";
3109 if (is_writable(dirname(_MPDF_TTFONTDATAPATH
.'x'))) {
3110 $fh = fopen(_MPDF_TTFONTDATAPATH
.$fontkey.'.mtx.php',"w");
3111 fwrite($fh,$s,strlen($s));
3113 $fh = fopen(_MPDF_TTFONTDATAPATH
.$fontkey.'.cw.dat',"wb");
3114 fwrite($fh,$cw,strlen($cw));
3116 @unlink(_MPDF_TTFONTDATAPATH
.$fontkey.'.cgm');
3117 @unlink(_MPDF_TTFONTDATAPATH
.$fontkey.'.z');
3118 @unlink(_MPDF_TTFONTDATAPATH
.$fontkey.'.cw127.php');
3119 @unlink(_MPDF_TTFONTDATAPATH
.$fontkey.'.cw');
3121 else if ($this->debugfonts
) { $this
->Error('Cannot write to the font caching directory - '._MPDF_TTFONTDATAPATH
); }
3125 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH
.$fontkey.'.cw.dat');
3128 if (isset($this->fontdata
[$family]['indic']) && $this->fontdata
[$family]['indic']) { $indic
= true; }
3129 else { $indic
= false; }
3130 if (isset($this->fontdata
[$family]['sip-ext']) && $this->fontdata
[$family]['sip-ext']) { $sipext
= $this
->fontdata
[$family
]['sip-ext']; }
3131 else { $sipext
= ''; }
3134 $i = count($this->fonts
)+
$this->extraFontSubsets+
1;
3136 $this->fonts
[$fontkey] = array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'panose'=>$panose, 'up'=>$up, 'ut'=>$ut, 'cw'=>$cw, 'ttffile'=>$ttffile, 'fontkey'=>$fontkey, 'subsets'=>array(0=>range(0,127)), 'subsetfontids'=>array($i), 'used'=>false, 'indic'=>$indic, 'sip'=>$sip, 'sipext'=>$sipext, 'smp'=>$smp, 'TTCfontID' => $TTCfontID, 'unAGlyphs' => false); // mPDF 5.4.05
3140 for ($s=32; $s<128; $s++
) { $ss
[$s
] = $s
; }
3141 $this->fonts
[$fontkey] = array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'panose'=>$panose, 'up'=>$up, 'ut'=>$ut, 'cw'=>$cw, 'ttffile'=>$ttffile, 'fontkey'=>$fontkey, 'subset'=>$ss, 'used'=>false, 'indic'=>$indic, 'sip'=>$sip, 'sipext'=>$sipext, 'smp'=>$smp, 'TTCfontID' => $TTCfontID, 'unAGlyphs' => $unAGlyphs); // mPDF 5.4.05
3143 if ($this->useKerning
&& $haskerninfo) { $this
->fonts
[$fontkey
]['kerninfo'] = $kerninfo
; }
3144 $this->FontFiles
[$fontkey]=array('length1'=>$originalsize, 'type'=>"TTF", 'ttffile'=>$ttffile, 'sip'=>$sip, 'smp'=>$smp);
3150 function SetFont($family,$style='',$size=0, $write=true, $forcewrite=false) {
3151 $family=strtolower($family);
3152 if (!$this->onlyCoreFonts
) {
3153 if ($family == 'sans' || $family == 'sans-serif') { $family
= $this
->sans_fonts
[0]; }
3154 if ($family == 'serif') { $family
= $this
->serif_fonts
[0]; }
3155 if ($family == 'mono' || $family == 'monospace') { $family
= $this
->mono_fonts
[0]; }
3157 if (isset($this->fonttrans
[$family]) && $this->fonttrans
[$family]) { $family
= $this
->fonttrans
[$family
]; }
3159 if ($this->FontFamily
) { $family
=$this
->FontFamily
; }
3160 else if ($this->default_font
) { $family
=$this
->default_font
; }
3161 else { $this
->Error("No font or default font set!"); }
3163 $this->ReqFontStyle
= $style; // required or requested style - used later for artificial bold/italic
3165 if (($family == 'csymbol') || ($family == 'czapfdingbats') || ($family == 'ctimes') || ($family == 'ccourier') || ($family == 'chelvetica')) {
3166 if ($this->PDFA
|| $this->PDFX
) {
3167 if ($family == 'csymbol' || $family == 'czapfdingbats') {
3168 $this->Error("Symbol and Zapfdingbats cannot be embedded in mPDF (required for PDFA1-b or PDFX/1-a).");
3170 if ($family == 'ctimes' || $family == 'ccourier' || $family == 'chelvetica') {
3171 if (($this->PDFA
&& !$this->PDFAauto
) || ($this->PDFX
&& !$this->PDFXauto
)) { $this
->PDFAXwarnings
[] = "Core Adobe font ".ucfirst($family
)." cannot be embedded in mPDF, which is required for PDFA1-b or PDFX/1-a. (Embedded font will be substituted.)"; }
3172 if ($family == 'chelvetica') { $family
= 'sans'; }
3173 if ($family == 'ctimes') { $family
= 'serif'; }
3174 if ($family == 'ccourier') { $family
= 'mono'; }
3176 $this->usingCoreFont
= false;
3178 else { $this
->usingCoreFont
= true; }
3179 if($family=='csymbol' || $family=='czapfdingbats') { $style
=''; }
3181 else { $this
->usingCoreFont
= false; }
3186 $style=strtoupper($style);
3187 if(strpos($style,'U')!==false) {
3189 $style=str_replace('U','',$style);
3191 if(strpos($style,'S')!==false) {
3194 if (empty($this->upperCase
)) { @include(_MPDF_PATH
.'includes/upperCase.php'); }
3195 $style=str_replace('S','',$style);
3197 if ($style=='IB') $style='BI';
3199 if ($size==0) $size=$this->FontSizePt
;
3201 $fontkey=$family.$style;
3204 if (!$stylekey) { $stylekey
= "R"; }
3206 if (!$this->onlyCoreFonts
&& !$this->usingCoreFont
) {
3207 if(!isset($this->fonts
[$fontkey]) || count($this->default_available_fonts
) != count($this->available_unifonts
) ) { // not already added
3210 if (in_array($fontkey,$this->available_CJK_fonts
)) {
3211 if(!isset($this->fonts
[$fontkey])) { // already added
3212 if (empty($this->Big5_widths
)) { require(_MPDF_PATH
. 'includes/CJKdata.php'); }
3213 $this->AddCJKFont($family); // don't need to add style
3216 // Test to see if requested font/style is available - or substitute
3218 /*-- END CJK-FONTS --*/
3219 if (!in_array($fontkey,$this->available_unifonts
)) {
3220 // If font[nostyle] exists - set it
3221 if (in_array($family,$this->available_unifonts
)) {
3225 // Else if only one font available - set it (assumes if only one font available it will not have a style)
3226 else if (count($this->available_unifonts
) == 1) {
3227 $family = $this->available_unifonts
[0];
3233 // else substitute font of similar type
3234 if (in_array($family,$this->sans_fonts
)) {
3235 $i = array_intersect($this->sans_fonts
,$this->available_unifonts
);
3237 $i = array_values($i);
3238 // with requested style if possible
3239 if (!in_array(($i[0].$style),$this->available_unifonts
)) {
3246 else if (in_array($family,$this->serif_fonts
)) {
3247 $i = array_intersect($this->serif_fonts
,$this->available_unifonts
);
3249 $i = array_values($i);
3250 // with requested style if possible
3251 if (!in_array(($i[0].$style),$this->available_unifonts
)) {
3258 else if (in_array($family,$this->mono_fonts
)) {
3259 $i = array_intersect($this->mono_fonts
,$this->available_unifonts
);
3261 $i = array_values($i);
3262 // with requested style if possible
3263 if (!in_array(($i[0].$style),$this->available_unifonts
)) {
3272 // set first available font
3273 $fs = $this->available_unifonts
[0];
3274 preg_match('/^([a-z_0-9\-]+)([BI]{0,2})$/',$fs,$fas); // Allow "-"
3275 // with requested style if possible
3276 $ws = $fas[1].$style;
3277 if (in_array($ws,$this->available_unifonts
)) {
3278 $family = $fas[1]; // leave $style as is
3280 else if (in_array($fas[1],$this->available_unifonts
)) {
3286 // or with the style specified
3292 $fontkey = $family.$style;
3295 // try to add font (if not already added)
3296 $this->AddFont($family, $style);
3298 //Test if font is already selected
3299 if($this->FontFamily
== $family && $this->FontFamily
== $this->currentfontfamily
&& $this->FontStyle
== $style && $this->FontStyle
== $this->currentfontstyle
&& $this->FontSizePt
== $size && $this->FontSizePt
== $this->currentfontsize
&& !$forcewrite) {
3303 $fontkey = $family.$style;
3306 $this->FontFamily
= $family;
3307 $this->FontStyle
= $style;
3308 $this->FontSizePt
= $size;
3309 $this->FontSize
= $size / _MPDFK
;
3310 $this->CurrentFont
= &$this->fonts
[$fontkey];
3312 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont
['i'], $this->FontSizePt
));
3313 if($this->page
>0 && ((isset($this->pageoutput
[$this->page
]['Font']) && $this->pageoutput
[$this->page
]['Font'] != $fontout) || !isset($this->pageoutput
[$this->page
]['Font']) || $this->keep_block_together
)) { $this
->_out($fontout
); }
3314 $this->pageoutput
[$this->page
]['Font'] = $fontout;
3319 // Added - currentfont (lowercase) used in HTML2PDF
3320 $this->currentfontfamily
=$family;
3321 $this->currentfontsize
=$size;
3322 $this->currentfontstyle
=$style.($this->U
? 'U' : '').($this->S
? 'S' : '');
3323 $this->setMBencoding('UTF-8');
3326 else { // if using core fonts
3329 if ($this->PDFA
|| $this->PDFX
) {
3330 $this->Error('Core Adobe fonts cannot be embedded in mPDF (required for PDFA1-b or PDFX/1-a) - cannot use option to use core fonts.');
3332 $this->setMBencoding('windows-1252');
3334 //Test if font is already selected
3335 if(($this->FontFamily
== $family) AND ($this->FontStyle
== $style) AND ($this->FontSizePt
== $size) && !$forcewrite) {
3339 if (!isset($this->CoreFonts
[$fontkey])) {
3340 if (in_array($family,$this->serif_fonts
)) { $family
= 'ctimes'; }
3341 else if (in_array($family,$this->mono_fonts
)) { $family
= 'ccourier'; }
3342 else { $family
= 'chelvetica'; }
3343 $this->usingCoreFont
= true;
3344 $fontkey = $family.$style;
3347 if(!isset($this->fonts
[$fontkey])) {
3348 // STANDARD CORE FONTS
3349 if (isset($this->CoreFonts
[$fontkey])) {
3352 if($family=='ctimes' || $family=='chelvetica' || $family=='ccourier') { $file
.=strtolower($style
); }
3354 include(_MPDF_PATH
.'font/'.$file);
3355 if(!isset($cw)) { $this
->Error('Could not include font metric file'); }
3356 $i=count($this->fonts
)+
$this->extraFontSubsets+
1;
3357 $this->fonts
[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts
[$fontkey],'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw);
3358 if ($this->useKerning
) { $this
->fonts
[$fontkey
]['kerninfo'] = $kerninfo
; }
3361 die('mPDF error - Font not defined');
3364 //Test if font is already selected
3365 if(($this->FontFamily
== $family) AND ($this->FontStyle
== $style) AND ($this->FontSizePt
== $size) && !$forcewrite) {
3369 $this->FontFamily
=$family;
3370 $this->FontStyle
=$style;
3371 $this->FontSizePt
=$size;
3372 $this->FontSize
=$size/_MPDFK
;
3373 $this->CurrentFont
=&$this->fonts
[$fontkey];
3375 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont
['i'], $this->FontSizePt
));
3376 if($this->page
>0 && ((isset($this->pageoutput
[$this->page
]['Font']) && $this->pageoutput
[$this->page
]['Font'] != $fontout) || !isset($this->pageoutput
[$this->page
]['Font']) || $this->keep_block_together
)) { $this
->_out($fontout
); }
3377 $this->pageoutput
[$this->page
]['Font'] = $fontout;
3379 // Added - currentfont (lowercase) used in HTML2PDF
3380 $this->currentfontfamily
=$family;
3381 $this->currentfontsize
=$size;
3382 $this->currentfontstyle
=$style.($this->U
? 'U' : '').($this->S
? 'S' : '');
3389 function SetFontSize($size,$write=true) {
3390 //Set font size in points
3391 if($this->FontSizePt
==$size) return;
3392 $this->FontSizePt
=$size;
3393 $this->FontSize
=$size/_MPDFK
;
3394 $this->currentfontsize
=$size;
3396 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont
['i'], $this->FontSizePt
));
3398 if($this->page
>0 && ((isset($this->pageoutput
[$this->page
]['Font']) && $this->pageoutput
[$this->page
]['Font'] != $fontout) || !isset($this->pageoutput
[$this->page
]['Font']) || $this->keep_block_together
)) { $this
->_out($fontout
); }
3399 $this->pageoutput
[$this->page
]['Font'] = $fontout;
3403 function AddLink() {
3404 //Create a new internal link
3405 $n=count($this->links
)+
1;
3406 $this->links
[$n]=array(0,0);
3410 function SetLink($link,$y=0,$page=-1) {
3411 //Set destination of internal link
3412 if($y==-1) $y=$this->y
;
3413 if($page==-1) $page=$this->page
;
3414 $this->links
[$link]=array($page,$y);
3417 function Link($x,$y,$w,$h,$link) {
3418 $l = array($x*_MPDFK
,$this->hPt
-$y*_MPDFK
,$w*_MPDFK
,$h*_MPDFK
,$link);
3419 if ($this->keep_block_together
) { // Save to array - don't write yet
3420 $this->ktLinks
[$this->page
][]= $l;
3423 else if ($this->table_rotate
) { // *TABLES*
3424 $this->tbrot_Links
[$this->page
][]= $l; // *TABLES*
3427 else if ($this->kwt
) {
3428 $this->kwt_Links
[$this->page
][]= $l;
3432 if ($this->writingHTMLheader
|| $this->writingHTMLfooter
) {
3433 $this->HTMLheaderPageLinks
[]= $l;
3436 //Put a link on the page
3437 $this->PageLinks
[$this->page
][]= $l;
3438 // Save cross-reference to Column buffer
3439 $ref = count($this->PageLinks
[$this->page
])-1; // *COLUMNS*
3440 $this->columnLinks
[$this->CurrCol
][INTVAL($this->x
)][INTVAL($this->y
)] = $ref; // *COLUMNS*
3444 function Text($x,$y,$txt) {
3446 // Called (internally) by Watermark and _tableWrite [rotated cells]
3447 // Expects input to be mb_encoded if necessary and RTL reversed
3449 // ARTIFICIAL BOLD AND ITALIC
3451 if ($this->falseBoldWeight
&& strpos($this->ReqFontStyle
,"B") !== false && strpos($this->FontStyle
,"B") === false) {
3452 $s .= '2 Tr 1 J 1 j ';
3453 $s .= sprintf('%.3F w ',($this->FontSize
/130)*_MPDFK
*$this->falseBoldWeight
);
3454 $tc = strtoupper($this->TextColor
); // change 0 0 0 rg to 0 0 0 RG
3455 if($this->FillColor
!=$tc) { $s
.= $tc
.' '; } // stroke (outline) = same colour as text(fill)
3457 if (strpos($this->ReqFontStyle
,"I") !== false && strpos($this->FontStyle
,"I") === false) {
3458 $aix = '1 0 0.261799 1 %.3F %.3F Tm';
3460 else { $aix
= '%.3F %.3F Td'; }
3462 if($this->ColorFlag
) $s.=$this->TextColor
.' ';
3464 $this->CurrentFont
['used']= true;
3465 if ($this->CurrentFont
['type']=='TTF' && ($this->CurrentFont
['sip'] || $this->CurrentFont
['smp'])) {
3466 $txt2 = str_replace(chr(194).chr(160),chr(32),$txt);
3467 $txt2 = $this->UTF8toSubset($txt2);
3468 $s.=sprintf('BT '.$aix.' %s Tj ET ',$x*_MPDFK
,($this->h
-$y)*_MPDFK
,$txt2);
3470 else if (!$this->usingCoreFont
) {
3471 $txt2 = str_replace(chr(194).chr(160),chr(32),$txt);
3472 $this->UTF8StringToArray($txt2); // this is just to add chars to subset list
3473 if ($this->kerning
&& $this->useKerning
) { $s
.= $this
->_kern($txt2
, '', $aix
, $x
, $y
); }
3475 //Convert string to UTF-16BE without BOM
3476 $txt2= $this->UTF8ToUTF16BE($txt2, false);
3477 $s.=sprintf('BT '.$aix.' (%s) Tj ET ',$x*_MPDFK
,($this->h
-$y)*_MPDFK
,$this->_escape($txt2));
3481 $txt2 = str_replace(chr(160),chr(32),$txt);
3482 if ($this->kerning
&& $this->useKerning
) { $s
.= $this
->_kern($txt2
, '', $aix
, $x
, $y
); }
3484 $s.=sprintf('BT '.$aix.' (%s) Tj ET ',$x*_MPDFK
,($this->h
-$y)*_MPDFK
,$this->_escape($txt2));
3487 if($this->U
&& $txt!='') {
3488 $c = strtoupper($this->TextColor
); // change 0 0 0 rg to 0 0 0 RG
3489 if($this->FillColor
!=$c) { $s
.= ' '.$c
.' '; }
3490 if (isset($this->CurrentFont
['up'])) { $up
=$this
->CurrentFont
['up']; }
3491 else { $up
= -100; }
3492 $adjusty = (-$up/1000* $this->FontSize
);
3493 if (isset($this->CurrentFont
['ut'])) { $ut
=$this
->CurrentFont
['ut']/1000* $this
->FontSize
; }
3494 else { $ut
= 60/1000* $this
->FontSize
; }
3495 $olw = $this->LineWidth
;
3496 $s.=' '.(sprintf(' %.3F w',$ut*_MPDFK
));
3497 $s.=' '.$this->_dounderline($x,$y +
$adjusty,$txt);
3498 $s.=' '.(sprintf(' %.3F w',$olw*_MPDFK
));
3499 if($this->FillColor
!=$c) { $s
.= ' '.$this
->FillColor
.' '; }
3502 if($this->strike
&& $txt!='') {
3503 $c = strtoupper($this->TextColor
); // change 0 0 0 rg to 0 0 0 RG
3504 if($this->FillColor
!=$c) { $s
.= ' '.$c
.' '; }
3505 //Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
3506 if (isset($this->CurrentFont
['desc']['CapHeight'])) { $ch
=$this
->CurrentFont
['desc']['CapHeight']; }
3508 $adjusty = (-$ch/1000* $this->FontSize
) * 0.35;
3509 if (isset($this->CurrentFont
['ut'])) { $ut
=$this
->CurrentFont
['ut']/1000* $this
->FontSize
; }
3510 else { $ut
= 60/1000* $this
->FontSize
; }
3511 $olw = $this->LineWidth
;
3512 $s.=' '.(sprintf(' %.3F w',$ut*_MPDFK
));
3513 $s.=' '.$this->_dounderline($x,$y+
$adjusty,$txt);
3514 $s.=' '.(sprintf(' %.3F w',$olw*_MPDFK
));
3515 if($this->FillColor
!=$c) { $s
.= ' '.$this
->FillColor
.' '; }
3522 function WriteText($x,$y,$txt) {
3523 // Output a string using Text() but does encoding and text reversing of RTL
3524 $txt = $this->purify_utf8_text($txt);
3525 if ($this->text_input_as_HTML
) {
3526 $txt = $this->all_entities_to_utf8($txt);
3528 if ($this->usingCoreFont
) { $txt
= mb_convert_encoding($txt
,$this
->mb_enc
,'UTF-8'); }
3530 if (preg_match("/([".$this->pregRTLchars
."])/u", $txt)) { $this
->biDirectional
= true; } // *RTL*
3531 $this->magic_reverse_dir($txt, true, $this->directionality
); // *RTL*
3532 // Font-specific ligature substitution for Indic fonts
3533 if (isset($this->CurrentFont
['indic']) && $this->CurrentFont
['indic']) $this->ConvertIndic($txt); // *INDIC*
3534 $this->Text($x,$y,$txt);
3537 function WriteCell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='', $currentx=0) {
3538 //Output a cell using Cell() but does encoding and text reversing of RTL
3539 $txt = $this->purify_utf8_text($txt);
3540 if ($this->text_input_as_HTML
) {
3541 $txt = $this->all_entities_to_utf8($txt);
3543 if ($this->usingCoreFont
) { $txt
= mb_convert_encoding($txt
,$this
->mb_enc
,'UTF-8'); }
3545 if (preg_match("/([".$this->pregRTLchars
."])/u", $txt)) { $this
->biDirectional
= true; } // *RTL*
3546 $this->magic_reverse_dir($txt, true, $this->directionality
); // *RTL*
3547 // Font-specific ligature substitution for Indic fonts
3548 if (isset($this->CurrentFont
['indic']) && $this->CurrentFont
['indic']) $this->ConvertIndic($txt); // *INDIC*
3549 $this->Cell($w,$h,$txt,$border,$ln,$align,$fill,$link, $currentx);
3551 /*-- END DIRECTW --*/
3554 function ResetSpacing() {
3555 if ($this->ws
!= 0) { $this
->_out('BT 0 Tw ET'); }
3557 if ($this->charspacing
!= 0) { $this
->_out('BT 0 Tc ET'); }
3558 $this->charspacing
=0;
3562 function SetSpacing($cs,$ws) {
3563 if (intval($cs*1000)==0) { $cs
= 0; }
3564 if ($cs) { $this
->_out(sprintf('BT %.3F Tc ET',$cs
)); }
3565 else if ($this->charspacing
!= 0) { $this
->_out('BT 0 Tc ET'); }
3566 $this->charspacing
=$cs;
3567 if (intval($ws*1000)==0) { $ws
= 0; }
3568 if ($ws) { $this
->_out(sprintf('BT %.3F Tw ET',$ws
)); }
3569 else if ($this->ws
!= 0) { $this
->_out('BT 0 Tw ET'); }
3574 function GetJspacing($nc,$ns,$w,$inclCursive) {
3577 $ww = $this->jSWord
;
3579 if ($nc == 0) { return array(0,0); }
3580 else if ($nc==1) { $charspacing
= $w
; }
3581 // Only word spacing allowed / possible
3582 else if ($this->fixedlSpacing
!== false || $inclCursive) {
3583 if ($ns) { $ws
= $w
/ $ns
; }
3586 $charspacing = $w / ($ncx );
3587 if (($this->jSmaxChar
> 0) && ($charspacing > $this->jSmaxChar
)) {
3588 $charspacing = $this->jSmaxChar
;
3591 else if ($ns == ($ncx )) {
3592 $charspacing = $w / $ns;
3595 if ($this->usingCoreFont
) {
3596 $cs = ($w * (1 - $this->jSWord
)) / ($ncx );
3597 if (($this->jSmaxChar
> 0) && ($cs > $this->jSmaxChar
)) {
3598 $cs = $this->jSmaxChar
;
3599 $ww = 1 - (($cs * ($ncx ))/$w);
3602 $ws = ($w * ($ww) ) / $ns;
3605 $cs = ($w * (1 - $this->jSWord
)) / ($ncx -$ns);
3606 if (($this->jSmaxChar
> 0) && ($cs > $this->jSmaxChar
)) {
3607 $cs = $this->jSmaxChar
;
3608 $ww = 1 - (($cs * ($ncx -$ns))/$w);
3611 $ws = (($w * ($ww) ) / $ns) - $charspacing;
3614 return array($charspacing,$ws);
3617 function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='', $currentx=0, $lcpaddingL=0, $lcpaddingR=0, $valign='M', $spanfill=0, $abovefont=0, $belowfont=0, $exactWidth=false) {
3619 // Expects input to be mb_encoded if necessary and RTL reversed
3620 // NON_BREAKING SPACE
3621 if ($this->usingCoreFont
) {
3622 $txt = str_replace(chr(160),chr(32),$txt);
3625 $txt = str_replace(chr(194).chr(160),chr(32),$txt);
3628 $oldcolumn = $this->CurrCol
;
3629 // Automatic page break
3630 // Allows PAGE-BREAK-AFTER = avoid to work
3632 if (!$this->tableLevel
&& (($this->y+
$this->divheight
>$this->PageBreakTrigger
) || ($this->y+
$h>$this->PageBreakTrigger
) ||
3633 ($this->y+
($h*2)>$this->PageBreakTrigger
&& $this->blk
[$this->blklvl
]['page_break_after_avoid'])) and !$this->InFooter
and $this->AcceptPageBreak()) {
3634 $x=$this->x
;//Current X position
3638 $ws=$this->ws
;//Word Spacing
3639 $charspacing=$this->charspacing
;//Character Spacing
3640 $this->ResetSpacing();
3642 $this->AddPage($this->CurOrientation
);
3643 // Added to correct for OddEven Margins
3644 $x +
= $this->MarginCorrection
;
3646 $currentx +
= $this->MarginCorrection
;
3650 $this->SetSpacing($charspacing,$ws);
3653 // Test: to put line through centre of cell: $this->Line($this->x,$this->y+($h/2),$this->x+50,$this->y+($h/2));
3658 if ($this->CurrCol
!= $oldcolumn) {
3660 $currentx +
= $this->ChangeColumn
* ($this->ColWidth+
$this->ColGap
);
3662 $this->x +
= $this->ChangeColumn
* ($this->ColWidth+
$this->ColGap
);
3665 // COLUMNS Update/overwrite the lowest bottom of printing y value for a column
3666 if ($this->ColActive
) {
3667 if ($h) { $this
->ColDetails
[$this
->CurrCol
]['bottom_margin'] = $this
->y+$h
; }
3668 else { $this
->ColDetails
[$this
->CurrCol
]['bottom_margin'] = $this
->y+$this
->divheight
; }
3670 /*-- END COLUMNS --*/
3672 // KEEP BLOCK TOGETHER Update/overwrite the lowest bottom of printing y value on first page
3673 if ($this->keep_block_together
) {
3674 if ($h) { $this
->ktBlock
[$this
->page
]['bottom_margin'] = $this
->y+$h
; }
3675 // else { $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$this->divheight; }
3678 if($w==0) $w = $this->w
-$this->rMargin
-$this->x
;
3680 if($fill==1 && $this->FillColor
) {
3681 if((isset($this->pageoutput
[$this->page
]['FillColor']) && $this->pageoutput
[$this->page
]['FillColor'] != $this->FillColor
) || !isset($this->pageoutput
[$this->page
]['FillColor']) || $this->keep_block_together
) { $s
.= $this
->FillColor
.' '; }
3682 $this->pageoutput
[$this->page
]['FillColor'] = $this->FillColor
;
3688 $boxbottom = $this->y+
$h;
3691 // FONT SIZE - this determines the baseline caculation
3692 if ($this->linemaxfontsize
&& !$this->processingHeader
) { $bfs
= $this
->linemaxfontsize
; }
3693 else { $bfs
= $this
->FontSize
; }
3694 //Calculate baseline Superscript and Subscript Y coordinate adjustment
3695 $bfx = $this->baselineC
;
3696 $baseline = $bfx*$bfs;
3697 if($this->SUP
) { $baseline +
= ($bfx
-1.05)*$this
->FontSize
; }
3698 else if($this->SUB
) { $baseline +
= ($bfx +
0.04)*$this
->FontSize
; }
3699 else if($this->bullet
) { $baseline +
= ($bfx
-0.7)*$this
->FontSize
; }
3701 // Vertical align (for Images)
3702 if ($abovefont || $belowfont) { // from flowing block - valign always M
3703 $va = $abovefont +
(0.5*$bfs);
3705 else if ($this->lineheight_correction
) {
3706 if ($valign == 'T') { $va
= (0.5 * $bfs
* $this
->lineheight_correction
); }
3707 else if ($valign == 'B') { $va
= $h
-(0.5 * $bfs
* $this
->lineheight_correction
); }
3708 else { $va
= 0.5*$h
; } // Middle
3711 if ($valign == 'T') { $va
= (0.5 * $bfs
* $this
->default_lineheight_correction
); }
3712 else if ($valign == 'B') { $va
= $h
-(0.5 * $bfs
* $this
->default_lineheight_correction
); }
3713 else { $va
= 0.5*$h
; } // Middle
3716 // ONLY SET THESE IF WANT TO CONFINE BORDER +/- FILL TO FIT FONTSIZE - NOT FULL CELL AS IS ORIGINAL FUNCTION
3717 // spanfill or spanborder are set in FlowingBlock functions
3718 if ($spanfill || !empty($this->spanborddet
) || $link!='') {
3719 $exth = 0.2; // Add to fontsize to increase height of background / link / border
3720 $boxtop = $this->y+
$baseline+
$va-($this->FontSize
*(1+
$exth/2)*(0.5+
$bfx));
3721 $boxheight = $this->FontSize
* (1+
$exth);
3722 $boxbottom = $boxtop +
$boxheight;
3726 $bbw = $tbw = $lbw = $rbw = 0; // Border widths
3727 if (!empty($this->spanborddet
)) {
3728 if (!isset($this->spanborddet
['B'])) { $this
->spanborddet
['B'] = array('s' => 0, 'style' => '', 'w' => 0); }
3729 if (!isset($this->spanborddet
['T'])) { $this
->spanborddet
['T'] = array('s' => 0, 'style' => '', 'w' => 0); }
3730 if (!isset($this->spanborddet
['L'])) { $this
->spanborddet
['L'] = array('s' => 0, 'style' => '', 'w' => 0); }
3731 if (!isset($this->spanborddet
['R'])) { $this
->spanborddet
['R'] = array('s' => 0, 'style' => '', 'w' => 0); }
3732 $bbw = $this->spanborddet
['B']['w'];
3733 $tbw = $this->spanborddet
['T']['w'];
3734 $lbw = $this->spanborddet
['L']['w'];
3735 $rbw = $this->spanborddet
['R']['w'];
3737 if($fill==1 || $border==1 || !empty($this->spanborddet
)) {
3738 if (!empty($this->spanborddet
)) {
3740 $s.=sprintf('%.3F %.3F %.3F %.3F re f ',($this->x
-$lbw)*_MPDFK
,($this->h
-$boxtop+
$tbw)*_MPDFK
,($w+
$lbw+
$rbw)*_MPDFK
,(-$boxheight-$tbw-$bbw)*_MPDFK
);
3748 if ($this->spanborddet
['T']['style'] == 'dashed') {
3749 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$tbw*$dashon*_MPDFK
,$tbw*$dashoff*_MPDFK
);
3751 else if ($this->spanborddet
['T']['style'] == 'dotted') {
3752 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$tbw*$dot*_MPDFK
,-$tbw/2*_MPDFK
);
3756 $s.=' 0 j 0 J [] 0 d ';
3758 $c = $this->SetDColor($this->spanborddet
['T']['c'],true);
3759 if ($this->spanborddet
['T']['style'] == 'double') {
3760 $s.=sprintf(' %s %.3F w ',$c,$tbw/3*_MPDFK
);
3762 if ($this->spanborddet
['L']['style'] == 'double') { $xadj
= $this
->spanborddet
['L']['w']*2/3; }
3763 if ($this->spanborddet
['R']['style'] == 'double') { $xadj2
= $this
->spanborddet
['R']['w']*2/3; }
3764 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x
-$lbw)*_MPDFK
,($this->h
-$boxtop+
$tbw*5/6)*_MPDFK
,($this->x+
$w+
$rbw-$short)*_MPDFK
,($this->h
-$boxtop+
$tbw*5/6)*_MPDFK
);
3765 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x
-$lbw+
$xadj)*_MPDFK
,($this->h
-$boxtop+
$tbw/6)*_MPDFK
,($this->x+
$w+
$rbw-$short-$xadj2)*_MPDFK
,($this->h
-$boxtop+
$tbw/6)*_MPDFK
);
3768 $s.=sprintf(' %s %.3F w ',$c,$tbw*_MPDFK
);
3769 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x
-$lbw)*_MPDFK
,($this->h
-$boxtop+
$tbw/2)*_MPDFK
,($this->x+
$w+
$rbw-$short)*_MPDFK
,($this->h
-$boxtop+
$tbw/2)*_MPDFK
);
3774 if ($this->spanborddet
['B']['style'] == 'dashed') {
3775 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$bbw*$dashon*_MPDFK
,$bbw*$dashoff*_MPDFK
);
3777 else if ($this->spanborddet
['B']['style'] == 'dotted') {
3778 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$bbw*$dot*_MPDFK
,-$bbw/2*_MPDFK
);
3782 $s.=' 0 j 0 J [] 0 d ';
3784 $c = $this->SetDColor($this->spanborddet
['B']['c'],true);
3785 if ($this->spanborddet
['B']['style'] == 'double') {
3786 $s.=sprintf(' %s %.3F w ',$c,$bbw/3*_MPDFK
);
3788 if ($this->spanborddet
['L']['style'] == 'double') { $xadj
= $this
->spanborddet
['L']['w']*2/3; }
3789 if ($this->spanborddet
['R']['style'] == 'double') { $xadj2
= $this
->spanborddet
['R']['w']*2/3; }
3790 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x
-$lbw+
$xadj)*_MPDFK
,($this->h
-$boxbottom-$bbw/6)*_MPDFK
,($this->x+
$w+
$rbw-$short-$xadj2)*_MPDFK
,($this->h
-$boxbottom-$bbw/6)*_MPDFK
);
3791 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x
-$lbw)*_MPDFK
,($this->h
-$boxbottom-$bbw*5/6)*_MPDFK
,($this->x+
$w+
$rbw-$short)*_MPDFK
,($this->h
-$boxbottom-$bbw*5/6)*_MPDFK
);
3794 $s.=sprintf(' %s %.3F w ',$c,$bbw*_MPDFK
);
3795 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x
-$lbw)*_MPDFK
,($this->h
-$boxbottom-$bbw/2)*_MPDFK
,($this->x+
$w+
$rbw-$short)*_MPDFK
,($this->h
-$boxbottom-$bbw/2)*_MPDFK
);
3800 if ($this->spanborddet
['L']['style'] == 'dashed') {
3801 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$lbw*$dashon*_MPDFK
,$lbw*$dashoff*_MPDFK
);
3803 else if ($this->spanborddet
['L']['style'] == 'dotted') {
3804 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$lbw*$dot*_MPDFK
,-$lbw/2*_MPDFK
);
3808 $s.=' 0 j 0 J [] 0 d ';
3810 $c = $this->SetDColor($this->spanborddet
['L']['c'],true);
3811 if ($this->spanborddet
['L']['style'] == 'double') {
3812 $s.=sprintf(' %s %.3F w ',$c,$lbw/3*_MPDFK
);
3814 if ($this->spanborddet
['T']['style'] == 'double') { $yadj
= $this
->spanborddet
['T']['w']*2/3; }
3815 if ($this->spanborddet
['B']['style'] == 'double') { $yadj2
= $this
->spanborddet
['B']['w']*2/3; }
3816 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x
-$lbw/6)*_MPDFK
,($this->h
-$boxtop+
$tbw-$yadj)*_MPDFK
,($this->x
-$lbw/6)*_MPDFK
,($this->h
-$boxbottom-$bbw+
$short+
$yadj2)*_MPDFK
);
3817 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x
-$lbw*5/6)*_MPDFK
,($this->h
-$boxtop+
$tbw)*_MPDFK
,($this->x
-$lbw*5/6)*_MPDFK
,($this->h
-$boxbottom-$bbw+
$short)*_MPDFK
);
3820 $s.=sprintf(' %s %.3F w ',$c,$lbw*_MPDFK
);
3821 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x
-$lbw/2)*_MPDFK
,($this->h
-$boxtop+
$tbw)*_MPDFK
,($this->x
-$lbw/2)*_MPDFK
,($this->h
-$boxbottom-$bbw+
$short)*_MPDFK
);
3826 if ($this->spanborddet
['R']['style'] == 'dashed') {
3827 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$rbw*$dashon*_MPDFK
,$rbw*$dashoff*_MPDFK
);
3829 else if ($this->spanborddet
['R']['style'] == 'dotted') {
3830 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$rbw*$dot*_MPDFK
,-$rbw/2*_MPDFK
);
3834 $s.=' 0 j 0 J [] 0 d ';
3836 $c = $this->SetDColor($this->spanborddet
['R']['c'],true);
3837 if ($this->spanborddet
['R']['style'] == 'double') {
3838 $s.=sprintf(' %s %.3F w ',$c,$rbw/3*_MPDFK
);
3840 if ($this->spanborddet
['T']['style'] == 'double') { $yadj
= $this
->spanborddet
['T']['w']*2/3; }
3841 if ($this->spanborddet
['B']['style'] == 'double') { $yadj2
= $this
->spanborddet
['B']['w']*2/3; }
3842 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x+
$w+
$rbw/6)*_MPDFK
,($this->h
-$boxtop+
$tbw-$yadj)*_MPDFK
,($this->x+
$w+
$rbw/6)*_MPDFK
,($this->h
-$boxbottom-$bbw+
$short+
$yadj2)*_MPDFK
);
3843 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x+
$w+
$rbw*5/6)*_MPDFK
,($this->h
-$boxtop+
$tbw)*_MPDFK
,($this->x+
$w+
$rbw*5/6)*_MPDFK
,($this->h
-$boxbottom-$bbw+
$short)*_MPDFK
);
3846 $s.=sprintf(' %s %.3F w ',$c,$rbw*_MPDFK
);
3847 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x+
$w+
$rbw/2)*_MPDFK
,($this->h
-$boxtop+
$tbw)*_MPDFK
,($this->x+
$w+
$rbw/2)*_MPDFK
,($this->h
-$boxbottom-$bbw+
$short)*_MPDFK
);
3853 if ($fill==1) $op=($border==1) ? 'B' : 'f';
3855 $s.=sprintf('%.3F %.3F %.3F %.3F re %s ',$this->x
*_MPDFK
,($this->h
-$boxtop)*_MPDFK
,$w*_MPDFK
,-$boxheight*_MPDFK
,$op);
3859 if(is_string($border)) {
3862 if(is_int(strpos($border,'L')))
3863 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK
,($this->h
-$boxtop)*_MPDFK
,$x*_MPDFK
,($this->h
-($boxbottom))*_MPDFK
);
3864 if(is_int(strpos($border,'T')))
3865 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK
,($this->h
-$boxtop)*_MPDFK
,($x+
$w)*_MPDFK
,($this->h
-$boxtop)*_MPDFK
);
3866 if(is_int(strpos($border,'R')))
3867 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($x+
$w)*_MPDFK
,($this->h
-$boxtop)*_MPDFK
,($x+
$w)*_MPDFK
,($this->h
-($boxbottom))*_MPDFK
);
3868 if(is_int(strpos($border,'B')))
3869 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK
,($this->h
-($boxbottom))*_MPDFK
,($x+
$w)*_MPDFK
,($this->h
-($boxbottom))*_MPDFK
);
3876 $stringWidth = $this->GetStringWidth($txt) +
( $this->charspacing
* mb_strlen( $txt, $this->mb_enc
) / _MPDFK
)
3877 +
( $this->ws
* mb_substr_count( $txt, ' ', $this->mb_enc
) / _MPDFK
);
3879 // Set x OFFSET FOR PRINTING
3881 $dx=$w-$this->cMarginR
- $stringWidth - $lcpaddingR;
3883 elseif($align=='C') {
3884 $dx=(($w - $stringWidth )/2);
3886 elseif($align=='L' or $align=='J') $dx=$this->cMarginL +
$lcpaddingL;
3889 if($this->ColorFlag
) $s .='q '.$this->TextColor
.' ';
3892 if($this->textparam
['outline-s'] && !$this->S
) { // mPDF 5.6.07
3893 $s .=' '.sprintf('%.3F w',$this->LineWidth
*_MPDFK
).' ';
3894 $s .=" $this->DrawColor ";
3897 else if ($this->falseBoldWeight
&& strpos($this->ReqFontStyle
,"B") !== false && strpos($this->FontStyle
,"B") === false && !$this->S
) { // can't use together with OUTLINE or Small Caps
3898 $s .= ' 2 Tr 1 J 1 j ';
3899 $s .= ' '.sprintf('%.3F w',($this->FontSize
/130)*_MPDFK
*$this->falseBoldWeight
).' ';
3900 $tc = strtoupper($this->TextColor
); // change 0 0 0 rg to 0 0 0 RG
3901 if($this->FillColor
!=$tc) { $s
.= ' '.$tc
.' '; } // stroke (outline) = same colour as text(fill)
3903 else { $s
.=" 0 Tr "; } // mPDF 5.6.07
3905 if (strpos($this->ReqFontStyle
,"I") !== false && strpos($this->FontStyle
,"I") === false) { // Artificial italic
3906 $aix = '1 0 0.261799 1 %.3F %.3F Tm ';
3908 else { $aix
= '%.3F %.3F Td '; }
3912 $this->CurrentFont
['used']= true;
3915 // IF multibyte - Tw has no effect - need to use alternative method - do word spacing using an adjustment before each space
3916 if ($this->ws
&& !$this->usingCoreFont
&& !$this->CurrentFont
['sip'] && !$this->CurrentFont
['smp'] && !$this->S
) {
3917 $sub .= ' BT 0 Tw ET ';
3918 if ($this->kerning
&& $this->useKerning
) { $sub
.= $this
->_kern($txt
, 'MBTw', $aix
, ($this
->x+$dx
), ($this
->y+$baseline+$va
)); }
3921 //Convert string to UTF-16BE without BOM
3922 $space= $this->UTF8ToUTF16BE($space , false);
3923 $space=$this->_escape($space );
3924 $sub .=sprintf('BT '.$aix,($this->x+
$dx)*_MPDFK
,($this->h
-($this->y+
$baseline+
$va))*_MPDFK
);
3925 $t = explode(' ',$txt);
3926 $sub .=sprintf(' %.3F Tc [',$this->charspacing
);
3928 for($i=0;$i<$numt;$i++
) {
3930 //Convert string to UTF-16BE without BOM
3931 $tx = $this->UTF8ToUTF16BE($tx , false);
3932 $tx = $this->_escape($tx);
3933 $sub .=sprintf('(%s) ',$tx);
3935 $adj = -($this->ws
)*1000/$this->FontSizePt
;
3936 $sub .=sprintf('%d(%s) ',$adj,$space);
3945 if ($this->CurrentFont
['type']=='TTF' && ($this->CurrentFont
['sip'] || $this->CurrentFont
['smp'])) {
3946 if ($this->S
) { $sub
.= $this
->_smallCaps($txt2
, 'SIPSMP', $aix
, $dx
, _MPDFK
, $baseline
, $va
); }
3948 $txt2 = $this->UTF8toSubset($txt2);
3949 $sub .=sprintf('BT '.$aix.' %s Tj ET',($this->x+
$dx)*_MPDFK
,($this->h
-($this->y+
$baseline+
$va))*_MPDFK
,$txt2);
3953 if ($this->S
) { $sub
.= $this
->_smallCaps($txt2
, '', $aix
, $dx
, _MPDFK
, $baseline
, $va
); }
3954 else if ($this->kerning
&& $this->useKerning
) { $sub
.= $this
->_kern($txt2
, '', $aix
, ($this
->x+$dx
), ($this
->y+$baseline+$va
)); }
3956 if (!$this->usingCoreFont
) {
3957 $txt2 = $this->UTF8ToUTF16BE($txt2, false);
3959 $txt2=$this->_escape($txt2);
3960 $sub .=sprintf('BT '.$aix.' (%s) Tj ET',($this->x+
$dx)*_MPDFK
,($this->h
-($this->y+
$baseline+
$va))*_MPDFK
,$txt2);
3966 $c = strtoupper($this->TextColor
); // change 0 0 0 rg to 0 0 0 RG
3967 if($this->FillColor
!=$c) { $sub
.= ' '.$c
.' '; }
3968 if (isset($this->CurrentFont
['up'])) { $up
=$this
->CurrentFont
['up']; }
3969 else { $up
= -100; }
3970 $adjusty = (-$up/1000* $this->FontSize
);
3971 if (isset($this->CurrentFont
['ut'])) { $ut
=$this
->CurrentFont
['ut']/1000* $this
->FontSize
; }
3972 else { $ut
= 60/1000* $this
->FontSize
; }
3973 $olw = $this->LineWidth
;
3974 $sub .=' '.(sprintf(' %.3F w 0 j 0 J ',$ut*_MPDFK
));
3975 $sub .=' '.$this->_dounderline($this->x+
$dx,$this->y+
$baseline+
$va+
$adjusty,$txt);
3976 $sub .=' '.(sprintf(' %.3F w 2 j 2 J ',$olw*_MPDFK
));
3977 if($this->FillColor
!=$c) { $sub
.= ' '.$this
->FillColor
.' '; }
3982 $c = strtoupper($this->TextColor
); // change 0 0 0 rg to 0 0 0 RG
3983 if($this->FillColor
!=$c) { $sub
.= ' '.$c
.' '; }
3984 //Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
3985 if (isset($this->CurrentFont
['desc']['CapHeight'])) { $ch
=$this
->CurrentFont
['desc']['CapHeight']; }
3987 $adjusty = (-$ch/1000* $this->FontSize
) * 0.35;
3988 if (isset($this->CurrentFont
['ut'])) { $ut
=$this
->CurrentFont
['ut']/1000* $this
->FontSize
; }
3989 else { $ut
= 60/1000* $this
->FontSize
; }
3990 $olw = $this->LineWidth
;
3991 $sub .=' '.(sprintf(' %.3F w 0 j 0 J ',$ut*_MPDFK
));
3992 $sub .=' '.$this->_dounderline($this->x+
$dx,$this->y+
$baseline+
$va+
$adjusty,$txt);
3993 $sub .=' '.(sprintf(' %.3F w 2 j 2 J ',$olw*_MPDFK
));
3994 if($this->FillColor
!=$c) { $sub
.= ' '.$this
->FillColor
.' '; }
3998 if ($this->textshadow
) { // First to process is last in CSS comma separated shadows
3999 foreach($this->textshadow
AS $ts) {
4001 $s .= $this->SetTColor($ts['col'], true)."\n";
4002 if ($ts['col']{0}==5 && ord($ts['col']{4})<100) { // RGBa
4003 $s .= $this->SetAlpha(ord($ts['col']{4})/100, 'Normal', true, 'F')."\n";
4005 else if ($ts['col']{0}==6 && ord($ts['col']{5})<100) { // CMYKa
4006 $s .= $this->SetAlpha(ord($ts['col']{5})/100, 'Normal', true, 'F')."\n";
4008 else if ($ts['col']{0}==1 && $ts['col']{2}==1 && ord($ts['col']{3})<100) { // Gray
4009 $s .= $this->SetAlpha(ord($ts['col']{3})/100, 'Normal', true, 'F')."\n";
4011 $s .= sprintf(' 1 0 0 1 %.4F %.4F cm', $ts['x']*_MPDFK
, -$ts['y']*_MPDFK
)."\n";
4020 if($this->ColorFlag
) $s .=' Q';
4024 $this->Link($this->x
,$boxtop,$w,$boxheight,$link);
4027 if($s) $this->_out($s);
4030 if ($this->ws
&& !$this->usingCoreFont
) {
4031 $this->_out(sprintf('BT %.3F Tc ET',$this->charspacing
));
4034 if( strpos($txt,"\n") !== false) $ln=1; // cell recognizes \n from <BR> tag
4041 if ($currentx != 0) { $this
->x
=$currentx
; }
4042 else { $this
->x
=$this
->lMargin
; }
4051 function _kern($txt, $mode, $aix, $x, $y) {
4052 if ($mode == 'MBTw') { // Multibyte requiring word spacing
4054 //Convert string to UTF-16BE without BOM
4055 $space= $this->UTF8ToUTF16BE($space , false);
4056 $space=$this->_escape($space );
4057 $s = sprintf(' BT '.$aix,$x*_MPDFK
,($this->h
-$y)*_MPDFK
);
4058 $t = explode(' ',$txt);
4059 for($i=0;$i<count($t);$i++
) {
4063 $unicode = $this->UTF8StringToArray($tx);
4064 for($ti=0;$ti<count($unicode);$ti++
) {
4065 if ($ti > 0 && isset($this->CurrentFont
['kerninfo'][$unicode[($ti-1)]][$unicode[$ti]])) {
4066 $kern = -$this->CurrentFont
['kerninfo'][$unicode[($ti-1)]][$unicode[$ti]];
4067 $tj .= sprintf(')%d(',$kern);
4069 $tc = code2utf($unicode[$ti]);
4070 $tc = $this->UTF8ToUTF16BE($tc, false);
4071 $tj .= $this->_escape($tc);
4074 $s.=sprintf(' %.3F Tc [%s] TJ',$this->charspacing
,$tj);
4077 if (($i+
1)<count($t)) {
4078 $s.=sprintf(' %.3F Tc (%s) Tj',$this->ws+
$this->charspacing
,$space);
4083 else if (!$this->usingCoreFont
) {
4086 $unicode = $this->UTF8StringToArray($txt);
4087 for($i=0;$i<count($unicode);$i++
) {
4088 if ($i > 0 && isset($this->CurrentFont
['kerninfo'][$unicode[($i-1)]][$unicode[$i]])) {
4089 $kern = -$this->CurrentFont
['kerninfo'][$unicode[($i-1)]][$unicode[$i]];
4090 $tj .= sprintf(')%d(',$kern);
4092 $tx = code2utf($unicode[$i]);
4093 $tx = $this->UTF8ToUTF16BE($tx, false);
4094 $tj .= $this->_escape($tx);
4097 $s.=sprintf(' BT '.$aix.' [%s] TJ ET ',$x*_MPDFK
,($this->h
-$y)*_MPDFK
,$tj);
4103 for($i=0;$i<$l;$i++
) {
4104 if ($i > 0 && isset($this->CurrentFont
['kerninfo'][$txt[($i-1)]][$txt[$i]])) {
4105 $kern = -$this->CurrentFont
['kerninfo'][$txt[($i-1)]][$txt[$i]];
4106 $tj .= sprintf(')%d(',$kern);
4108 $tj .= $this->_escape($txt[$i]);
4111 $s.=sprintf(' BT '.$aix.' [%s] TJ ET ',$x*_MPDFK
,($this->h
-$y)*_MPDFK
,$tj);
4118 function _smallCaps($txt, $mode, $aix, $dx, $k, $baseline, $va) {
4122 if (!$this->usingCoreFont
) {
4123 $unicode = $this->UTF8StringToArray($txt);
4124 foreach($unicode as $char) {
4125 if ($this->ws
&& $char == 32) { // space
4126 if (count($str)) { $bits
[] = array($upp
, $str
, false); }
4127 $bits[] = array(false, array(32), true);
4131 else if (isset($this->upperCase
[$char])) {
4133 if (count($str)) { $bits
[] = array($upp
, $str
, false); }
4136 $str[] = $this->upperCase
[$char];
4137 if ((!isset($this->CurrentFont
['sip']) || !$this->CurrentFont
['sip']) && (!isset($this->CurrentFont
['smp']) || !$this->CurrentFont
['smp'])) {
4138 $this->CurrentFont
['subset'][$this->upperCase
[$char]] = $this->upperCase
[$char];
4144 if (count($str)) { $bits
[] = array($upp
, $str
, false); }
4153 for($i=0;$i<strlen($txt);$i++
) {
4154 if (isset($this->upperCase
[ord($txt[$i])]) && $this->upperCase
[ord($txt[$i])] < 256) {
4156 if (count($str)) { $bits
[] = array($upp
, $str
, false); }
4159 $str[] = $this->upperCase
[ord($txt[$i])];
4164 if (count($str)) { $bits
[] = array($upp
, $str
, false); }
4167 $str[] = ord($txt[$i]);
4172 if (count($str)) { $bits
[] = array($upp
, $str
, false); }
4174 $fid = $this->CurrentFont
['i'];
4176 $s=sprintf(' BT '.$aix,($this->x+
$dx)*$k,($this->h
-($this->y+
$baseline+
$va))*$k);
4177 foreach($bits AS $b) {
4178 if ($b[0]) { $upp
= true; }
4179 else { $upp
= false; }
4181 $size = count ($b[1]);
4183 for ($i = 0; $i < $size; $i++
) {
4184 $txt .= code2utf($b[1][$i]);
4186 if ($this->usingCoreFont
) {
4187 $txt = utf8_decode($txt);
4189 if ($mode == 'SIPSMP') {
4190 $txt = $this->UTF8toSubset($txt);
4193 if (!$this->usingCoreFont
) {
4194 $txt = $this->UTF8ToUTF16BE($txt, false);
4196 $txt=$this->_escape($txt);
4197 $txt = '('.$txt.')';
4199 if ($b[2]) { // space
4200 $s.=sprintf(' /F%d %.3F Tf %d Tz', $fid, $this->FontSizePt
, 100);
4201 $s.=sprintf(' %.3F Tc', ($this->charspacing+
$this->ws
));
4202 $s.=sprintf(' %s Tj', $txt);
4205 $s.=sprintf(' /F%d %.3F Tf', $fid, $this->FontSizePt
*$this->smCapsScale
);
4206 $s.=sprintf(' %d Tz', $this->smCapsStretch
);
4207 $s.=sprintf(' %.3F Tc', ($this->charspacing
*100/$this->smCapsStretch
));
4208 $s.=sprintf(' %s Tj', $txt);
4211 $s.=sprintf(' /F%d %.3F Tf %d Tz', $fid, $this->FontSizePt
, 100);
4212 $s.=sprintf(' %.3F Tc', ($this->charspacing
));
4213 $s.=sprintf(' %s Tj', $txt);
4221 function MultiCell($w,$h,$txt,$border=0,$align='',$fill=0,$link='',$directionality='ltr',$encoded=false)
4223 // Parameter (pre-)encoded - When called internally from ToC or textarea: mb_encoding already done - but not reverse RTL/Indic
4225 $txt = $this->purify_utf8_text($txt);
4226 if ($this->text_input_as_HTML
) {
4227 $txt = $this->all_entities_to_utf8($txt);
4229 if ($this->usingCoreFont
) { $txt
= mb_convert_encoding($txt
,$this
->mb_enc
,'UTF-8'); }
4230 // Font-specific ligature substitution for Indic fonts
4231 else if (isset($this->CurrentFont
['indic']) && $this->CurrentFont
['indic']) { // *INDIC*
4232 $this->ConvertIndic($tmp); // *INDIC*
4234 if (preg_match("/([".$this->pregRTLchars
."])/u", $txt)) { $this
->biDirectional
= true; } // *RTL*
4236 if (!$align) { $align
= $this
->defaultAlign
; }
4238 //Output text with automatic or explicit line breaks
4239 $cw=&$this->CurrentFont
['cw'];
4240 if($w==0) $w=$this->w
-$this->rMargin
-$this->x
;
4242 $wmax = ($w - ($this->cMarginL+
$this->cMarginR
));
4243 if ($this->usingCoreFont
) {
4244 $s=str_replace("\r",'',$txt);
4246 while($nb>0 and $s[$nb-1]=="\n") $nb--;
4249 $s=str_replace("\r",'',$txt);
4250 $nb=mb_strlen($s, $this->mb_enc
);
4251 while($nb>0 and mb_substr($s,$nb-1,1,$this->mb_enc
)=="\n") $nb--;
4262 if(is_int(strpos($border,'L'))) $b2.='L';
4263 if(is_int(strpos($border,'R'))) $b2.='R';
4264 $b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
4276 if (!$this->usingCoreFont
) {
4277 $checkCursive=false;
4278 if ($this->biDirectional
) { $checkCursive
=true; }
4279 else if (isset($this->CurrentFont
['indic']) && $this->CurrentFont
['indic']) { $checkCursive
=true; } // *INDIC*
4281 //Get next character
4282 $c = mb_substr($s,$i,1,$this->mb_enc
);
4284 //Explicit line break
4286 $this->ResetSpacing();
4287 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc
));
4289 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4291 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4298 if($border and $nl==2) $b=$b2;
4307 $l +
= $this->GetCharWidthNonCore($c);
4310 //Automatic line break
4311 if($sep==-1) { // Only one word
4314 $this->ResetSpacing();
4315 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc
));
4317 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4319 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4322 $tmp = rtrim(mb_substr($s,$j,$sep-$j,$this->mb_enc
));
4324 //////////////////////////////////////////
4325 // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
4326 // WORD SPACING UNICODE
4327 // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
4328 $tmp = str_replace(chr(194).chr(160),chr(32),$tmp );
4329 $len_ligne = $this->GetStringWidth($tmp );
4330 $nb_carac = mb_strlen( $tmp , $this->mb_enc
) ;
4331 $nb_spaces = mb_substr_count( $tmp ,' ', $this->mb_enc
) ;
4334 if ($checkCursive) {
4335 if (preg_match("/([".$this->pregRTLchars
."])/u", $tmp)) { $inclCursive
= true; } // *RTL*
4336 if (preg_match("/([".$this->pregHIchars
.$this->pregBNchars
.$this->pregPAchars
."])/u", $tmp)) { $inclCursive
= true; } // *INDIC*
4338 list($charspacing,$ws) = $this->GetJspacing($nb_carac,$nb_spaces,((($wmax) - $len_ligne) * _MPDFK
),$inclCursive);
4339 $this->SetSpacing($charspacing,$ws);
4340 //////////////////////////////////////////
4344 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4346 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4354 if($border and $nl==2) $b=$b2;
4361 $this->ResetSpacing();
4369 //Get next character
4372 //Explicit line break
4374 $this->ResetSpacing();
4375 $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
4382 if($border and $nl==2) $b=$b2;
4391 $l +
= $this->GetCharWidthCore($c);
4393 //Automatic line break
4397 $this->ResetSpacing();
4398 $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
4402 $tmp = rtrim(substr($s,$j,$sep-$j));
4403 //////////////////////////////////////////
4404 // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
4405 // WORD SPACING NON_UNICDOE/CJK
4406 // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
4407 $tmp = str_replace(chr(160),chr(32),$tmp);
4408 $len_ligne = $this->GetStringWidth($tmp );
4409 $nb_carac = strlen( $tmp ) ;
4410 $nb_spaces = substr_count( $tmp ,' ' ) ;
4411 list($charspacing,$ws) = $this->GetJspacing($nb_carac,$nb_spaces,((($wmax) - $len_ligne) * _MPDFK
),false);
4412 $this->SetSpacing($charspacing,$ws);
4413 //////////////////////////////////////////
4415 $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill,$link);
4423 if($border and $nl==2) $b=$b2;
4430 $this->ResetSpacing();
4434 if($border and is_int(strpos($border,'B'))) $b.='B';
4435 if (!$this->usingCoreFont
) {
4436 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc
));
4438 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4439 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4441 else { $this
->Cell($w
,$h
,substr($s
,$j
,$i
-$j
),$b
,2,$align
,$fill
,$link
); }
4442 $this->x
=$this->lMargin
;
4447 function Write($h,$txt,$currentx=0,$link='',$directionality='ltr',$align='') {
4448 if (!class_exists('directw', false)) { include(_MPDF_PATH
.'classes/directw.php'); }
4449 if (empty($this->directw
)) { $this
->directw
= new directw($this
); }
4450 $this->directw
->Write($h,$txt,$currentx,$link,$directionality,$align);
4452 /*-- END DIRECTW --*/
4456 function saveInlineProperties() {
4458 $saved[ 'family' ] = $this->FontFamily
;
4459 $saved[ 'style' ] = $this->FontStyle
;
4460 $saved[ 'sizePt' ] = $this->FontSizePt
;
4461 $saved[ 'size' ] = $this->FontSize
;
4462 $saved[ 'HREF' ] = $this->HREF
;
4463 $saved[ 'underline' ] = $this->U
;
4464 $saved[ 'smCaps' ] = $this->S
;
4465 $saved[ 'strike' ] = $this->strike
;
4466 $saved[ 'textshadow' ] = $this->textshadow
;
4467 $saved[ 'SUP' ] = $this->SUP
;
4468 $saved[ 'SUB' ] = $this->SUB
;
4469 $saved[ 'linewidth' ] = $this->LineWidth
;
4470 $saved[ 'drawcolor' ] = $this->DrawColor
;
4471 $saved[ 'textparam' ] = $this->textparam
;
4472 $saved[ 'toupper' ] = $this->toupper
;
4473 $saved[ 'tolower' ] = $this->tolower
;
4474 $saved[ 'capitalize' ] = $this->capitalize
;
4475 $saved[ 'fontkerning' ] = $this->kerning
;
4476 $saved[ 'lSpacingCSS' ] = $this->lSpacingCSS
;
4477 $saved[ 'wSpacingCSS' ] = $this->wSpacingCSS
;
4478 $saved[ 'I' ] = $this->I
;
4479 $saved[ 'B' ] = $this->B
;
4480 $saved[ 'colorarray' ] = $this->colorarray
;
4481 $saved[ 'bgcolorarray' ] = $this->spanbgcolorarray
;
4482 $saved[ 'border' ] = $this->spanborddet
;
4483 $saved[ 'color' ] = $this->TextColor
;
4484 $saved[ 'bgcolor' ] = $this->FillColor
;
4485 $saved[ 'lang' ] = $this->currentLang
;
4486 $saved[ 'display_off' ] = $this->inlineDisplayOff
;
4491 function restoreInlineProperties( &$saved) {
4492 $FontFamily = $saved[ 'family' ];
4493 $this->FontStyle
= $saved[ 'style' ];
4494 $this->FontSizePt
= $saved[ 'sizePt' ];
4495 $this->FontSize
= $saved[ 'size' ];
4497 $this->currentLang
= $saved['lang'];
4498 if ($this->useLang
&& !$this->usingCoreFont
) {
4499 if ($this->currentLang
!= $this->default_lang
&& ((strlen($this->currentLang
) == 5 && $this->currentLang
!= 'UTF-8') || strlen($this->currentLang
) == 2)) {
4500 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($this->currentLang
, $this->useAdobeCJK
);
4501 if ($mpdf_pdf_unifonts) { $this
->RestrictUnicodeFonts($mpdf_pdf_unifonts
); }
4502 else { $this
->RestrictUnicodeFonts($this
->default_available_fonts
); }
4505 $this->RestrictUnicodeFonts($this->default_available_fonts
);
4509 $this->ColorFlag
= ($this->FillColor
!= $this->TextColor
); //Restore ColorFlag as well
4511 $this->HREF
= $saved[ 'HREF' ];
4512 $this->U
= $saved[ 'underline' ];
4513 $this->S
= $saved[ 'smCaps' ];
4514 $this->strike
= $saved[ 'strike' ];
4515 $this->textshadow
= $saved[ 'textshadow' ];
4516 $this->SUP
= $saved[ 'SUP' ];
4517 $this->SUB
= $saved[ 'SUB' ];
4518 $this->LineWidth
= $saved[ 'linewidth' ];
4519 $this->DrawColor
= $saved[ 'drawcolor' ];
4520 $this->textparam
= $saved[ 'textparam' ];
4521 $this->inlineDisplayOff
= $saved['display_off'];
4523 $this->toupper
= $saved[ 'toupper' ];
4524 $this->tolower
= $saved[ 'tolower' ];
4525 $this->capitalize
= $saved[ 'capitalize' ];
4526 $this->kerning
= $saved[ 'fontkerning' ];
4527 $this->lSpacingCSS
= $saved[ 'lSpacingCSS' ];
4528 if (($this->lSpacingCSS
|| $this->lSpacingCSS
==='0') && strtoupper($this->lSpacingCSS
) != 'NORMAL') {
4529 $this->fixedlSpacing
= $this->ConvertSize($this->lSpacingCSS
,$this->FontSize
);
4531 else { $this
->fixedlSpacing
= false; }
4532 $this->wSpacingCSS
= $saved[ 'wSpacingCSS' ];
4533 if ($this->wSpacingCSS
&& strtoupper($this->wSpacingCSS
) != 'NORMAL') {
4534 $this->minwSpacing
= $this->ConvertSize($this->wSpacingCSS
,$this->FontSize
);
4536 else { $this
->minwSpacing
= 0; }
4538 $this->SetFont($FontFamily, $saved[ 'style' ].($this->U
? 'U' : '').($this->S
? 'S' : ''),$saved[ 'sizePt' ],false);
4540 $this->currentfontstyle
= $saved[ 'style' ].($this->U
? 'U' : '').($this->S
? 'S' : '');
4541 $this->currentfontsize
= $saved[ 'sizePt' ];
4542 $this->SetStylesArray(array('S'=>$this->S
, 'U'=>$this->U
, 'B'=>$saved[ 'B' ], 'I'=>$saved[ 'I' ]));
4544 $this->TextColor
= $saved[ 'color' ];
4545 $this->FillColor
= $saved[ 'bgcolor' ];
4546 $this->colorarray
= $saved[ 'colorarray' ];
4547 $cor = $saved[ 'colorarray' ];
4548 if ($cor) $this->SetTColor($cor);
4549 $this->spanbgcolorarray
= $saved[ 'bgcolorarray' ];
4550 $cor = $saved[ 'bgcolorarray' ];
4551 if ($cor) $this->SetFColor($cor);
4552 $this->spanborddet
= $saved[ 'border' ];
4557 // Used when ColActive for tables - updated to return first block with background fill OR borders
4558 function GetFirstBlockFill() {
4559 // Returns the first blocklevel that uses a bgcolor fill
4561 for ($i=1;$i<=$this->blklvl
;$i++
) {
4562 if ($this->blk
[$i]['bgcolor'] || $this->blk
[$i]['border_left']['w'] || $this->blk
[$i]['border_right']['w'] || $this->blk
[$i]['border_top']['w'] || $this->blk
[$i]['border_bottom']['w'] ) {
4570 function SetBlockFill($blvl) {
4571 if ($this->blk
[$blvl]['bgcolor']) {
4572 $this->SetFColor($this->blk
[$blvl]['bgcolorarray']);
4576 $this->SetFColor($this->ConvertColor(255));
4582 //-------------------------FLOWING BLOCK------------------------------------//
4583 //The following functions were originally written by Damon Kohler //
4584 //--------------------------------------------------------------------------//
4586 function saveFont() {
4588 $saved[ 'family' ] = $this->FontFamily
;
4589 $saved[ 'style' ] = $this->FontStyle
;
4590 $saved[ 'sizePt' ] = $this->FontSizePt
;
4591 $saved[ 'size' ] = $this->FontSize
;
4592 $saved[ 'curr' ] = &$this->CurrentFont
;
4593 $saved[ 'color' ] = $this->TextColor
;
4594 $saved[ 'spanbgcolor' ] = $this->spanbgcolor
;
4595 $saved[ 'spanbgcolorarray' ] = $this->spanbgcolorarray
;
4596 $saved[ 'bord' ] = $this->spanborder
;
4597 $saved[ 'border' ] = $this->spanborddet
;
4598 $saved[ 'HREF' ] = $this->HREF
;
4599 $saved[ 'underline' ] = $this->U
;
4600 $saved[ 'smCaps' ] = $this->S
;
4601 $saved[ 'strike' ] = $this->strike
;
4602 $saved[ 'textshadow' ] = $this->textshadow
;
4603 $saved[ 'SUP' ] = $this->SUP
;
4604 $saved[ 'SUB' ] = $this->SUB
;
4605 $saved[ 'linewidth' ] = $this->LineWidth
;
4606 $saved[ 'drawcolor' ] = $this->DrawColor
;
4607 $saved[ 'textparam' ] = $this->textparam
;
4608 $saved[ 'ReqFontStyle' ] = $this->ReqFontStyle
;
4609 $saved[ 'fontkerning' ] = $this->kerning
;
4610 $saved[ 'fixedlSpacing' ] = $this->fixedlSpacing
;
4611 $saved[ 'minwSpacing' ] = $this->minwSpacing
;
4615 function restoreFont( &$saved, $write=true) {
4616 if (!isset($saved) || empty($saved)) return;
4618 $this->FontFamily
= $saved[ 'family' ];
4619 $this->FontStyle
= $saved[ 'style' ];
4620 $this->FontSizePt
= $saved[ 'sizePt' ];
4621 $this->FontSize
= $saved[ 'size' ];
4622 $this->CurrentFont
= &$saved[ 'curr' ];
4623 $this->TextColor
= $saved[ 'color' ];
4624 $this->spanbgcolor
= $saved[ 'spanbgcolor' ];
4625 $this->spanbgcolorarray
= $saved[ 'spanbgcolorarray' ];
4626 $this->spanborder
= $saved[ 'bord' ];
4627 $this->spanborddet
= $saved[ 'border' ];
4628 $this->ColorFlag
= ($this->FillColor
!= $this->TextColor
); //Restore ColorFlag as well
4629 $this->HREF
= $saved[ 'HREF' ];
4630 $this->U
= $saved[ 'underline' ];
4631 $this->S
= $saved[ 'smCaps' ];
4632 $this->kerning
= $saved[ 'fontkerning' ];
4633 $this->fixedlSpacing
= $saved[ 'fixedlSpacing' ];
4634 $this->minwSpacing
= $saved[ 'minwSpacing' ];
4635 $this->strike
= $saved[ 'strike' ];
4636 $this->textshadow
= $saved[ 'textshadow' ];
4637 $this->SUP
= $saved[ 'SUP' ];
4638 $this->SUB
= $saved[ 'SUB' ];
4639 $this->LineWidth
= $saved[ 'linewidth' ];
4640 $this->DrawColor
= $saved[ 'drawcolor' ];
4641 $this->textparam
= $saved[ 'textparam' ];
4643 $this->SetFont($saved[ 'family' ],$saved[ 'style' ].($this->U
? 'U' : '').($this->S
? 'S' : ''),$saved[ 'sizePt' ],true,true); // force output
4644 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont
['i'], $this->FontSizePt
));
4645 if($this->page
>0 && ((isset($this->pageoutput
[$this->page
]['Font']) && $this->pageoutput
[$this->page
]['Font'] != $fontout) || !isset($this->pageoutput
[$this->page
]['Font']) || $this->keep_block_together
)) { $this
->_out($fontout
); }
4646 $this->pageoutput
[$this->page
]['Font'] = $fontout;
4649 $this->SetFont($saved[ 'family' ],$saved[ 'style' ].($this->U
? 'U' : '').($this->S
? 'S' : ''),$saved[ 'sizePt' ]);
4650 $this->ReqFontStyle
= $saved[ 'ReqFontStyle' ];
4653 function newFlowingBlock( $w, $h, $a = '', $is_table = false, $is_list = false, $blockstate = 0, $newblock=true, $blockdir='ltr')
4656 if ($blockdir=='rtl') { $a
= 'R'; }
4659 $this->flowingBlockAttr
[ 'width' ] = ($w * _MPDFK
);
4660 // line height in user units
4661 $this->flowingBlockAttr
[ 'is_table' ] = $is_table;
4662 $this->flowingBlockAttr
[ 'is_list' ] = $is_list;
4663 $this->flowingBlockAttr
[ 'height' ] = $h;
4664 $this->flowingBlockAttr
[ 'lineCount' ] = 0;
4665 $this->flowingBlockAttr
[ 'align' ] = $a;
4666 $this->flowingBlockAttr
[ 'font' ] = array();
4667 $this->flowingBlockAttr
[ 'content' ] = array();
4668 $this->flowingBlockAttr
[ 'contentB' ] = array();
4669 $this->flowingBlockAttr
[ 'contentWidth' ] = 0;
4670 $this->flowingBlockAttr
[ 'blockstate' ] = $blockstate;
4672 $this->flowingBlockAttr
[ 'newblock' ] = $newblock;
4673 $this->flowingBlockAttr
[ 'valign' ] = 'M';
4674 $this->flowingBlockAttr
['blockdir'] = $blockdir;
4678 function finishFlowingBlock($endofblock=false, $next='') {
4679 $currentx = $this->x
;
4680 //prints out the last chunk
4681 $is_table = $this->flowingBlockAttr
[ 'is_table' ];
4682 $is_list = $this->flowingBlockAttr
[ 'is_list' ];
4683 $maxWidth =& $this->flowingBlockAttr
[ 'width' ];
4684 $lineHeight =& $this->flowingBlockAttr
[ 'height' ];
4685 $align =& $this->flowingBlockAttr
[ 'align' ];
4686 $content =& $this->flowingBlockAttr
[ 'content' ];
4687 $contentB =& $this->flowingBlockAttr
[ 'contentB' ];
4688 $font =& $this->flowingBlockAttr
[ 'font' ];
4689 $contentWidth =& $this->flowingBlockAttr
[ 'contentWidth' ];
4690 $lineCount =& $this->flowingBlockAttr
[ 'lineCount' ];
4691 $valign =& $this->flowingBlockAttr
[ 'valign' ];
4692 $blockstate = $this->flowingBlockAttr
[ 'blockstate' ];
4694 $newblock = $this->flowingBlockAttr
[ 'newblock' ];
4695 $blockdir = $this->flowingBlockAttr
['blockdir'];
4698 // *********** BLOCK BACKGROUND COLOR *****************//
4699 if ($this->blk
[$this->blklvl
]['bgcolor'] && !$is_table) {
4703 $this->SetFColor($this->ConvertColor(255));
4707 $hanger = ''; // mPDF 5.6.40
4709 // Always right trim!
4710 // Right trim content and adjust width if need to justify (later)
4711 if (isset($content[count($content)-1]) && preg_match('/[ ]+$/',$content[count($content)-1], $m)) {
4712 $strip = strlen($m[0]);
4713 $content[count($content)-1] = substr($content[count($content)-1],0,(strlen($content[count($content)-1])-$strip));
4714 $this->restoreFont( $font[ count($content)-1 ],false );
4715 $contentWidth -= $this->GetStringWidth($m[0]) * _MPDFK
;
4718 // the amount of space taken up so far in user units
4722 $oldcolumn = $this->CurrCol
;
4724 if ($this->ColActive
&& !$is_table) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
4726 // Print out each chunk
4736 /*-- END TABLES --*/
4737 $ipaddingL = $this->blk
[$this->blklvl
]['padding_left'];
4738 $ipaddingR = $this->blk
[$this->blklvl
]['padding_right'];
4739 $paddingL = ($ipaddingL * _MPDFK
);
4740 $paddingR = ($ipaddingR * _MPDFK
);
4741 $this->cMarginL
= $this->blk
[$this->blklvl
]['border_left']['w'];
4742 $this->cMarginR
= $this->blk
[$this->blklvl
]['border_right']['w'];
4744 // Added mPDF 3.0 Float DIV
4748 if (count($this->floatDivs
)) {
4749 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl
);
4750 if ($r_exists) { $fpaddingR
= $r_width
; }
4751 if ($l_exists) { $fpaddingL
= $l_width
; }
4753 /*-- END CSS-FLOAT --*/
4755 $usey = $this->y +
0.002;
4756 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
4757 $usey +
= $this->blk
[$this->blklvl
]['margin_top'] +
$this->blk
[$this->blklvl
]['padding_top'] +
$this->blk
[$this->blklvl
]['border_top']['w'];
4759 /*-- CSS-IMAGE-FLOAT --*/
4760 // If float exists at this level
4761 if (isset($this->floatmargins
['R']) && $usey <= $this->floatmargins
['R']['y1'] && $usey >= $this->floatmargins
['R']['y0'] && !$this->floatmargins
['R']['skipline']) { $fpaddingR +
= $this
->floatmargins
['R']['w']; }
4762 if (isset($this->floatmargins
['L']) && $usey <= $this->floatmargins
['L']['y1'] && $usey >= $this->floatmargins
['L']['y0'] && !$this->floatmargins
['L']['skipline']) { $fpaddingL +
= $this
->floatmargins
['L']['w']; }
4763 /*-- END CSS-IMAGE-FLOAT --*/
4766 // Set Current lineheight (correction factor)
4770 if (preg_match('/([0-9.,]+)mm/',$this->list_lineheight
[$this->listlvl
][$this->listOcc
],$am)) {
4772 $def_fontsize = $this->InlineProperties
['LISTITEM'][$this->listlvl
][$this->listOcc
][$this->listnum
]['size'];
4773 $this->lineheight_correction
= $am[1] / $def_fontsize ;
4776 $this->lineheight_correction
= $this->list_lineheight
[$this->listlvl
][$this->listOcc
];
4783 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight
,$am)) {
4785 $def_fontsize = $this->FontSize
; // needs to be default font-size for block ****
4786 $this->lineheight_correction
= $lineHeight / $def_fontsize ;
4789 $this->lineheight_correction
= $this->table_lineheight
;
4793 /*-- END TABLES --*/
4794 if (isset($this->blk
[$this->blklvl
]['line_height']) && $this->blk
[$this->blklvl
]['line_height']) {
4795 if (preg_match('/([0-9.,]+)mm/',$this->blk
[$this->blklvl
]['line_height'],$am)) {
4797 $def_fontsize = $this->blk
[$this->blklvl
]['InlineProperties']['size']; // needs to be default font-size for block ****
4798 $this->lineheight_correction
= $am[1] / $def_fontsize ;
4801 $this->lineheight_correction
= $this->blk
[$this->blklvl
]['line_height'];
4805 $this->lineheight_correction
= $this->normalLineheight
;
4808 // correct lineheight to maximum fontsize
4809 if ($lhfixed) { $maxlineHeight
= $this
->lineheight
; }
4810 else { $maxlineHeight
= 0; }
4811 $this->forceExactLineheight
= true;
4813 // While we're at it, check if contains cursive text
4814 $checkCursive=false;
4815 if ($this->biDirectional
) { $checkCursive
=true; } // *RTL*
4816 foreach ( $content as $k => $chunk )
4818 $this->restoreFont( $font[ $k ],false );
4819 if (!isset($this->objectbuffer
[$k])) {
4820 // Soft Hyphens chr(173)
4821 if (!$this->usingCoreFont
) {
4822 $content[$k] = $chunk = str_replace("\xc2\xad",'',$chunk );
4823 if (isset($this->CurrentFont
['indic']) && $this->CurrentFont
['indic']) { $checkCursive
=true; } // *INDIC*
4825 else if ($this->FontFamily
!='csymbol' && $this->FontFamily
!='czapfdingbats') {
4826 $content[$k] = $chunk = str_replace(chr(173),'',$chunk );
4828 // Special case of sub/sup carried over on its own to last line
4829 if (($this->SUB
|| $this->SUP
) && count($content)==1) { $actfs
= $this
->FontSize
*100/55; } // 55% is font change for sub/sup
4830 else { $actfs
= $this
->FontSize
; }
4831 if (!$lhfixed) { $maxlineHeight
= max($maxlineHeight
,$actfs
* $this
->lineheight_correction
); }
4832 if ($lhfixed && ($actfs > $def_fontsize || ($actfs > ($lineHeight * $this->lineheight_correction
) && $is_list))) {
4833 $this->forceExactLineheight
= false;
4835 $maxfontsize = max($maxfontsize,$actfs);
4839 if(isset($font[count($font)-1])) {
4840 $lastfontreqstyle = $font[count($font)-1]['ReqFontStyle'];
4841 $lastfontstyle = $font[count($font)-1]['style'];
4844 $lastfontreqstyle=null;
4845 $lastfontstyle=null;
4847 if ($blockdir == 'ltr' && strpos($lastfontreqstyle,"I") !== false && strpos($lastfontstyle,"I") === false) { // Artificial italic
4848 $lastitalic = $this->FontSize
*0.15*_MPDFK
;
4850 else { $lastitalic
= 0; }
4854 if ($is_list && is_array($this->bulletarray
) && count($this->bulletarray
)) {
4855 $actfs = $this->bulletarray
['fontsize'];
4856 if (!$lhfixed) { $maxlineHeight
= max($maxlineHeight
,$actfs
* $this
->lineheight_correction
); }
4857 if ($lhfixed && $actfs > $def_fontsize) { $this
->forceExactLineheight
= false; }
4858 $maxfontsize = max($maxfontsize,$actfs);
4862 // when every text item checked i.e. $maxfontsize is set properly
4864 $af = 0; // Above font
4865 $bf = 0; // Below font
4866 $mta = 0; // Maximum top-aligned
4867 $mba = 0; // Maximum bottom-aligned
4869 foreach ( $content as $k => $chunk )
4871 if (isset($this->objectbuffer
[$k])) {
4872 $oh = $this->objectbuffer
[$k]['OUTER-HEIGHT'];
4873 $va = $this->objectbuffer
[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
4874 if ($lhfixed && $oh > $def_fontsize) { $this
->forceExactLineheight
= false; }
4876 if ($va == 'BS') { // (BASELINE default)
4877 $af = max($af, ($oh - ($maxfontsize * (0.5 +
$this->baselineC
))));
4879 else if ($va == 'M') {
4880 $af = max($af, ($oh - $maxfontsize)/2);
4881 $bf = max($bf, ($oh - $maxfontsize)/2);
4883 else if ($va == 'TT') {
4884 $bf = max($bf, ($oh - $maxfontsize));
4886 else if ($va == 'TB') {
4887 $af = max($af, ($oh - $maxfontsize));
4889 else if ($va == 'T') {
4890 $mta = max($mta, $oh);
4892 else if ($va == 'B') {
4893 $mba = max($mba, $oh);
4897 if ((!$lhfixed || !$this->forceExactLineheight
) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
4898 $maxlineHeight = $maxfontsize +
$af +
$bf;
4900 else if (!$lhfixed) { $af
= $bf
= ($maxlineHeight
- $maxfontsize
)/2; }
4901 if ($mta > $maxlineHeight) {
4902 $bf +
= ($mta - $maxlineHeight);
4903 $maxlineHeight = $mta;
4905 if ($mba > $maxlineHeight) {
4906 $af +
= ($mba - $maxlineHeight);
4907 $maxlineHeight = $mba;
4910 $lineHeight = $maxlineHeight;
4911 // If NOT images, and maxfontsize NOT > lineHeight - this value determines text baseline positioning
4912 if ($lhfixed && $af==0 && $bf==0 && $maxfontsize<=($def_fontsize * $this->lineheight_correction
* 0.8 )) {
4913 $this->linemaxfontsize
= $def_fontsize;
4915 else { $this
->linemaxfontsize
= $maxfontsize
; }
4917 // Get PAGEBREAK TO TEST for height including the bottom border/padding
4918 $check_h = max($this->divheight
,$lineHeight);
4920 // This fixes a proven bug...
4921 if ($endofblock && $newblock && $blockstate==0 && !$content) { $check_h
= 0; }
4922 // but ? needs to fix potentially more widespread...
4923 // if (!$content) { $check_h = 0; }
4925 if ($this->blklvl
> 0 && !$is_table) {
4926 if ($endofblock && $blockstate > 1) {
4927 if ($this->blk
[$this->blklvl
]['page_break_after_avoid']) { $check_h +
= $lineHeight
; }
4928 $check_h +
= ($this->blk
[$this->blklvl
]['padding_bottom'] +
$this->blk
[$this->blklvl
]['border_bottom']['w']);
4931 if (($newblock && ($blockstate==1 || $blockstate==3) && $lineCount == 0) || ($endofblock && $blockstate ==3 && $lineCount == 0)) {
4932 $check_h +
= ($this->blk
[$this->blklvl
]['padding_top'] +
$this->blk
[$this->blklvl
]['margin_top'] +
$this->blk
[$this->blklvl
]['border_top']['w']);
4936 // Force PAGE break if column height cannot take check-height
4937 if ($this->ColActive
&& $check_h > ($this->PageBreakTrigger
- $this->y0
)) {
4938 $this->SetCol($this->NbCol
-1);
4942 // Avoid just border/background-color moved on to next page
4943 if ($endofblock && $blockstate > 1 && !$content) { $buff
= $this
->margBuffer
; }
4949 if(!$is_table && ($this->y+
$check_h) > ($this->PageBreakTrigger +
$buff) and !$this->InFooter
and $this->AcceptPageBreak()) {
4950 $bak_x=$this->x
;//Current X position
4952 $ws=$this->ws
;//Word Spacing
4953 $charspacing=$this->charspacing
;//Character Spacing
4954 $this->ResetSpacing();
4956 $this->AddPage($this->CurOrientation
);
4959 // Added to correct for OddEven Margins
4960 $currentx +
= $this->MarginCorrection
;
4961 $this->x +
= $this->MarginCorrection
;
4964 $this->SetSpacing($charspacing,$ws);
4967 if ($this->keep_block_together
&& !$is_table && $this->kt_p00
< $this->page
&& ($this->y+
$check_h) > $this->kt_y00
) {
4968 $this->printdivbuffer();
4969 $this->keep_block_together
= 0;
4975 if ($this->CurrCol
!= $oldcolumn) {
4976 $currentx +
= $this->ChangeColumn
* ($this->ColWidth+
$this->ColGap
);
4977 $this->x +
= $this->ChangeColumn
* ($this->ColWidth+
$this->ColGap
);
4978 $oldcolumn = $this->CurrCol
;
4982 if ($this->ColActive
&& !$is_table) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; }
4983 /*-- END COLUMNS --*/
4986 if ($newblock && ($blockstate==1 || $blockstate==3) && ($this->blk
[$this->blklvl
]['margin_top']) && $lineCount == 0 && !$is_table && !$is_list) {
4987 $this->DivLn($this->blk
[$this->blklvl
]['margin_top'],$this->blklvl
-1,true,$this->blk
[$this->blklvl
]['margin_collapse']);
4988 if ($this->ColActive
) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
4991 if ($newblock && ($blockstate==1 || $blockstate==3) && $lineCount == 0 && !$is_table && !$is_list) {
4992 $this->blk
[$this->blklvl
]['y0'] = $this->y
;
4993 $this->blk
[$this->blklvl
]['startpage'] = $this->page
;
4994 if ($this->blk
[$this->blklvl
]['float']) { $this
->blk
[$this
->blklvl
]['float_start_y'] = $this
->y
; } // mPDF 5.6.63
4995 if ($this->ColActive
) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
4998 // ADDED for Paragraph_indent
4999 $WidthCorrection = 0;
5000 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk
[$this->blklvl
]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align != 'C')) {
5001 $ti = $this->ConvertSize($this->blk
[$this->blklvl
]['text_indent'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
5002 $WidthCorrection = ($ti*_MPDFK
);
5006 // PADDING and BORDER spacing/fill
5007 if (($newblock) && ($blockstate==1 || $blockstate==3) && (($this->blk
[$this->blklvl
]['padding_top']) || ($this->blk
[$this->blklvl
]['border_top'])) && ($lineCount == 0) && (!$is_table) && (!$is_list)) {
5008 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
5009 $this->DivLn($this->blk
[$this->blklvl
]['padding_top'] +
$this->blk
[$this->blklvl
]['border_top']['w'],-3,true,false,1);
5010 if ($this->ColActive
) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
5011 $this->x
= $currentx;
5015 // Added mPDF 3.0 Float DIV
5019 if (count($this->floatDivs
)) {
5020 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl
);
5021 if ($r_exists) { $fpaddingR
= $r_width
; }
5022 if ($l_exists) { $fpaddingL
= $l_width
; }
5024 /*-- END CSS-FLOAT --*/
5026 $usey = $this->y +
0.002;
5027 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
5028 $usey +
= $this->blk
[$this->blklvl
]['margin_top'] +
$this->blk
[$this->blklvl
]['padding_top'] +
$this->blk
[$this->blklvl
]['border_top']['w'];
5030 /*-- CSS-IMAGE-FLOAT --*/
5031 // If float exists at this level
5032 if (isset($this->floatmargins
['R']) && $usey <= $this->floatmargins
['R']['y1'] && $usey >= $this->floatmargins
['R']['y0'] && !$this->floatmargins
['R']['skipline']) { $fpaddingR +
= $this
->floatmargins
['R']['w']; }
5033 if (isset($this->floatmargins
['L']) && $usey <= $this->floatmargins
['L']['y1'] && $usey >= $this->floatmargins
['L']['y0'] && !$this->floatmargins
['L']['skipline']) { $fpaddingL +
= $this
->floatmargins
['L']['w']; }
5034 /*-- END CSS-IMAGE-FLOAT --*/
5038 // In FinishFlowing Block no lines are justified as it is always last line
5039 // but if CJKorphan has allowed content width to go over max width, use J charspacing to compress line
5040 // JUSTIFICATION J - NOT!
5046 $dottab = false; // mPDF 5.6.19
5047 foreach ( $content as $k => $chunk ) {
5048 if (!isset($this->objectbuffer
[$k]) || (isset($this->objectbuffer
[$k]) && !$this->objectbuffer
[$k])) {
5049 if ($this->usingCoreFont
) {
5050 $chunk = str_replace(chr(160),chr(32),$chunk );
5053 $chunk = str_replace(chr(194).chr(160),chr(32),$chunk );
5055 $nb_carac +
= mb_strlen( $chunk, $this->mb_enc
);
5056 $nb_spaces +
= mb_substr_count( $chunk,' ', $this->mb_enc
);
5057 if ($checkCursive) {
5058 if (preg_match("/([".$this->pregRTLchars
."])/u", $chunk)) { $inclCursive
= true; } // *RTL*
5059 if (preg_match("/([".$this->pregHIchars
.$this->pregBNchars
.$this->pregPAchars
."])/u", $chunk)) { $inclCursive
= true; } // *INDIC*
5062 else if ($this->objectbuffer
[$k]['type']=='dottab') { $dottab
= $this
->objectbuffer
[$k
]['outdent']; } // mPDF 5.6.19
5064 // if it's justified, we need to find the char/word spacing (or if orphans have allowed length of line to go over the maxwidth)
5065 // If "orphans" in fact is just a final space - ignore this
5067 $lastchar = mb_substr($content[(count($content)-1)],mb_strlen($content[(count($content)-1)], $this->mb_enc
)-1, 1, $this->mb_enc
);
5068 if (preg_match("/[".$this->CJKoverflow
."]/u", $lastchar)) { $CJKoverflow
= true; }
5069 else {$CJKoverflow
= false; }
5070 if ((((($contentWidth +
$lastitalic) > $maxWidth) && ($content[count($content)-1] != ' ') ) ||
5071 (!$endofblock && $align=='J' && ($next=='image' || $next=='select' || $next=='input' || $next=='textarea' || ($next=='br' && $this->justifyB4br
)))) && !($CJKoverflow && $this->allowCJKoverflow
) ) { // mPDF 5.6.40
5073 list($jcharspacing,$jws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$contentWidth-$WidthCorrection-(($this->cMarginL+
$this->cMarginR
)*_MPDFK
)-($paddingL+
$paddingR +
(($fpaddingL +
$fpaddingR) * _MPDFK
) )),$inclCursive);
5077 else if ($this->checkCJK
&& $align=='J' && $CJKoverflow && $this->allowCJKoverflow
&& $this->CJKforceend
) {
5078 // force-end overhang
5079 $hanger = mb_substr($content[count($content)-1],mb_strlen($content[count($content)-1],$this->mb_enc
)-1,1,$this->mb_enc
);
5080 if (preg_match("/[".$this->CJKoverflow
."]/u", $hanger)) {
5081 $content[count($content)-1] = mb_substr($content[count($content)-1],0,mb_strlen($content[count($content)-1],$this->mb_enc
)-1,$this->mb_enc
);
5082 $this->restoreFont( $font[ count($content)-1 ],false );
5083 $contentWidth -= $this->GetStringWidth($hanger) * _MPDFK
;
5085 list($jcharspacing,$jws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$contentWidth-$WidthCorrection-(($this->cMarginL+
$this->cMarginR
)*_MPDFK
)-($paddingL+
$paddingR +
(($fpaddingL +
$fpaddingR) * _MPDFK
) )),$inclCursive);
5088 /*-- END CJK-FONTS --*/
5090 // Check if will fit at word/char spacing of previous line - if so continue it
5091 // but only allow a maximum of $this->jSmaxWordLast and $this->jSmaxCharLast
5092 else if ($contentWidth < ($maxWidth - $lastitalic-$WidthCorrection - (($this->cMarginL+
$this->cMarginR
)* _MPDFK
) - ($paddingL+
$paddingR +
(($fpaddingL +
$fpaddingR) * _MPDFK
))) && !$this->fixedlSpacing
) {
5093 if ($this->ws
> $this->jSmaxWordLast
) {
5094 $jws = $this->jSmaxWordLast
;
5096 if ($this->charspacing
> $this->jSmaxCharLast
) {
5097 $jcharspacing = $this->jSmaxCharLast
;
5099 $check = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+
$this->cMarginR
)* _MPDFK
) - ($paddingL+
$paddingR +
(($fpaddingL +
$fpaddingR) * _MPDFK
) ) - ( $jcharspacing * $nb_carac) - ( $jws * $nb_spaces);
5106 $empty = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+
$this->cMarginR
)* _MPDFK
) - ($paddingL+
$paddingR +
(($fpaddingL +
$fpaddingR) * _MPDFK
) );
5108 $empty -= ($jcharspacing * $nb_carac);
5109 $empty -= ($jws * $nb_spaces);
5114 $this->maxPosR
= max($this->maxPosR
, ($this->w
- $this->rMargin
- $this->blk
[$this->blklvl
]['outer_right_margin'] - $empty));
5115 $this->maxPosL
= min($this->maxPosL
, ($this->lMargin +
$this->blk
[$this->blklvl
]['outer_left_margin'] +
$empty));
5118 $arraysize = count($content);
5120 $margins = ($this->cMarginL+
$this->cMarginR
) +
($ipaddingL+
$ipaddingR +
$fpaddingR +
$fpaddingR );
5122 if (!$is_table) { $this
->DivLn($lineHeight
,$this
->blklvl
,false); } // false -> don't advance y
5124 // DIRECTIONALITY RTL
5126 $contains_rtl = false;
5128 if ($blockdir == 'rtl' || $this->biDirectional
) {
5130 foreach ( $content as $k => $chunk ) {
5131 $reversed = $this->magic_reverse_dir($chunk, false, $blockdir);
5132 if ($reversed > 0) { $contains_rtl
= true; }
5133 if ($reversed < 2) { $all_rtl
= false; }
5134 $content[$k] = $chunk;
5136 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) {
5137 $content = array_reverse($content,false);
5138 $contentB = array_reverse($contentB,false);
5143 $this->x
= $currentx +
$this->cMarginL +
$ipaddingL +
$fpaddingL;
5144 if ($dottab !== false && $blockdir=='rtl') { $this
->x
-= $dottab
; } // mPDF 5.6.19
5145 else if ($align == 'R') { $this
->x +
= $
empty; }
5146 else if ($align == 'J' && $blockdir == 'rtl') { $this
->x +
= $
empty; }
5147 else if ($align == 'C') { $this
->x +
= ($
empty / 2); }
5150 $WidthCorrection = 0;
5151 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk
[$this->blklvl
]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align !='C')) {
5152 $ti = $this->ConvertSize($this->blk
[$this->blklvl
]['text_indent'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
5157 foreach ( $content as $k => $chunk )
5161 if ((($blockdir == 'rtl') && ($contains_rtl )) || $all_rtl ) { $dirk
= $arraysize
-1 - $k
; } else { $dirk
= $k
; }
5163 $va = 'M'; // default for text
5164 if (isset($this->objectbuffer
[$dirk]) && $this->objectbuffer
[$dirk]) {
5165 $xadj = $this->x
- $this->objectbuffer
[$dirk]['OUTER-X'];
5166 $this->objectbuffer
[$dirk]['OUTER-X'] +
= $xadj;
5167 $this->objectbuffer
[$dirk]['BORDER-X'] +
= $xadj;
5168 $this->objectbuffer
[$dirk]['INNER-X'] +
= $xadj;
5169 $va = $this->objectbuffer
[$dirk]['vertical-align'];
5170 $yadj = $this->y
- $this->objectbuffer
[$dirk]['OUTER-Y'];
5172 $yadj +
= $af +
($this->linemaxfontsize
* (0.5 +
$this->baselineC
)) - $this->objectbuffer
[$dirk]['OUTER-HEIGHT'];
5174 else if ($va == 'M' || $va == '') {
5175 $yadj +
= $af +
($this->linemaxfontsize
/2) - ($this->objectbuffer
[$dirk]['OUTER-HEIGHT']/2);
5177 else if ($va == 'TB') {
5178 $yadj +
= $af +
$this->linemaxfontsize
- $this->objectbuffer
[$dirk]['OUTER-HEIGHT'];
5180 else if ($va == 'TT') {
5183 else if ($va == 'B') {
5184 $yadj +
= $af +
$this->linemaxfontsize +
$bf - $this->objectbuffer
[$dirk]['OUTER-HEIGHT'];
5186 else if ($va == 'T') {
5189 $this->objectbuffer
[$dirk]['OUTER-Y'] +
= $yadj;
5190 $this->objectbuffer
[$dirk]['BORDER-Y'] +
= $yadj;
5191 $this->objectbuffer
[$dirk]['INNER-Y'] +
= $yadj;
5195 // DIRECTIONALITY RTL
5196 if ((($blockdir == 'rtl') && ($contains_rtl )) || $all_rtl ) { $this
->restoreFont( $font
[ $arraysize
-1 - $k
] ); }
5197 else { $this
->restoreFont( $font
[ $k
] ); }
5199 // mPDF 5.6.13 Decimal alignment - set in _tableWrite
5200 if ($is_table && substr($align,0,1)=='D' && $k==0 ) {
5201 $dp = $this->decimal_align
[substr($align,0,2)];
5202 $s = preg_split('/'.preg_quote($dp,'/').'/', $content[0], 2); // ? needs to be /u if not core
5203 $s0 = $this->GetStringWidth($s[0], false);
5204 $this->x +
= ($this->decimal_offset
- $s0);
5207 $this->SetSpacing(($this->fixedlSpacing
*_MPDFK
)+
$jcharspacing,($this->fixedlSpacing+
$this->minwSpacing
)*_MPDFK+
$jws);
5208 $this->fixedlSpacing
= false;
5209 $this->minwSpacing
= 0;
5212 $save_vis = $this->visibility
;
5213 if (isset($this->textparam
['visibility']) && $this->textparam
['visibility'] && $this->textparam
['visibility'] != $this->visibility
) {
5214 $this->SetVisibility($this->textparam
['visibility']);
5217 // *********** SPAN BACKGROUND COLOR ***************** //
5218 if (isset($this->spanbgcolor
) && $this->spanbgcolor
) {
5219 $cor = $this->spanbgcolorarray
;
5220 $this->SetFColor($cor);
5221 $save_fill = $fill; $spanfill = 1; $fill = 1;
5223 if (!empty($this->spanborddet
)) {
5224 if (strpos($contentB[$k],'L')!==false && isset($this->spanborddet
['L'])) $this->x +
= $this->spanborddet
['L']['w'];
5225 if (strpos($contentB[$k],'L')===false) $this->spanborddet
['L']['s'] = $this->spanborddet
['L']['w'] = 0;
5226 if (strpos($contentB[$k],'R')===false) $this->spanborddet
['R']['s'] = $this->spanborddet
['R']['w'] = 0;
5229 $stringWidth = $this->GetStringWidth($chunk ) +
( $this->charspacing
* mb_strlen($chunk,$this->mb_enc
) / _MPDFK
)
5230 +
( $this->ws
* mb_substr_count($chunk,' ',$this->mb_enc
) / _MPDFK
);
5231 if (isset($this->objectbuffer
[$dirk])) {
5232 if ($this->objectbuffer
[$dirk]['type']=='dottab') {
5233 $this->objectbuffer
[$dirk]['OUTER-WIDTH'] +
=$empty;
5234 $this->objectbuffer
[$dirk]['OUTER-WIDTH'] +
=$this->objectbuffer
[$dirk]['outdent']; // mPDF 5.6.19
5236 $stringWidth = $this->objectbuffer
[$dirk]['OUTER-WIDTH'];
5239 if ($stringWidth==0) { $stringWidth
= 0.000001; }
5240 if ($k == $arraysize-1) {
5242 if ($this->checkCJK
&& $CJKoverflow && $align=='J' && $this->allowCJKoverflow
&& $hanger && $this->CJKforceend
) {
5243 // force-end overhang
5244 $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF
, $currentx,0,0,'M', $fill, $af, $bf, true );
5245 $this->Cell( $this->GetStringWidth($hanger), $lineHeight, $hanger, '', 1, '', $fill, $this->HREF
, $currentx,0,0,'M', $fill, $af, $bf, true );
5248 $this->Cell( $stringWidth, $lineHeight, $chunk, '', 1, '', $fill, $this->HREF
, $currentx,0,0,'M', $fill, $af, $bf, true );
5251 else $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF
, 0, 0,0,'M', $fill, $af, $bf, true );//first or middle part
5254 if (!empty($this->spanborddet
)) {
5255 if (strpos($contentB[$k],'R')!==false && $k != $arraysize-1) $this->x +
= $this->spanborddet
['R']['w'];
5257 // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
5258 if (isset($spanfill) && $spanfill) {
5259 $fill = $save_fill; $spanfill = 0;
5260 if ($fill) { $this
->SetFColor($bcor
); }
5263 if (isset($this->textparam
['visibility']) && $this->textparam
['visibility'] && $this->visibility
!= $save_vis) {
5264 $this->SetVisibility($save_vis);
5269 $this->printobjectbuffer($is_table, $blockdir);
5271 $this->objectbuffer
= array();
5273 $this->ResetSpacing();
5276 // LIST BULLETS/NUMBERS
5277 if ($is_list && is_array($this->bulletarray
) && ($lineCount == 0) ) {
5279 $savedFont = $this->saveFont();
5281 $bull = $this->bulletarray
;
5282 if (isset($bull['level']) && isset($bull['occur']) && isset($this->InlineProperties
['LIST'][$bull['level']][$bull['occur']])) {
5283 $this->restoreInlineProperties($this->InlineProperties
['LIST'][$bull['level']][$bull['occur']]);
5285 if (isset($bull['level']) && isset($bull['occur']) && isset($bull['num']) && isset($this->InlineProperties
['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]) && $this->InlineProperties
['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]) { $this
->restoreInlineProperties($this
->InlineProperties
['LISTITEM'][$bull
['level']][$bull
['occur']][$bull
['num']]); }
5286 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
5287 $this->bullet
= true;
5288 $this->SetFont('czapfdingbats','',$this->FontSizePt
/2.5);
5290 else { $this
->SetFont($this
->FontFamily
,$this
->FontStyle
,$this
->FontSizePt
,true,true); } // force output
5292 $this->x
= $currentx;
5293 if (isset($bull['x'])) { $this
->x +
= $bull
['x']; }
5294 $this->y
-= $lineHeight;
5295 if (isset($bull['col']) && $bull['col']) { $this
->SetTColor($bull
['col']); } // mPDF 5.6.67
5297 if (isset($bull['txt'])) { $this
->Cell($bull
['w'], $lineHeight
,$bull
['txt'],'','',$bull
['align'],0,'',0,-$this
->cMarginL
, -$this
->cMarginR
); }
5298 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
5299 $this->bullet
= false;
5301 $this->x
= $currentx; // Reset
5302 $this->y +
= $lineHeight;
5304 if ($this->ColActive
&& !$is_table) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
5306 $this->restoreFont( $savedFont );
5307 // $font = array( $savedFont );
5309 $this->bulletarray
= array(); // prevents repeat of bullet/number if <li>....<br />.....</li>
5316 /*-- CSS-IMAGE-FLOAT --*/
5317 // Update values if set to skipline
5318 if ($this->floatmargins
) { $this
->_advanceFloatMargins(); }
5321 if ($endofblock && $blockstate>1) {
5322 // If float exists at this level
5323 if (isset($this->floatmargins
['R']['y1'])) { $fry1
= $this
->floatmargins
['R']['y1']; }
5325 if (isset($this->floatmargins
['L']['y1'])) { $fly1
= $this
->floatmargins
['L']['y1']; }
5327 if ($this->y
< $fry1 || $this->y
< $fly1) {
5328 $drop = max($fry1,$fly1) - $this->y
;
5329 $this->DivLn($drop);
5330 $this->x
= $currentx;
5333 /*-- END CSS-IMAGE-FLOAT --*/
5336 // PADDING and BORDER spacing/fill
5337 if ($endofblock && ($blockstate > 1) && ($this->blk
[$this->blklvl
]['padding_bottom'] || $this->blk
[$this->blklvl
]['border_bottom'] || $this->blk
[$this->blklvl
]['css_set_height']) && (!$is_table) && (!$is_list)) {
5338 // If CSS height set, extend bottom - if on same page as block started, and CSS HEIGHT > actual height,
5339 // and does not force pagebreak
5341 if ($this->blk
[$this->blklvl
]['css_set_height'] && $this->blk
[$this->blklvl
]['startpage']==$this->page
) {
5343 $h1 = ($this->y
-$this->blk
[$this->blklvl
]['y0']) +
$this->blk
[$this->blklvl
]['padding_bottom'] +
$this->blk
[$this->blklvl
]['border_bottom']['w'];
5344 if ($h1 < ($this->blk
[$this->blklvl
]['css_set_height']+
$this->blk
[$this->blklvl
]['padding_bottom']+
$this->blk
[$this->blklvl
]['padding_top'])) { $extra
= ($this
->blk
[$this
->blklvl
]['css_set_height']+$this
->blk
[$this
->blklvl
]['padding_bottom']+$this
->blk
[$this
->blklvl
]['padding_top']) - $h1
; }
5345 if($this->y +
$this->blk
[$this->blklvl
]['padding_bottom'] +
$this->blk
[$this->blklvl
]['border_bottom']['w'] +
$extra > $this->PageBreakTrigger
) {
5346 $extra = $this->PageBreakTrigger
- ($this->y +
$this->blk
[$this->blklvl
]['padding_bottom'] +
$this->blk
[$this->blklvl
]['border_bottom']['w']);
5350 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
5351 $this->DivLn($this->blk
[$this->blklvl
]['padding_bottom'] +
$this->blk
[$this->blklvl
]['border_bottom']['w'] +
$extra,-3,true,false,2);
5352 $this->x
= $currentx;
5354 if ($this->ColActive
) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
5358 // SET Bottom y1 of block (used for painting borders)
5359 if (($endofblock) && ($blockstate > 1) && (!$is_table) && (!$is_list)) {
5360 $this->blk
[$this->blklvl
]['y1'] = $this->y
;
5364 if (($endofblock) && ($blockstate > 1) && ($this->blk
[$this->blklvl
]['margin_bottom']) && (!$is_table) && (!$is_list)) {
5365 if($this->y+
$this->blk
[$this->blklvl
]['margin_bottom'] < $this->PageBreakTrigger
and !$this->InFooter
) {
5366 $this->DivLn($this->blk
[$this->blklvl
]['margin_bottom'],$this->blklvl
-1,true,$this->blk
[$this->blklvl
]['margin_collapse']);
5367 if ($this->ColActive
) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
5372 $lineHeight = $this->divheight
;
5379 function printobjectbuffer($is_table=false, $blockdir=false) {
5380 if (!$blockdir) { $blockdir
= $this
->directionality
; }
5381 if ($is_table && $this->shrin_k
> 1) { $k
= $this
->shrin_k
; }
5385 $save_currentfontfamily = $this->FontFamily
;
5386 $save_currentfontsize = $this->FontSizePt
;
5387 $save_currentfontstyle = $this->FontStyle
.($this->U
? 'U' : '').($this->S
? 'S' : '');
5388 if ($blockdir == 'rtl') { $rtlalign
= 'R'; } else { $rtlalign
= 'L'; }
5389 foreach ($this->objectbuffer
AS $ib => $objattr) {
5390 if ($objattr['type'] == 'bookmark' || $objattr['type'] == 'indexentry' || $objattr['type'] == 'toc') {
5391 $x = $objattr['OUTER-X'];
5392 $y = $objattr['OUTER-Y'];
5393 $this->y
= $y - $this->FontSize
/2;
5395 if ($objattr['type'] == 'bookmark' ) { $this
->Bookmark($objattr
['CONTENT'],$objattr
['bklevel'] ,$y
- $this
->FontSize
); } // *BOOKMARKS*
5396 if ($objattr['type'] == 'indexentry') { $this
->IndexEntry($objattr
['CONTENT']); } // *INDEX*
5397 if ($objattr['type'] == 'toc') { $this
->TOC_Entry($objattr
['CONTENT'], $objattr
['toclevel'], $objattr
['toc_id']); } // *TOC*
5399 /*-- ANNOTATIONS --*/
5400 else if ($objattr['type'] == 'annot') {
5401 if ($objattr['POS-X']) { $x
= $objattr
['POS-X']; }
5402 else if ($this->annotMargin
<>0) { $x
= -$objattr
['OUTER-X']; }
5403 else { $x
= $objattr
['OUTER-X']; }
5404 if ($objattr['POS-Y']) { $y
= $objattr
['POS-Y']; }
5405 else { $y
= $objattr
['OUTER-Y'] - $this
->FontSize
/2; }
5406 // Create a dummy entry in the _out/columnBuffer with position sensitive data,
5407 // linking $y-1 in the Columnbuffer with entry in $this->columnAnnots
5408 // and when columns are split in length will not break annotation from current line
5411 $this->Line($x-1,$y-1,$x-1,$y-1);
5412 $this->Annotation($objattr['CONTENT'], $x , $y , $objattr['ICON'], $objattr['AUTHOR'], $objattr['SUBJECT'], $objattr['OPACITY'], $objattr['COLOR'], $objattr['POPUP'], $objattr['FILE']);
5414 /*-- END ANNOTATIONS --*/
5416 $y = $objattr['OUTER-Y'];
5417 $x = $objattr['OUTER-X'];
5418 $w = $objattr['OUTER-WIDTH'];
5419 $h = $objattr['OUTER-HEIGHT'];
5420 if (isset($objattr['text'])) { $texto
= $objattr
['text']; }
5423 if (isset($objattr['fontfamily'])) { $this
->SetFont($objattr
['fontfamily'],'',$objattr
['fontsize'] ); }
5427 if ($objattr['type'] == 'hr') {
5428 $this->SetDColor($objattr['color']);
5429 switch($objattr['align']) {
5431 $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
5436 $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
5440 $oldlinewidth = $this->LineWidth
;
5441 $this->SetLineWidth($objattr['linewidth']/$k );
5442 $this->y +
= ($objattr['linewidth']/2) +
$objattr['margin_top']/$k;
5443 $this->Line($x,$this->y
,$x+
$objattr['INNER-WIDTH'],$this->y
);
5444 $this->SetLineWidth($oldlinewidth);
5445 $this->SetDColor($this->ConvertColor(0));
5448 if ($objattr['type'] == 'image') {
5449 // mPDF 5.6.01 - LAYERS
5450 if (isset($objattr['z-index']) && $objattr['z-index'] > 0 && $this->currentlayer
==0) {
5451 $this->BeginLayer($objattr['z-index']);
5453 if(isset($objattr['visibility']) && $objattr['visibility']!='visible' && $objattr['visibility']) {
5454 $this->SetVisibility($objattr['visibility']);
5456 if (isset($objattr['opacity'])) { $this
->SetAlpha($objattr
['opacity']); }
5458 $obiw = $objattr['INNER-WIDTH'];
5459 $obih = $objattr['INNER-HEIGHT'];
5460 $sx = $objattr['INNER-WIDTH']*_MPDFK
/ $objattr['orig_w'];
5461 $sy = abs($objattr['INNER-HEIGHT'])*_MPDFK
/ abs($objattr['orig_h']);
5462 $sx = ($objattr['INNER-WIDTH']*_MPDFK
/ $objattr['orig_w']);
5463 $sy = ($objattr['INNER-HEIGHT']*_MPDFK
/ $objattr['orig_h']);
5465 if (isset($objattr['ROTATE'])) { $rotate
= $objattr
['ROTATE']; }
5468 $obiw = $objattr['INNER-HEIGHT'];
5469 $obih = $objattr['INNER-WIDTH'];
5470 $tr = $this->transformTranslate(0, -$objattr['INNER-WIDTH'], true) ;
5471 $tr .= ' '. $this->transformRotate(90, $objattr['INNER-X'],($objattr['INNER-Y'] +
$objattr['INNER-WIDTH'] ),true) ;
5472 $sx = $obiw*_MPDFK
/ $objattr['orig_h'];
5473 $sy = $obih*_MPDFK
/ $objattr['orig_w'];
5475 else if ($rotate==-90 || $rotate==270) {
5477 $obiw = $objattr['INNER-HEIGHT'];
5478 $obih = $objattr['INNER-WIDTH'];
5479 $tr = $this->transformTranslate($objattr['INNER-WIDTH'], ($objattr['INNER-HEIGHT']-$objattr['INNER-WIDTH']), true) ;
5480 $tr .= ' '. $this->transformRotate(-90, $objattr['INNER-X'],($objattr['INNER-Y'] +
$objattr['INNER-WIDTH'] ),true) ;
5481 $sx = $obiw*_MPDFK
/ $objattr['orig_h'];
5482 $sy = $obih*_MPDFK
/ $objattr['orig_w'];
5484 else if ($rotate==180) {
5486 $tr = $this->transformTranslate($objattr['INNER-WIDTH'], -$objattr['INNER-HEIGHT'], true) ;
5487 $tr .= ' '. $this->transformRotate(180, $objattr['INNER-X'],($objattr['INNER-Y'] +
$objattr['INNER-HEIGHT'] ),true) ;
5491 if ($tr) { $tr
.= ' '; }
5495 /*-- BACKGROUNDS --*/
5496 if (isset($objattr['GRADIENT-MASK'])) {
5497 $g = $this->grad
->parseMozGradient( $objattr['GRADIENT-MASK'] );
5499 $dummy = $this->grad
->Gradient($objattr['INNER-X'], $objattr['INNER-Y'], $obiw, $obih, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true, true);
5500 $gradmask = '/TGS'.count($this->gradients
).' gs ';
5501 // $this->_out("q ".$tr.$this->grad->Gradient($objattr['INNER-X'], $objattr['INNER-Y'], $obiw, $obih, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true)." Q");
5504 /*-- END BACKGROUNDS --*/
5505 /*-- IMAGES-WMF --*/
5506 if (isset($objattr['itype']) && $objattr['itype']=='wmf') {
5507 $outstring = sprintf('q '.$tr.'%.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, -$sy, $objattr['INNER-X']*_MPDFK
-$sx*$objattr['wmf_x'], (($this->h
-$objattr['INNER-Y'])*_MPDFK
)+
$sy*$objattr['wmf_y'], $objattr['ID']);
5510 /*-- END IMAGES-WMF --*/
5511 if (isset($objattr['itype']) && $objattr['itype']=='svg') {
5512 $outstring = sprintf('q '.$tr.'%.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, -$sy, $objattr['INNER-X']*_MPDFK
-$sx*$objattr['wmf_x'], (($this->h
-$objattr['INNER-Y'])*_MPDFK
)+
$sy*$objattr['wmf_y'], $objattr['ID']);
5515 $outstring = sprintf("q ".$tr."%.3F 0 0 %.3F %.3F %.3F cm ".$gradmask."/I%d Do Q",$obiw*_MPDFK
, $obih*_MPDFK
, $objattr['INNER-X'] *_MPDFK
, ($this->h
-($objattr['INNER-Y'] +
$obih ))*_MPDFK
,$objattr['ID'] );
5517 $this->_out($outstring);
5519 if (isset($objattr['link'])) $this->Link($objattr['INNER-X'],$objattr['INNER-Y'],$objattr['INNER-WIDTH'],$objattr['INNER-HEIGHT'],$objattr['link']);
5520 if (isset($objattr['opacity'])) { $this
->SetAlpha(1); }
5521 if ((isset($objattr['border_top']) && $objattr['border_top']>0) || (isset($objattr['border_left']) && $objattr['border_left']>0) || (isset($objattr['border_right']) && $objattr['border_right']>0) || (isset($objattr['border_bottom']) && $objattr['border_bottom']>0)) { $this
->PaintImgBorder($objattr
,$is_table
); }
5522 if(isset($objattr['visibility']) && $objattr['visibility']!='visible' && $objattr['visibility']) {
5523 $this->SetVisibility('visible');
5525 // mPDF 5.6.01 - LAYERS
5526 if (isset($objattr['z-index']) && $objattr['z-index'] > 0 && $this->currentlayer
==0) {
5534 if ($objattr['type'] == 'barcode') {
5535 $bgcol = $this->ConvertColor(255);
5536 if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
5537 $bgcol = $objattr['bgcolor'];
5539 $col = $this->ConvertColor(0);
5540 if (isset($objattr['color']) && $objattr['color']) {
5541 $col = $objattr['color'];
5543 $this->SetFColor($bgcol);
5544 $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F');
5545 $this->SetFColor($this->ConvertColor(255));
5546 if (isset($objattr['BORDER-WIDTH'])) { $this
->PaintImgBorder($objattr
,$is_table
); }
5547 if ($objattr['btype'] == 'EAN13' || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN' || $objattr['btype'] == 'UPCA' || $objattr['btype'] == 'UPCE' || $objattr['btype'] == 'EAN8') {
5548 $this->WriteBarcode($objattr['code'], $objattr['showtext'], $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize'], 0, 0, 0, 0, 0, $objattr['bheight'], $bgcol, $col, $objattr['btype'], $objattr['bsupp'], $objattr['bsupp_code'], $k);
5551 else if ($objattr['btype']=='QR') {
5552 if (!class_exists('QRcode', false)) {
5553 include(_MPDF_PATH
.'qrcode/qrcode.class.php');
5555 $this->qrcode
= new QRcode($objattr['code'], $objattr['errorlevel']);
5556 $this->qrcode
->displayFPDF($this, $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize']*25, array(255,255,255), array(0,0,0));
5559 $this->WriteBarcode2($objattr['code'], $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize'], $objattr['bheight'], $bgcol, $col, $objattr['btype'], $objattr['pr_ratio'], $k);
5562 /*-- END BARCODES --*/
5565 if ($objattr['type'] == 'textcircle') {
5566 $bgcol = ''; // mPDF 5.5.14
5567 if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
5568 $bgcol = $objattr['bgcolor'];
5570 $col = $this->ConvertColor(0);
5571 if (isset($objattr['color']) && $objattr['color']) {
5572 $col = $objattr['color'];
5574 $this->SetTColor($col);
5575 $this->SetFColor($bgcol);
5576 if ($bgcol) $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F'); // mPDF 5.5.14
5577 $this->SetFColor($this->ConvertColor(255));
5578 if (isset($objattr['BORDER-WIDTH'])) { $this
->PaintImgBorder($objattr
,$is_table
); }
5579 if (!class_exists('directw', false)) { include(_MPDF_PATH
.'classes/directw.php'); }
5580 if (empty($this->directw
)) { $this
->directw
= new directw($this
); }
5581 $save_lmfs = $this->linemaxfontsize
;
5582 $this->linemaxfontsize
= 0;
5583 if (isset($objattr['top-text'])) {
5584 $this->directw
->CircularText($objattr['INNER-X']+
$objattr['INNER-WIDTH']/2, $objattr['INNER-Y']+
$objattr['INNER-HEIGHT']/2, $objattr['r']/$k, $objattr['top-text'], 'top', $objattr['fontfamily'], $objattr['fontsize']/$k, $objattr['fontstyle'], $objattr['space-width'], $objattr['char-width'], $objattr['divider']); // mPDF 5.5.23
5586 if (isset($objattr['bottom-text'])) {
5587 $this->directw
->CircularText($objattr['INNER-X']+
$objattr['INNER-WIDTH']/2, $objattr['INNER-Y']+
$objattr['INNER-HEIGHT']/2, $objattr['r']/$k, $objattr['bottom-text'], 'bottom', $objattr['fontfamily'], $objattr['fontsize']/$k, $objattr['fontstyle'], $objattr['space-width'], $objattr['char-width'], $objattr['divider']); // mPDF 5.5.23
5589 $this->linemaxfontsize
= $save_lmfs;
5592 $this->ResetSpacing();
5595 if ($objattr['type'] == 'dottab') {
5597 if (isset($objattr['fontfamily'])) { $this
->SetFont($objattr
['fontfamily'],'',$objattr
['fontsize'] ); }
5598 $sp = $this->GetStringWidth(' ');
5599 $nb=floor(($w-2*$sp)/$this->GetStringWidth('.'));
5600 if ($nb>0) { $dots
=' '.str_repeat('.',$nb
).' '; }
5602 $col = $this->ConvertColor(0);
5603 if (isset($objattr['colorarray']) && ($objattr['colorarray'])) { // mPDF 5.6.19
5604 $col = $objattr['colorarray'];
5606 $this->SetTColor($col);
5607 $save_dh = $this->divheight
; // mPDF 5.6.19
5608 $save_sbd = $this->spanborddet
;
5610 $save_s = $this->strike
;
5611 $this->spanborddet
= '';
5612 $this->divheight
= 0; // mPDF 5.6.19
5614 $this->strike
= false;
5615 $this->Cell($w,$h,$dots,0,0,'C');
5616 $this->spanborddet
= $save_sbd;
5618 $this->strike
= $save_s;
5619 $this->divheight
= $save_dh; // mPDF 5.6.19
5621 $this->SetTColor($this->ConvertColor(0));
5625 // TEXT/PASSWORD INPUT
5626 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD')) {
5627 $this->form
->print_ob_text($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5631 if ($objattr['type'] == 'textarea') {
5632 $this->form
->print_ob_textarea($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5636 if ($objattr['type'] == 'select') {
5637 $this->form
->print_ob_select($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5641 // INPUT/BUTTON as IMAGE
5642 if ($objattr['type'] == 'input' && $objattr['subtype'] == 'IMAGE') {
5643 $this->form
->print_ob_imageinput($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5647 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'SUBMIT' || $objattr['subtype'] == 'RESET' || $objattr['subtype'] == 'BUTTON')) {
5648 $this->form
->print_ob_button($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5652 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'CHECKBOX')) {
5653 $this->form
->print_ob_checkbox($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir,$x,$y);
5656 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'RADIO')) {
5657 $this->form
->print_ob_radio($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir,$x,$y);
5661 $this->SetFont($save_currentfontfamily,$save_currentfontstyle,$save_currentfontsize);
5668 function WriteFlowingBlock( $s)
5670 $currentx = $this->x
;
5671 $is_table = $this->flowingBlockAttr
[ 'is_table' ];
5672 $is_list = $this->flowingBlockAttr
[ 'is_list' ];
5673 // width of all the content so far in points
5674 $contentWidth =& $this->flowingBlockAttr
[ 'contentWidth' ];
5675 // cell width in points
5676 $maxWidth =& $this->flowingBlockAttr
[ 'width' ];
5677 $lineCount =& $this->flowingBlockAttr
[ 'lineCount' ];
5678 // line height in user units
5679 $lineHeight =& $this->flowingBlockAttr
[ 'height' ];
5680 $align =& $this->flowingBlockAttr
[ 'align' ];
5681 $content =& $this->flowingBlockAttr
[ 'content' ];
5682 $contentB =& $this->flowingBlockAttr
[ 'contentB' ];
5683 $font =& $this->flowingBlockAttr
[ 'font' ];
5684 $valign =& $this->flowingBlockAttr
[ 'valign' ];
5685 $blockstate = $this->flowingBlockAttr
[ 'blockstate' ];
5687 $newblock = $this->flowingBlockAttr
[ 'newblock' ];
5688 $blockdir = $this->flowingBlockAttr
['blockdir'];
5689 // *********** BLOCK BACKGROUND COLOR ***************** //
5690 if ($this->blk
[$this->blklvl
]['bgcolor'] && !$is_table) {
5694 $this->SetFColor($this->ConvertColor(255));
5697 $font[] = $this->saveFont();
5700 $currContent =& $content[ count( $content ) - 1 ];
5701 // where the line should be cutoff if it is to be justified
5702 $cutoffWidth = $contentWidth;
5704 $CJKoverflow = false;
5705 $hanger = ''; // mPDF 5.6.40
5708 $oldcolumn = $this->CurrCol
;
5710 if ($this->ColActive
&& !$is_table) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
5718 $cpaddingadjustL = 0;
5719 $cpaddingadjustR = 0;
5725 /*-- END TABLES --*/
5726 $ipaddingL = $this->blk
[$this->blklvl
]['padding_left'];
5727 $ipaddingR = $this->blk
[$this->blklvl
]['padding_right'];
5728 $paddingL = ($ipaddingL * _MPDFK
);
5729 $paddingR = ($ipaddingR * _MPDFK
);
5730 $this->cMarginL
= $this->blk
[$this->blklvl
]['border_left']['w'];
5731 $cpaddingadjustL = -$this->cMarginL
;
5732 $this->cMarginR
= $this->blk
[$this->blklvl
]['border_right']['w'];
5733 $cpaddingadjustR = -$this->cMarginR
;
5734 // Added mPDF 3.0 Float DIV
5738 if (count($this->floatDivs
)) {
5739 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl
);
5740 if ($r_exists) { $fpaddingR
= $r_width
; }
5741 if ($l_exists) { $fpaddingL
= $l_width
; }
5743 /*-- END CSS-FLOAT --*/
5745 $usey = $this->y +
0.002;
5746 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
5747 $usey +
= $this->blk
[$this->blklvl
]['margin_top'] +
$this->blk
[$this->blklvl
]['padding_top'] +
$this->blk
[$this->blklvl
]['border_top']['w'];
5749 /*-- CSS-IMAGE-FLOAT --*/
5750 // If float exists at this level
5751 if (isset($this->floatmargins
['R']) && $usey <= $this->floatmargins
['R']['y1'] && $usey >= $this->floatmargins
['R']['y0'] && !$this->floatmargins
['R']['skipline']) { $fpaddingR +
= $this
->floatmargins
['R']['w']; }
5752 if (isset($this->floatmargins
['L']) && $usey <= $this->floatmargins
['L']['y1'] && $usey >= $this->floatmargins
['L']['y0'] && !$this->floatmargins
['L']['skipline']) { $fpaddingL +
= $this
->floatmargins
['L']['w']; }
5753 /*-- END CSS-IMAGE-FLOAT --*/
5756 //OBJECTS - IMAGES & FORM Elements (NB has already skipped line/page if required - in printbuffer)
5757 if (substr($s,0,3) == "\xbb\xa4\xac") { //identifier has been identified!
5758 $objattr = $this->_getObjAttr($s);
5760 if ($is_table) { // *TABLES*
5761 $maximumW = ($maxWidth/_MPDFK
) - ($this->cellPaddingL +
$this->cMarginL +
$this->cellPaddingR +
$this->cMarginR
); // *TABLES*
5764 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) && (!$is_table)) { $h_corr
= $this
->blk
[$this
->blklvl
]['padding_top'] + $this
->blk
[$this
->blklvl
]['border_top']['w']; }
5765 $maximumW = ($maxWidth/_MPDFK
) - ($this->blk
[$this->blklvl
]['padding_left'] +
$this->blk
[$this->blklvl
]['border_left']['w'] +
$this->blk
[$this->blklvl
]['padding_right'] +
$this->blk
[$this->blklvl
]['border_right']['w'] +
$fpaddingL +
$fpaddingR );
5767 $objattr = $this->inlineObject($objattr['type'],$this->lMargin +
$fpaddingL +
($contentWidth/_MPDFK
),($this->y +
$h_corr), $objattr, $this->lMargin
,($contentWidth/_MPDFK
),$maximumW,$lineHeight,true,$is_table);
5769 // SET LINEHEIGHT for this line ================ RESET AT END
5770 $lineHeight = MAX($lineHeight,$objattr['OUTER-HEIGHT']);
5771 $this->objectbuffer
[count($content)-1] = $objattr;
5772 // if (isset($objattr['vertical-align'])) { $valign = $objattr['vertical-align']; }
5773 // else { $valign = ''; }
5774 $contentWidth +
= ($objattr['OUTER-WIDTH'] * _MPDFK
);
5778 $lbw = $rbw = 0; // Border widths
5779 if (!empty($this->spanborddet
)) {
5780 if (isset($this->spanborddet
['L'])) $lbw = $this->spanborddet
['L']['w'];
5781 if (isset($this->spanborddet
['R'])) $rbw = $this->spanborddet
['R']['w'];
5784 if ($this->usingCoreFont
) {
5785 $tmp = strlen( $s );
5788 $tmp = mb_strlen( $s, $this->mb_enc
);
5791 // for every character in the string
5792 for ( $i = 0; $i < $tmp; $i++
) {
5793 // extract the current character
5794 // get the width of the character in points
5795 if ($this->usingCoreFont
) {
5797 // Soft Hyphens chr(173)
5798 $cw = ($this->GetCharWidthCore($c) * _MPDFK
);
5799 if ($this->kerning
&& $this->useKerning
&& $i > 0) {
5800 if (isset($this->CurrentFont
['kerninfo'][$s[($i-1)]][$c])) {
5801 $cw +
= ($this->CurrentFont
['kerninfo'][$s[($i-1)]][$c] * $this->FontSizePt
/ 1000 );
5806 $c = mb_substr($s,$i,1,$this->mb_enc
);
5807 $cw = ($this->GetCharWidthNonCore($c, false) * _MPDFK
);
5808 if ($this->kerning
&& $this->useKerning
&& $i > 0) {
5809 $lastc = mb_substr($s,($i-1),1,$this->mb_enc
);
5810 $ulastc = $this->UTF8StringToArray($lastc, false);
5811 $uc = $this->UTF8StringToArray($c, false);
5812 if (isset($this->CurrentFont
['kerninfo'][$ulastc[0]][$uc[0]])) {
5813 $cw +
= ($this->CurrentFont
['kerninfo'][$ulastc[0]][$uc[0]] * $this->FontSizePt
/ 1000 );
5820 $contentB[(count($contentB)-1)] .= 'L';
5824 $contentB[(count($contentB)-1)] .= 'R';
5829 $cutoffWidth = $contentWidth;
5830 $contentWidth +
= $cw;
5834 // ADDED for Paragraph_indent
5835 $WidthCorrection = 0;
5836 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk
[$this->blklvl
]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align != 'C')) {
5837 $ti = $this->ConvertSize($this->blk
[$this->blklvl
]['text_indent'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
5838 $WidthCorrection = ($ti*_MPDFK
);
5841 // Added mPDF 3.0 Float DIV
5845 if (count($this->floatDivs
)) {
5846 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl
);
5847 if ($r_exists) { $fpaddingR
= $r_width
; }
5848 if ($l_exists) { $fpaddingL
= $l_width
; }
5850 /*-- END CSS-FLOAT --*/
5852 $usey = $this->y +
0.002;
5853 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
5854 $usey +
= $this->blk
[$this->blklvl
]['margin_top'] +
$this->blk
[$this->blklvl
]['padding_top'] +
$this->blk
[$this->blklvl
]['border_top']['w'];
5857 /*-- CSS-IMAGE-FLOAT --*/
5858 // If float exists at this level
5859 if (isset($this->floatmargins
['R']) && $usey <= $this->floatmargins
['R']['y1'] && $usey >= $this->floatmargins
['R']['y0'] && !$this->floatmargins
['R']['skipline']) { $fpaddingR +
= $this
->floatmargins
['R']['w']; }
5860 if (isset($this->floatmargins
['L']) && $usey <= $this->floatmargins
['L']['y1'] && $usey >= $this->floatmargins
['L']['y0'] && !$this->floatmargins
['L']['skipline']) { $fpaddingL +
= $this
->floatmargins
['L']['w']; }
5861 /*-- END CSS-IMAGE-FLOAT --*/
5865 // try adding another char
5866 if (( $contentWidth +
$cw > $maxWidth - $WidthCorrection - (($this->cMarginL+
$this->cMarginR
)*_MPDFK
) - ($paddingL+
$paddingR +
(($fpaddingL +
$fpaddingR) * _MPDFK
) ) +
0.001)) {// 0.001 is to correct for deviations converting mm=>pts
5867 // it won't fit, output what we already have
5870 // contains any content that didn't make it into this print
5872 $savedContentB = '';
5873 $savedFont = array();
5874 $savedObj = array();
5876 $savedPreContent = array();
5877 $savedPreContentB = array();
5878 $savedPreFont = array();
5880 // cut off and save any partial words at the end of the string
5881 $words = explode( ' ', $currContent );
5884 $currWord = $words[count($words)-1] ;
5887 // mPDF 5.6.21 Hard Hyphens -
5888 $hardsuccess = false;
5889 if ($this->textparam
['hyphens'] != 2 && preg_match("/\-/",$currWord)) {
5890 $rem = $maxWidth - $WidthCorrection - (($this->cMarginL+
$this->cMarginR
)*_MPDFK
) - ($paddingL+
$paddingR +
(($fpaddingL +
$fpaddingR) * _MPDFK
) );
5891 list($hardsuccess,$pre,$post,$prelength) = $this->hardHyphenate($currWord, (($rem-$cutoffWidth)/_MPDFK
-$this->GetCharWidth("-", false)) );
5893 $already = array_pop( $words );
5894 $forward = mb_substr($already,$prelength+
1,mb_strlen($already, $this->mb_enc
), $this->mb_enc
);
5895 $words[] = $pre.'-';
5896 $words[] = $forward;
5897 $currContent = mb_substr($currContent,0,mb_strlen($currContent, $this->mb_enc
)+
1-mb_strlen($post, $this->mb_enc
), $this->mb_enc
) . '-';
5901 /*-- HYPHENATION --*/
5902 // Soft Hyphens chr(173)
5903 else if ($this->textparam
['hyphens'] != 2 && (!$this->usingCoreFont
&& preg_match("/\xc2\xad/",$currWord)) || ($this->usingCoreFont
&& preg_match("/".chr(173)."/",$currWord) && ($this->FontFamily
!='csymbol' && $this->FontFamily
!='czapfdingbats')) ) { // mPDF 5.6.06
5904 $rem = $maxWidth - $WidthCorrection - (($this->cMarginL+
$this->cMarginR
)*_MPDFK
) - ($paddingL+
$paddingR +
(($fpaddingL +
$fpaddingR) * _MPDFK
) );
5905 list($success,$pre,$post,$prelength) = $this->softHyphenate($currWord, (($rem-$cutoffWidth)/_MPDFK
-$this->GetCharWidth(" ", false)) );
5908 if (!$success && !$hardsuccess && $this->textparam
['hyphens'] == 1 ) { // mPDF 5.6.06 // mPDF 5.6.21
5909 // Look ahead to get current word
5910 for($ac = $i; $ac<(mb_strlen($s)-1); $ac++
) {
5911 $addc = mb_substr($s,$ac,1,$this->mb_enc
);
5912 if ($addc == ' ') { break; }
5915 $rem = $maxWidth - $WidthCorrection - (($this->cMarginL+
$this->cMarginR
)*_MPDFK
) - ($paddingL+
$paddingR +
(($fpaddingL +
$fpaddingR) * _MPDFK
) );
5916 list($success,$pre,$post,$prelength) = $this->hyphenateWord($currWord, (($rem-$cutoffWidth)/_MPDFK
-$this->GetCharWidth(" ", false)) );
5919 $already = array_pop( $words );
5920 $forward = mb_substr($already,$prelength,mb_strlen($already, $this->mb_enc
), $this->mb_enc
);
5921 $words[] = $pre.'-';
5922 $words[] = $forward;
5923 $currContent = mb_substr($currContent,0,mb_strlen($currContent, $this->mb_enc
)+
1-mb_strlen($post, $this->mb_enc
), $this->mb_enc
) . '-';
5925 /*-- END HYPHENATION --*/
5927 // mPDF 5.6.13 Decimal alignment (cancel if wraps to > 1 line)
5928 if ($is_table && substr($align,0,1)=='D' ) { $align
=substr($align
,2,1); }
5932 if ($this->checkCJK
) {
5933 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc
)-1, 1, $this->mb_enc
);
5935 // Next character is suitable to add as overhanging or squeezed punctuation
5936 if ($this->checkCJK
&& preg_match("/[".$this->CJKoverflow
."]/u", $c) && $this->allowCJKorphans
&& !$CJKoverflow) {
5937 // add character onto this line
5939 $cutoffWidth = $contentWidth;
5940 $contentWidth +
= $cw;
5941 $CJKoverflow = true;
5944 // Last character that fits is not allowed to end a line - move lastchar(s) to start of next line
5945 else if ($this->checkCJK
&& preg_match("/[".$this->CJKleading
."]/u", $lastchar)) {
5946 //move lastchar(s) to next line
5949 while(preg_match("/[".$this->CJKleading
."]/u", $m0) && mb_strlen($words[(count($words)-1)], $this->mb_enc
)>2) {
5950 // trim last letter off word[0]
5951 $words[(count($words)-1)] = mb_substr($words[(count($words)-1)],0,mb_strlen($words[(count($words)-1)], $this->mb_enc
)-1, $this->mb_enc
);
5952 // and add it to savedContent for next line
5953 $savedContent = $m0.$savedContent;
5955 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc
)-1, 1, $this->mb_enc
);
5959 for ( $w = 0; $w < count( $words ) ; $w++
) { $lastContent
.= $words
[ $w
]." "; }
5960 $savedFont = $this->saveFont();
5961 // replace the current content with the cropped version
5962 $currContent = rtrim( $lastContent );
5964 // Next character is not allowed to start a new line
5965 else if ($this->checkCJK
&& preg_match("/[".$this->CJKfollowing
."]/u", $c)) {
5966 // try squeezing another character(s) onto this line = Oikomi
5967 if ($this->allowCJKorphans
&& !$CJKoverflow) { // mPDF 5.6.40
5968 $lookahead = mb_substr($s,$i+
1,1,$this->mb_enc
);
5969 //if lookahead is not another following char
5970 if (!$lookahead || ($lookahead && !preg_match("/[".$this->CJKfollowing
."]/u", $lookahead))) {
5972 $cutoffWidth = $contentWidth;
5973 $contentWidth +
= $cw;
5974 if ($this->allowCJKoverflow
&& preg_match("/[".$this->CJKoverflow
."]/u", $c)) { $CJKoverflow
= true; }
5978 // or move lastchar(s) to next line to keep $c company = Oidashi
5981 while(preg_match("/[".$this->CJKfollowing
."]/u", $m1) && mb_strlen($words[(count($words)-1)], $this->mb_enc
)>2) {
5982 // trim last letter off word[0]
5983 $words[(count($words)-1)] = mb_substr($words[(count($words)-1)],0,mb_strlen($words[(count($words)-1)], $this->mb_enc
)-1, $this->mb_enc
);
5984 // and add it to savedContent for next line
5985 $savedContent = $m0.$savedContent;
5987 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc
)-1, 1, $this->mb_enc
);
5991 for ( $w = 0; $w < count( $words ) ; $w++
) { $lastContent
.= $words
[ $w
]." "; }
5992 $savedFont = $this->saveFont();
5993 // replace the current content with the cropped version
5994 $currContent = rtrim( $lastContent );
5997 else if ($this->checkCJK
&& preg_match("/([".$this->pregCJKchars
."]+[0-9\x{ff10}-\x{ff19}]+$)/u", $words[0])) {
5998 $lookahead = mb_substr($s,$i,16,$this->mb_enc
);
5999 //and if lookahead starts with a few numerals
6000 if ($lookahead && (preg_match("/^([0-9\x{ff10}-\x{ff19}]+[".$this->pregCJKchars
."]+)/u", $lookahead) || preg_match("/^([0-9\x{ff10}-\x{ff19}]+$)/u", $lookahead)) ) {
6001 // or move lastchar(s) to next line to keep numerals together
6003 while(preg_match("/[0-9\x{ff10}-\x{ff19}]/u", $m0) && mb_strlen($words[(count($words)-1)], $this->mb_enc
)>2) {
6004 // trim last letter off word[0]
6005 $words[(count($words)-1)] = mb_substr($words[(count($words)-1)],0,mb_strlen($words[(count($words)-1)], $this->mb_enc
)-1, $this->mb_enc
);
6006 // and add it to savedContent for next line
6007 $savedContent = $m0.$savedContent;
6008 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc
)-1, 1, $this->mb_enc
);
6013 for ( $w = 0; $w < count( $words ) ; $w++
) { $lastContent
.= $words
[ $w
]." "; }
6014 $savedFont = $this->saveFont();
6015 // replace the current content with the cropped version
6016 $currContent = rtrim( $lastContent );
6019 /*-- END CJK-FONTS --*/
6020 // if it looks like we didn't finish any words for this chunk
6021 if ( count( $words ) == 1 ) {
6022 // TO correct for error when word too wide for page - but only when one long word from left to right margin
6023 if (count($content) == 1 && $currContent != ' ') {
6024 $lastchar = mb_substr($words[0],mb_strlen($words[0], $this->mb_enc
)-1, 1, $this->mb_enc
);
6025 $lastContent = $words[0];
6026 $savedFont = $this->saveFont();
6027 // replace the current content with the cropped version
6028 $currContent = rtrim( $lastContent );
6031 else if ( count($content)>1
6032 && (!isset($this->objectbuffer
[(count($content)-1)]) && !isset($this->objectbuffer
[(count($content)-2)]))
6033 && substr($content[count($content)-2],-1,1) != ' '
6034 && substr($currContent,0,1) != ' '
6036 // Go back to find a space in a previous chunk of content
6038 for ($ix=count($content)-1;$ix>=0;$ix--) {
6040 if ($this->usingCoreFont
&& preg_match('/[ '.chr(173).']/',$content[$ix],$m)) { $match
= $m
[0]; $found
= $ix
; break; }
6041 else if (!$this->usingCoreFont
) {
6042 if (preg_match('/[ ]/',$content[$ix])) { $match
= ' '; $found
= $ix
; break; }
6043 else if (preg_match('/[\x{00AD}]/u',$content[$ix])) {
6044 // even though it is UTF-8 replace it temporarily with chr(173)
6045 $content[$ix] = preg_replace('/[\x{00AD}]/u',chr(173),$content[$ix]);
6046 $match = chr(173); $found = $ix; break;
6050 if ($found !== false) {
6051 $charpos = strrpos($content[$found],$match); // mPDF 5.6.29
6052 for ($ix=count($content)-1;$ix>$found;$ix--) {
6053 // save and crop off any subsequent chunks
6054 $savedPreContent[] = array_pop($content);
6055 $savedPreContentB[] = array_pop($contentB);
6056 $savedPreFont[] = array_pop($font);
6058 if (substr($content[count($content)-1],$charpos+
1,strlen($content[count($content)-1])-1) != '') {
6059 $savedPreContent[] = substr($content[count($content)-1],$charpos+
1,strlen($content[count($content)-1])-1);
6060 $savedPreContentB[] = preg_replace('/L/','',$contentB[count($content)-1]); // ???
6061 $savedPreFont[] = $font[count($content)-1];
6064 $savedContentB = '';
6065 $savedFont = array();
6067 $currContent =& $content[ count( $content ) - 1 ];
6068 $currContent = substr($currContent,0,$charpos);
6069 if ($match == chr(173)) { $currContent
.= '-'; } // mPDF 5.6.29
6070 if (strpos($contentB[(count($contentB)-1)],'R')!==false) { // ???
6071 $contentB[count($content)-1] = preg_replace('/R/','',$contentB[count($content)-1]); // ???
6074 $currContent = rtrim( $currContent );
6077 $savedContent = array_pop( $content );
6078 $savedContentB = array_pop($contentB);
6079 $savedFont = array_pop( $font );
6080 $currContent =& $content[ count( $content ) - 1 ];
6081 $currContent = rtrim( $currContent );
6085 // save and crop off the content currently on the stack
6086 $savedContent = array_pop( $content );
6087 $savedContentB = array_pop($contentB); // mPDF 5.6.20
6088 $savedFont = array_pop( $font );
6089 // trim any trailing spaces off the last bit of content
6090 $currContent =& $content[ count( $content ) - 1 ];
6091 $currContent = rtrim( $currContent );
6094 else { // otherwise, we need to find which bit to cut off
6096 for ( $w = 0; $w < count( $words ) - 1; $w++
) { $lastContent
.= $words
[ $w
]." "; }
6097 $savedContent = $words[ count( $words ) - 1 ];
6098 $savedFont = $this->saveFont();
6099 // replace the current content with the cropped version
6100 $currContent = rtrim( $lastContent );
6102 // CJK - strip CJK space at end of line
6103 //   = \xe3\x80\x80 = CJK space
6104 if ($this->checkCJK
) { $currContent
= preg_replace("/\xe3\x80\x80$/",'',$currContent
) ; } // *CJK-FONTS*
6107 if (isset($this->objectbuffer
[(count($content)-1)]) && $this->objectbuffer
[(count($content)-1)]['type']=='dottab') {
6108 $savedObj = array_pop( $this->objectbuffer
);
6109 $contentWidth -= ($this->objectbuffer
[(count($content)-1)]['OUTER-WIDTH'] * _MPDFK
);
6112 // Set Current lineheight (correction factor)
6116 if (preg_match('/([0-9.,]+)mm/',$this->list_lineheight
[$this->listlvl
][$this->listOcc
],$am)) {
6118 $def_fontsize = $this->InlineProperties
['LISTITEM'][$this->listlvl
][$this->listOcc
][$this->listnum
]['size'];
6119 $this->lineheight_correction
= $am[1] / $def_fontsize ;
6122 $this->lineheight_correction
= $this->list_lineheight
[$this->listlvl
][$this->listOcc
];
6129 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight
,$am)) {
6131 $def_fontsize = $this->FontSize
; // needs to be default font-size for block ****
6132 $this->lineheight_correction
= $lineHeight / $def_fontsize ;
6135 $this->lineheight_correction
= $this->table_lineheight
;
6139 /*-- END TABLES --*/
6140 if (isset($this->blk
[$this->blklvl
]['line_height']) && $this->blk
[$this->blklvl
]['line_height']) {
6141 if (preg_match('/([0-9.,]+)mm/',$this->blk
[$this->blklvl
]['line_height'],$am)) {
6143 $def_fontsize = $this->blk
[$this->blklvl
]['InlineProperties']['size']; // needs to be default font-size for block ****
6144 $this->lineheight_correction
= $am[1] / $def_fontsize ;
6147 $this->lineheight_correction
= $this->blk
[$this->blklvl
]['line_height'];
6151 $this->lineheight_correction
= $this->normalLineheight
;
6153 // update $contentWidth and $cutoffWidth since they changed with cropping
6154 // Also correct lineheight to maximum fontsize (not for tables)
6156 // correct lineheight to maximum fontsize
6157 if ($lhfixed) { $maxlineHeight
= $this
->lineheight
; }
6158 else { $maxlineHeight
= 0; }
6159 $this->forceExactLineheight
= true;
6161 // While we're at it, check for cursive text
6162 $checkCursive=false;
6163 if ($this->biDirectional
) { $checkCursive
=true; } // *RTL*
6164 foreach ( $content as $k => $chunk )
6166 $this->restoreFont( $font[ $k ]);
6167 if (!isset($this->objectbuffer
[$k])) {
6169 if ($this->checkCJK
&& $k == count($content)-1 && $CJKoverflow && $align=='J' && $this->allowCJKoverflow
&& $this->CJKforceend
) {
6170 // force-end overhang
6171 $hanger = mb_substr($chunk,mb_strlen($chunk,$this->mb_enc
)-1,1,$this->mb_enc
);
6172 $content[$k] = $chunk = mb_substr($chunk,0,mb_strlen($chunk,$this->mb_enc
)-1,$this->mb_enc
);
6174 if (!$this->usingCoreFont
) {
6175 $content[$k] = $chunk = str_replace("\xc2\xad",'',$chunk );
6176 if (isset($this->CurrentFont
['indic']) && $this->CurrentFont
['indic']) { $checkCursive
=true; } // *INDIC*
6178 // Soft Hyphens chr(173)
6179 else if ($this->FontFamily
!='csymbol' && $this->FontFamily
!='czapfdingbats') {
6180 $content[$k] = $chunk = str_replace(chr(173),'',$chunk );
6182 $contentWidth +
= $this->GetStringWidth( $chunk ) * _MPDFK
;
6183 if (!empty($this->spanborddet
)) {
6184 if (strpos($contentB[$k],'L')!==false) $contentWidth +
= $this->spanborddet
['L']['w'] * _MPDFK
;
6185 if (strpos($contentB[$k],'R')!==false) $contentWidth +
= $this->spanborddet
['R']['w'] * _MPDFK
;
6187 if (!$lhfixed) { $maxlineHeight
= max($maxlineHeight
,$this
->FontSize
* $this
->lineheight_correction
); }
6188 if ($lhfixed && ($this->FontSize
> $def_fontsize || ($this->FontSize
> ($lineHeight * $this->lineheight_correction
) && $is_list))) {
6189 $this->forceExactLineheight
= false;
6191 $maxfontsize = max($maxfontsize,$this->FontSize
);
6195 $lastfontreqstyle = $font[count($font)-1]['ReqFontStyle'];
6196 $lastfontstyle = $font[count($font)-1]['style'];
6197 if ($blockdir == 'ltr' && strpos($lastfontreqstyle,"I") !== false && strpos($lastfontstyle,"I") === false) { // Artificial italic
6198 $lastitalic = $this->FontSize
*0.15*_MPDFK
;
6200 else { $lastitalic
= 0; }
6204 if ($is_list && is_array($this->bulletarray
) && $this->bulletarray
) {
6205 $actfs = $this->bulletarray
['fontsize'];
6206 if (!$lhfixed) { $maxlineHeight
= max($maxlineHeight
,$actfs
* $this
->lineheight_correction
); }
6207 if ($lhfixed && $actfs > $def_fontsize) { $this
->forceExactLineheight
= false; }
6208 $maxfontsize = max($maxfontsize,$actfs);
6212 // when every text item checked i.e. $maxfontsize is set properly
6214 $af = 0; // Above font
6215 $bf = 0; // Below font
6216 $mta = 0; // Maximum top-aligned
6217 $mba = 0; // Maximum bottom-aligned
6219 foreach ( $content as $k => $chunk ) {
6220 if (isset($this->objectbuffer
[$k]) && $this->objectbuffer
[$k]) {
6221 $contentWidth +
= $this->objectbuffer
[$k]['OUTER-WIDTH'] * _MPDFK
;
6222 $oh = $this->objectbuffer
[$k]['OUTER-HEIGHT'];
6223 $va = $this->objectbuffer
[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
6224 if ($lhfixed && $oh > $def_fontsize) { $this
->forceExactLineheight
= false; }
6226 if ($va == 'BS') { // (BASELINE default)
6227 $af = max($af, ($oh - ($maxfontsize * (0.5 +
$this->baselineC
))));
6229 else if ($va == 'M') {
6230 $af = max($af, ($oh - $maxfontsize)/2);
6231 $bf = max($bf, ($oh - $maxfontsize)/2);
6233 else if ($va == 'TT') {
6234 $bf = max($bf, ($oh - $maxfontsize));
6236 else if ($va == 'TB') {
6237 $af = max($af, ($oh - $maxfontsize));
6239 else if ($va == 'T') {
6240 $mta = max($mta, $oh);
6242 else if ($va == 'B') {
6243 $mba = max($mba, $oh);
6247 if ((!$lhfixed || !$this->forceExactLineheight
) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
6248 $maxlineHeight = $maxfontsize +
$af +
$bf;
6250 else if (!$lhfixed) { $af
= $bf
= ($maxlineHeight
- $maxfontsize
)/2; }
6252 if ($mta > $maxlineHeight) {
6253 $bf +
= ($mta - $maxlineHeight);
6254 $maxlineHeight = $mta;
6256 if ($mba > $maxlineHeight) {
6257 $af +
= ($mba - $maxlineHeight);
6258 $maxlineHeight = $mba;
6262 $lineHeight = $maxlineHeight;
6263 $cutoffWidth = $contentWidth;
6264 // If NOT images, and maxfontsize NOT > lineHeight - this value determines text baseline positioning
6265 if ($lhfixed && $af==0 && $bf==0 && $maxfontsize<=($def_fontsize * $this->lineheight_correction
* 0.8 )) {
6266 $this->linemaxfontsize
= $def_fontsize;
6268 else { $this
->linemaxfontsize
= $maxfontsize
; }
6272 foreach ( $content as $k => $chunk ) {
6273 if (!isset($this->objectbuffer
[$k]) || (isset($this->objectbuffer
[$k]) && !$this->objectbuffer
[$k])) {
6274 if ($this->usingCoreFont
) {
6275 $content[$k] = str_replace(chr(160),chr(32),$chunk );
6278 $content[$k] = str_replace(chr(194).chr(160),chr(32),$chunk );
6279 if ($checkCursive) {
6280 if (preg_match("/([".$this->pregRTLchars
."])/u", $chunk)) { $inclCursive
= true; } // *RTL*
6281 if (preg_match("/([".$this->pregHIchars
.$this->pregBNchars
.$this->pregPAchars
."])/u", $chunk)) { $inclCursive
= true; } // *INDIC*
6292 // if it's justified, we need to find the char/word spacing (or if orphans have allowed length of line to go over the maxwidth)
6293 if ( ($align == 'J' && !$CJKoverflow) || (($cutoffWidth +
$lastitalic > $maxWidth - $WidthCorrection - (($this->cMarginL+
$this->cMarginR
)*_MPDFK
) - ($paddingL+
$paddingR +
(($fpaddingL +
$fpaddingR) * _MPDFK
) ) +
0.001) && (!$CJKoverflow || ($CJKoverflow && !$this->allowCJKoverflow
))) || $CJKoverflow && $align=='J' && $this->allowCJKoverflow
&& $hanger && $this->CJKforceend
) { // 0.001 is to correct for deviations converting mm=>pts // mPDF 5.6.40
6294 // JUSTIFY J (Use character spacing)
6296 foreach ( $content as $k => $chunk ) {
6297 if (!isset($this->objectbuffer
[$k]) || (isset($this->objectbuffer
[$k]) && !$this->objectbuffer
[$k])) {
6298 $nb_carac +
= mb_strlen( $chunk, $this->mb_enc
) ;
6299 $nb_spaces +
= mb_substr_count( $chunk,' ', $this->mb_enc
) ;
6302 list($jcharspacing,$jws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$cutoffWidth-$WidthCorrection-(($this->cMarginL+
$this->cMarginR
)*_MPDFK
)-($paddingL+
$paddingR +
(($fpaddingL +
$fpaddingR) * _MPDFK
) )),$inclCursive);
6307 $empty = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+
$this->cMarginR
)* _MPDFK
) - ($paddingL+
$paddingR +
(($fpaddingL +
$fpaddingR) * _MPDFK
) );
6309 $empty -= ($jcharspacing * $nb_carac);
6310 $empty -= ($jws * $nb_spaces);
6313 $b = ''; //do not use borders
6314 // Get PAGEBREAK TO TEST for height including the top border/padding
6315 $check_h = max($this->divheight
,$lineHeight);
6316 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($this->blklvl
> 0) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6317 $check_h +
= ($this->blk
[$this->blklvl
]['padding_top'] +
$this->blk
[$this->blklvl
]['margin_top'] +
$this->blk
[$this->blklvl
]['border_top']['w']);
6320 if ($this->ColActive
&& $check_h > ($this->PageBreakTrigger
- $this->y0
)) {
6321 $this->SetCol($this->NbCol
-1);
6325 // 'If' below used in order to fix "first-line of other page with justify on" bug
6326 if(!$is_table && ($this->y+
$check_h) > $this->PageBreakTrigger
and !$this->InFooter
and $this->AcceptPageBreak()) {
6327 $bak_x=$this->x
;//Current X position
6330 $ws=$this->ws
;//Word Spacing
6331 $charspacing=$this->charspacing
;//Character Spacing
6332 $this->ResetSpacing();
6334 $this->AddPage($this->CurOrientation
);
6337 // Added to correct for OddEven Margins
6338 $currentx +
= $this->MarginCorrection
;
6339 $this->x +
= $this->MarginCorrection
;
6342 $this->SetSpacing($charspacing,$ws);
6345 if ($this->keep_block_together
&& !$is_table && $this->kt_p00
< $this->page
&& ($this->y+
$check_h) > $this->kt_y00
) {
6346 $this->printdivbuffer();
6347 $this->keep_block_together
= 0;
6354 if ($this->CurrCol
!= $oldcolumn) {
6355 $currentx +
= $this->ChangeColumn
* ($this->ColWidth+
$this->ColGap
);
6356 $this->x +
= $this->ChangeColumn
* ($this->ColWidth+
$this->ColGap
);
6357 $oldcolumn = $this->CurrCol
;
6360 if ($this->ColActive
&& !$is_table) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
6361 /*-- END COLUMNS --*/
6364 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($this->blk
[$this->blklvl
]['margin_top']) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6365 $this->DivLn($this->blk
[$this->blklvl
]['margin_top'],$this->blklvl
-1,true,$this->blk
[$this->blklvl
]['margin_collapse']);
6366 if ($this->ColActive
) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
6370 // Update y0 for top of block (used to paint border)
6371 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6372 $this->blk
[$this->blklvl
]['y0'] = $this->y
;
6373 $this->blk
[$this->blklvl
]['startpage'] = $this->page
;
6374 if ($this->blk
[$this->blklvl
]['float']) { $this
->blk
[$this
->blklvl
]['float_start_y'] = $this
->y
; } // mPDF 5.6.63
6377 // TOP PADDING and BORDER spacing/fill
6378 if (($newblock) && ($blockstate==1 || $blockstate==3) && (($this->blk
[$this->blklvl
]['padding_top']) || ($this->blk
[$this->blklvl
]['border_top'])) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6379 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
6380 $this->DivLn($this->blk
[$this->blklvl
]['padding_top'] +
$this->blk
[$this->blklvl
]['border_top']['w'],-3,true,false,1);
6381 if ($this->ColActive
) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
6384 $arraysize = count($content);
6386 $margins = ($this->cMarginL+
$this->cMarginR
) +
($ipaddingL+
$ipaddingR +
$fpaddingR +
$fpaddingR );
6388 // PAINT BACKGROUND FOR THIS LINE
6389 if (!$is_table) { $this
->DivLn($lineHeight
,$this
->blklvl
,false); } // false -> don't advance y
6391 $this->x
= $currentx +
$this->cMarginL +
$ipaddingL +
$fpaddingL ;
6392 if ($align == 'R') { $this
->x +
= $
empty; }
6393 else if ($align == 'C') { $this
->x +
= ($
empty / 2); }
6396 if (isset($this->blk
[$this->blklvl
]['text_indent']) && ($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 1) && (!$is_table) && ($blockdir !='rtl') && ($align !='C')) {
6397 $ti = $this->ConvertSize($this->blk
[$this->blklvl
]['text_indent'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
6401 // DIRECTIONALITY RTL
6403 $contains_rtl = false;
6405 if ($blockdir == 'rtl' || $this->biDirectional
) {
6407 foreach ( $content as $k => $chunk ) {
6408 $reversed = $this->magic_reverse_dir($chunk, false, $blockdir);
6410 if ($reversed > 0) { $contains_rtl
= true; }
6411 if ($reversed < 2) { $all_rtl
= false; }
6412 $content[$k] = $chunk;
6414 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) {
6415 $content = array_reverse($content,false);
6416 $contentB = array_reverse($contentB,false);
6421 foreach ( $content as $k => $chunk ) {
6423 // FOR IMAGES - UPDATE POSITION
6424 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) { $dirk
= $arraysize
-1 - $k
; } else { $dirk
= $k
; }
6426 $va = 'M'; // default for text
6427 if (isset($this->objectbuffer
[$dirk]) && $this->objectbuffer
[$dirk]) {
6428 $xadj = $this->x
- $this->objectbuffer
[$dirk]['OUTER-X'] ;
6429 $this->objectbuffer
[$dirk]['OUTER-X'] +
= $xadj;
6430 $this->objectbuffer
[$dirk]['BORDER-X'] +
= $xadj;
6431 $this->objectbuffer
[$dirk]['INNER-X'] +
= $xadj;
6432 $va = $this->objectbuffer
[$dirk]['vertical-align'];
6433 $yadj = $this->y
- $this->objectbuffer
[$dirk]['OUTER-Y'];
6435 $yadj +
= $af +
($this->linemaxfontsize
* (0.5 +
$this->baselineC
)) - $this->objectbuffer
[$dirk]['OUTER-HEIGHT'];
6437 else if ($va == 'M' || $va == '') {
6438 $yadj +
= $af +
($this->linemaxfontsize
/2) - ($this->objectbuffer
[$dirk]['OUTER-HEIGHT']/2);
6440 else if ($va == 'TB') {
6441 $yadj +
= $af +
$this->linemaxfontsize
- $this->objectbuffer
[$dirk]['OUTER-HEIGHT'];
6443 else if ($va == 'TT') {
6446 else if ($va == 'B') {
6447 $yadj +
= $af +
$this->linemaxfontsize +
$bf - $this->objectbuffer
[$dirk]['OUTER-HEIGHT'];
6449 else if ($va == 'T') {
6452 $this->objectbuffer
[$dirk]['OUTER-Y'] +
= $yadj;
6453 $this->objectbuffer
[$dirk]['BORDER-Y'] +
= $yadj;
6454 $this->objectbuffer
[$dirk]['INNER-Y'] +
= $yadj;
6457 // DIRECTIONALITY RTL
6458 if ((($blockdir == 'rtl') && ($contains_rtl )) || ($all_rtl )) { $this
->restoreFont($font
[$arraysize
-1 - $k
]); }
6459 else { $this
->restoreFont( $font
[ $k
] ); }
6461 $this->SetSpacing(($this->fixedlSpacing
*_MPDFK
)+
$jcharspacing,($this->fixedlSpacing+
$this->minwSpacing
)*_MPDFK+
$jws);
6462 // Now unset these values so they don't influence GetStringwidth below or in fn. Cell
6463 $this->fixedlSpacing
= false;
6464 $this->minwSpacing
= 0;
6467 $save_vis = $this->visibility
;
6468 if (isset($this->textparam
['visibility']) && $this->textparam
['visibility'] && $this->textparam
['visibility'] != $this->visibility
) {
6469 $this->SetVisibility($this->textparam
['visibility']);
6471 // *********** SPAN BACKGROUND COLOR ***************** //
6472 if ($this->spanbgcolor
) {
6473 $cor = $this->spanbgcolorarray
;
6474 $this->SetFColor($cor);
6475 $save_fill = $fill; $spanfill = 1; $fill = 1;
6477 if (!empty($this->spanborddet
)) {
6478 if (strpos($contentB[$k],'L')!==false) $this->x +
= $this->spanborddet
['L']['w'];
6479 if (strpos($contentB[$k],'L')===false) $this->spanborddet
['L']['s'] = $this->spanborddet
['L']['w'] = 0;
6480 if (strpos($contentB[$k],'R')===false) $this->spanborddet
['R']['s'] = $this->spanborddet
['R']['w'] = 0;
6484 $stringWidth = $this->GetStringWidth($chunk );
6485 $stringWidth +
= ( $this->charspacing
* mb_strlen($chunk,$this->mb_enc
) / _MPDFK
);
6486 $stringWidth +
= ( $this->ws
* mb_substr_count($chunk,' ',$this->mb_enc
) / _MPDFK
);
6487 if (isset($this->objectbuffer
[$dirk])) { $stringWidth
= $this
->objectbuffer
[$dirk
]['OUTER-WIDTH']; }
6489 if ($stringWidth==0) { $stringWidth
= 0.000001; }
6490 if ($k == $arraysize-1) {
6491 $stringWidth -= ( $this->charspacing
/ _MPDFK
);
6493 if ($this->checkCJK
&& $CJKoverflow && $align=='J' && $this->allowCJKoverflow
&& $hanger && $this->CJKforceend
) {
6494 // force-end overhang
6495 $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF
, $currentx,0,0,'M', $fill, $af, $bf, true );
6496 $this->Cell( $this->GetStringWidth($hanger), $lineHeight, $hanger, '', 1, '', $fill, $this->HREF
, $currentx,0,0,'M', $fill, $af, $bf, true );
6499 $this->Cell( $stringWidth, $lineHeight, $chunk, '', 1, '', $fill, $this->HREF
, $currentx,0,0,'M', $fill, $af, $bf, true ); //mono-style line or last part (skips line)
6503 else $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF
, 0, 0,0,'M', $fill, $af, $bf, true );//first or middle part
6505 if (!empty($this->spanborddet
)) {
6506 if (strpos($contentB[$k],'R')!==false && $k != $arraysize-1) $this->x +
= $this->spanborddet
['R']['w'];
6508 // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
6509 if (isset($spanfill) && $spanfill) {
6510 $fill = $save_fill; $spanfill = 0;
6511 if ($fill) { $this
->SetFColor($bcor
); }
6514 if (isset($this->textparam
['visibility']) && $this->textparam
['visibility'] && $this->visibility
!= $save_vis) {
6515 $this->SetVisibility($save_vis);
6520 $this->maxPosR
= max($this->maxPosR
, ($this->w
- $this->rMargin
- $this->blk
[$this->blklvl
]['outer_right_margin']));
6521 $this->maxPosL
= min($this->maxPosL
, ($this->lMargin +
$this->blk
[$this->blklvl
]['outer_left_margin']));
6524 // move on to the next line, reset variables, tack on saved content and current char
6526 $this->printobjectbuffer($is_table, $blockdir);
6527 $this->objectbuffer
= array();
6530 // LIST BULLETS/NUMBERS
6531 if ($is_list && is_array($this->bulletarray
) && ($lineCount == 1) ) {
6533 $this->ResetSpacing();
6535 $bull = $this->bulletarray
;
6536 if (isset($bull['level']) && isset($bull['occur']) && isset($this->InlineProperties
['LIST'][$bull['level']][$bull['occur']])) {
6537 $this->restoreInlineProperties($this->InlineProperties
['LIST'][$bull['level']][$bull['occur']]);
6539 if (isset($bull['level']) && isset($bull['occur']) && isset($bull['num']) && isset($this->InlineProperties
['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]) && $this->InlineProperties
['LISTITEM'][$bull['level']][$bull['occur']][$bull['num']]) { $this
->restoreInlineProperties($this
->InlineProperties
['LISTITEM'][$bull
['level']][$bull
['occur']][$bull
['num']]); }
6540 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
6541 $this->bullet
= true;
6542 $this->SetFont('czapfdingbats','',$this->FontSizePt
/2.5);
6544 else { $this
->SetFont($this
->FontFamily
,$this
->FontStyle
,$this
->FontSizePt
,true,true); } // force output
6546 $this->x
= $currentx;
6547 if (isset($bull['x'])) { $this
->x +
= $bull
['x']; }
6548 $this->y
-= $lineHeight;
6549 if (isset($bull['col']) && $bull['col']) { $this
->SetTColor($bull
['col']); } // mPDF 5.6.67
6550 if (isset($bull['txt'])) { $this
->Cell($bull
['w'], $lineHeight
,$bull
['txt'],'','',$bull
['align'],0,'',0,-$this
->cMarginL
, -$this
->cMarginR
); }
6551 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
6552 $this->bullet
= false;
6554 $this->x
= $currentx; // Reset
6555 $this->y +
= $lineHeight;
6557 if ($this->ColActive
&& !$is_table) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
6559 $this->bulletarray
= array(); // prevents repeat of bullet/number if <li>....<br />.....</li>
6564 /*-- CSS-IMAGE-FLOAT --*/
6565 // Update values if set to skipline
6566 if ($this->floatmargins
) { $this
->_advanceFloatMargins(); }
6567 /*-- END CSS-IMAGE-FLOAT --*/
6570 $lineHeight = $this->divheight
;
6575 $contentB = array();
6577 if (!empty($savedObj)) {
6578 $this->objectbuffer
[] = $savedObj;
6579 $font[] = $savedFont;
6582 $contentWidth +
= $savedObj['OUTER-WIDTH'] * _MPDFK
;
6585 if (count($savedPreContent) > 0) {
6586 for($ix=count($savedPreContent)-1;$ix>=0;$ix--) {
6587 $font[] = $savedPreFont[$ix];
6588 $content[] = $savedPreContent[$ix];
6589 $contentB[] = $savedPreContentB[$ix];
6590 $this->restoreFont( $savedPreFont[$ix] );
6591 $lbw = $rbw = 0; // Border widths
6592 if (!empty($this->spanborddet
)) {
6593 $lbw = $this->spanborddet
['L']['w'];
6594 $rbw = $this->spanborddet
['R']['w'];
6597 $contentWidth +
= $this->GetStringWidth( $savedPreContent[$ix] ) * _MPDFK
;
6598 if (strpos($savedPreContentB[$ix],'L')!==false) $contentWidth +
= $lbw;
6599 if (strpos($savedPreContentB[$ix],'R')!==false) $contentWidth +
= $rbw;
6602 $savedPreContent = array();
6603 $savedPreContentB = array();
6604 $savedPreFont = array();
6605 $content[ (count($content)-1) ] .= $c;
6608 $font[] = $savedFont;
6609 $content[] = $savedContent . $c;
6610 $contentB[] = $savedContentB ;
6613 $currContent =& $content[ (count($content)-1) ];
6615 // CJK - strip CJK space at end of line
6616 //   = \xe3\x80\x80 = CJK space
6617 if ($this->checkCJK
&& $currContent == "\xe3\x80\x80") { $currContent
= '' ; } // *CJK-FONTS*
6619 $this->restoreFont( $savedFont );
6620 $lbw = $rbw = 0; // Border widths
6621 if (!empty($this->spanborddet
)) {
6622 $lbw = $this->spanborddet
['L']['w'];
6623 $rbw = $this->spanborddet
['R']['w'];
6625 $contentWidth +
= $this->GetStringWidth( $currContent ) * _MPDFK
;
6626 if (strpos($savedContentB,'L')!==false) $contentWidth +
= $lbw;
6627 $cutoffWidth = $contentWidth;
6628 $CJKoverflow = false;
6629 $hanger = ''; // mPDF 5.6.40
6631 // another character will fit, so add it on
6633 $contentWidth +
= $cw;
6640 //----------------------END OF FLOWING BLOCK------------------------------------//
6643 /*-- CSS-IMAGE-FLOAT --*/
6644 // Update values if set to skipline
6645 function _advanceFloatMargins() {
6646 // Update floatmargins - L
6647 if (isset($this->floatmargins
['L']) && $this->floatmargins
['L']['skipline'] && $this->floatmargins
['L']['y0'] != $this->y
) {
6648 $yadj = $this->y
- $this->floatmargins
['L']['y0'];
6649 $this->floatmargins
['L']['y0'] = $this->y
;
6650 $this->floatmargins
['L']['y1'] +
= $yadj;
6652 // Update objattr in floatbuffer
6653 if ($this->floatbuffer
[$this->floatmargins
['L']['id']]['border_left']['w']) {
6654 $this->floatbuffer
[$this->floatmargins
['L']['id']]['BORDER-Y'] +
= $yadj;
6656 $this->floatbuffer
[$this->floatmargins
['L']['id']]['INNER-Y'] +
= $yadj;
6657 $this->floatbuffer
[$this->floatmargins
['L']['id']]['OUTER-Y'] +
= $yadj;
6660 $this->floatbuffer
[$this->floatmargins
['L']['id']]['skipline'] = false;
6661 $this->floatmargins
['L']['skipline'] = false;
6662 $this->floatmargins
['L']['id'] = '';
6664 // Update floatmargins - R
6665 if (isset($this->floatmargins
['R']) && $this->floatmargins
['R']['skipline'] && $this->floatmargins
['R']['y0'] != $this->y
) {
6666 $yadj = $this->y
- $this->floatmargins
['R']['y0'];
6667 $this->floatmargins
['R']['y0'] = $this->y
;
6668 $this->floatmargins
['R']['y1'] +
= $yadj;
6670 // Update objattr in floatbuffer
6671 if ($this->floatbuffer
[$this->floatmargins
['R']['id']]['border_left']['w']) {
6672 $this->floatbuffer
[$this->floatmargins
['R']['id']]['BORDER-Y'] +
= $yadj;
6674 $this->floatbuffer
[$this->floatmargins
['R']['id']]['INNER-Y'] +
= $yadj;
6675 $this->floatbuffer
[$this->floatmargins
['R']['id']]['OUTER-Y'] +
= $yadj;
6678 $this->floatbuffer
[$this->floatmargins
['R']['id']]['skipline'] = false;
6679 $this->floatmargins
['R']['skipline'] = false;
6680 $this->floatmargins
['R']['id'] = '';
6683 /*-- END CSS-IMAGE-FLOAT --*/
6687 ////////////////////////////////////////////////////////////////////////////////
6688 // ADDED forcewrap - to call from inline OBJECT functions to breakwords if necessary in cell
6689 ////////////////////////////////////////////////////////////////////////////////
6690 function WordWrap(&$text, $maxwidth, $forcewrap = 0) {
6694 $text = trim($text);
6696 if ($text==='') return 0;
6697 $space = $this->GetCharWidth(' ',false);
6698 $lines = explode("\n", $text);
6701 foreach ($lines as $line) {
6702 $words = explode(' ', $line);
6704 foreach ($words as $word) {
6705 $word = trim($word);
6706 $wordwidth = $this->GetStringWidth($word);
6707 //Warn user that maxwidth is insufficient
6708 if ($wordwidth > $maxwidth +
0.0001) {
6709 if ($wordwidth > $biggestword) { $biggestword
= $wordwidth
; }
6713 while($wordwidth > $maxwidth) {
6714 $chw = 0; // check width
6715 for ( $i = 0; $i < mb_strlen($word, $this->mb_enc
); $i++
) {
6716 $chw = $this->GetStringWidth(mb_substr($word,0,$i+
1,$this->mb_enc
));
6717 if ($chw > $maxwidth ) {
6719 $text = rtrim($text)."\n".mb_substr($word,0,$i,$this->mb_enc
);
6723 $text = mb_substr($word,0,$i,$this->mb_enc
);
6725 $word = mb_substr($word,$i,mb_strlen($word, $this->mb_enc
)-$i,$this->mb_enc
);
6726 $wordwidth = $this->GetStringWidth($word);
6735 if ($width +
$wordwidth < $maxwidth - 0.0001) {
6736 $width +
= $wordwidth +
$space;
6740 $width = $wordwidth +
$space;
6741 $text = rtrim($text)."\n".$word.' ';
6748 $text = rtrim($text);
6750 //Return -(wordsize) if word is bigger than maxwidth
6753 if ($forcewrap) { return $count
; }
6754 if (($toonarrow) && ($this->table_error_report
)) {
6755 $this->Error("Word is too long to fit in table - ".$this->table_error_report_param
);
6757 if ($toonarrow) return -$biggestword;
6761 /*-- END HTML-CSS --*/
6763 function _SetTextRendering($mode) {
6764 if (!(($mode == 0) || ($mode == 1) || ($mode == 2)))
6765 $this->Error("Text rendering mode should be 0, 1 or 2 (value : $mode)");
6766 $tr = ($mode.' Tr');
6767 if($this->page
>0 && ((isset($this->pageoutput
[$this->page
]['TextRendering']) && $this->pageoutput
[$this->page
]['TextRendering'] != $tr) || !isset($this->pageoutput
[$this->page
]['TextRendering']) || $this->keep_block_together
)) { $this
->_out($tr
); }
6768 $this->pageoutput
[$this->page
]['TextRendering'] = $tr;
6772 function SetTextOutline($params=array()) { // mPDF 5.6.07
6773 if (isset($params['outline-s']) && $params['outline-s'])
6775 $this->SetLineWidth($params['outline-WIDTH']);
6776 $this->SetDColor($params['outline-COLOR']);
6778 if($this->page
>0 && ((isset($this->pageoutput
[$this->page
]['TextRendering']) && $this->pageoutput
[$this->page
]['TextRendering'] != $tr) || !isset($this->pageoutput
[$this->page
]['TextRendering']) || $this->keep_block_together
)) { $this
->_out($tr
); }
6779 $this->pageoutput
[$this->page
]['TextRendering'] = $tr;
6781 else //Now resets all values
6783 $this->SetLineWidth(0.2);
6784 $this->SetDColor($this->ConvertColor(0));
6785 $this->_SetTextRendering(0);
6787 if($this->page
>0 && ((isset($this->pageoutput
[$this->page
]['TextRendering']) && $this->pageoutput
[$this->page
]['TextRendering'] != $tr) || !isset($this->pageoutput
[$this->page
]['TextRendering']) || $this->keep_block_together
)) { $this
->_out($tr
); }
6788 $this->pageoutput
[$this->page
]['TextRendering'] = $tr;
6792 function Image($file,$x,$y,$w=0,$h=0,$type='',$link='',$paint=true, $constrain=true, $watermark=false, $shownoimg=true, $allowvector=true) {
6793 $orig_srcpath = $file;
6794 $this->GetFullPath($file);
6796 $info=$this->_getImage($file, true, $allowvector, $orig_srcpath );
6797 if(!$info && $paint) {
6798 $info = $this->_getImage($this->noImageFile
);
6800 $file = $this->noImageFile
;
6801 $w = ($info['w'] * (25.4/$this->dpi
)); // 14 x 16px
6802 $h = ($info['h'] * (25.4/$this->dpi
)); // 14 x 16px
6805 if(!$info) return false;
6806 //Automatic width and height calculation if needed
6807 if($w==0 and $h==0) {
6808 /*-- IMAGES-WMF --*/
6809 if ($info['type']=='wmf') {
6810 // WMF units are twips (1/20pt)
6811 // divide by 20 to get points
6812 // divide by k to get user units
6813 $w = abs($info['w'])/(20*_MPDFK
);
6814 $h = abs($info['h']) / (20*_MPDFK
);
6817 /*-- END IMAGES-WMF --*/
6818 if ($info['type']=='svg') {
6819 // returned SVG units are pts
6820 // divide by k to get user units (mm)
6821 $w = abs($info['w'])/_MPDFK
;
6822 $h = abs($info['h']) /_MPDFK
;
6825 //Put image at default image dpi
6826 $w=($info['w']/_MPDFK
) * (72/$this->img_dpi
);
6827 $h=($info['h']/_MPDFK
) * (72/$this->img_dpi
);
6830 if($w==0) $w=abs($h*$info['w']/$info['h']);
6831 if($h==0) $h=abs($w*$info['h']/$info['w']);
6837 // Size = D PF or array
6838 if (is_array($this->watermark_size
)) {
6839 $w = $this->watermark_size
[0];
6840 $h = $this->watermark_size
[1];
6842 else if (!is_string($this->watermark_size
)) {
6843 $maxw -= $this->watermark_size
*2;
6844 $maxh -= $this->watermark_size
*2;
6846 $h=abs($w*$info['h']/$info['w']);
6848 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
6851 else if ($this->watermark_size
== 'F') {
6852 if ($this->ColActive
) { $maxw
= $this
->w
- ($this
->DeflMargin + $this
->DefrMargin
); }
6853 else { $maxw
= $this
->pgwidth
; }
6854 $maxh = $this->h
- ($this->tMargin +
$this->bMargin
);
6856 $h=abs($w*$info['h']/$info['w']);
6858 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
6861 else if ($this->watermark_size
== 'P') { // Default P
6863 $h=abs($w*$info['h']/$info['w']);
6865 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
6868 // Automatically resize to maximum dimensions of page if too large
6871 $h=abs($w*$info['h']/$info['w']);
6875 $w=abs($h*$info['w']/$info['h']);
6878 if (is_array($this->watermark_pos
)) {
6879 $x = $this->watermark_pos
[0];
6880 $y = $this->watermark_pos
[1];
6882 else if ($this->watermark_pos
== 'F') { // centred on printable area
6883 if ($this->ColActive
) { // *COLUMNS*
6884 if (($this->mirrorMargins
) && (($this->page
)%
2==0)) { $xadj
= $this
->DeflMargin
-$this
->DefrMargin
; } // *COLUMNS*
6885 else { $xadj
= 0; } // *COLUMNS*
6886 $x = ($this->DeflMargin
- $xadj +
($this->w
- ($this->DeflMargin +
$this->DefrMargin
))/2) - ($w/2); // *COLUMNS*
6889 $x = ($this->lMargin +
($this->pgwidth
)/2) - ($w/2);
6891 $y = ($this->tMargin +
($this->h
- ($this->tMargin +
$this->bMargin
))/2) - ($h/2);
6893 else { // default P - centred on whole page
6894 $x = ($this->w
/2) - ($w/2);
6895 $y = ($this->h
/2) - ($h/2);
6897 /*-- IMAGES-WMF --*/
6898 if ($info['type']=='wmf') {
6899 $sx = $w*_MPDFK
/ $info['w'];
6900 $sy = -$h*_MPDFK
/ $info['h'];
6901 $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x*_MPDFK
-$sx*$info['x'], (($this->h
-$y)*_MPDFK
)-$sy*$info['y'], $info['i']);
6904 /*-- END IMAGES-WMF --*/
6905 if ($info['type']=='svg') {
6906 $sx = $w*_MPDFK
/ $info['w'];
6907 $sy = -$h*_MPDFK
/ $info['h'];
6908 $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x*_MPDFK
-$sx*$info['x'], (($this->h
-$y)*_MPDFK
)-$sy*$info['y'], $info['i']);
6911 $outstring = sprintf("q %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q",$w*_MPDFK
,$h*_MPDFK
,$x*_MPDFK
,($this->h
-($y+
$h))*_MPDFK
,$info['i']);
6914 if ($this->watermarkImgBehind
) {
6915 $outstring = $this->watermarkImgAlpha
. "\n" . $outstring . "\n" . $this->SetAlpha(1, 'Normal', true) . "\n";
6916 $this->pages
[$this->page
] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', "\n".$outstring."\n".'\\1', $this->pages
[$this->page
]);
6918 else { $this
->_out($outstring
); }
6921 } // end of IF watermark
6922 /*-- END WATERMARK --*/
6925 // Automatically resize to maximum dimensions of page if too large
6926 if (isset($this->blk
[$this->blklvl
]['inner_width']) && $this->blk
[$this->blklvl
]['inner_width']) { $maxw
= $this
->blk
[$this
->blklvl
]['inner_width']; }
6927 else { $maxw
= $this
->pgwidth
; }
6930 $h=abs($w*$info['h']/$info['w']);
6932 if ($h > $this->h
- ($this->tMargin +
$this->bMargin +
1)) { // see below - +10 to avoid drawing too close to border of page
6933 $h = $this->h
- ($this->tMargin +
$this->bMargin +
1) ;
6934 if ($this->fullImageHeight
) { $h
= $this
->fullImageHeight
; }
6935 $w=abs($h*$info['w']/$info['h']);
6939 //Avoid drawing out of the paper(exceeding width limits).
6940 //if ( ($x + $w) > $this->fw ) {
6941 if ( ($x +
$w) > $this->w
) {
6942 $x = $this->lMargin
;
6946 $changedpage = false;
6947 $oldcolumn = $this->CurrCol
;
6948 //Avoid drawing out of the page.
6949 if($y+
$h>$this->PageBreakTrigger
and !$this->InFooter
and $this->AcceptPageBreak()) {
6950 $this->AddPage($this->CurOrientation
);
6951 // Added to correct for OddEven Margins
6952 $x=$x +
$this->MarginCorrection
;
6953 $y = $tMargin +
$this->margin_header
;
6954 $changedpage = true;
6959 if ($this->CurrCol
!= $oldcolumn) {
6961 $x +
= $this->ChangeColumn
* ($this->ColWidth+
$this->ColGap
);
6962 $this->x +
= $this->ChangeColumn
* ($this->ColWidth+
$this->ColGap
);
6964 /*-- END COLUMNS --*/
6965 } // end of IF constrain
6967 /*-- IMAGES-WMF --*/
6968 if ($info['type']=='wmf') {
6969 $sx = $w*_MPDFK
/ $info['w'];
6970 $sy = -$h*_MPDFK
/ $info['h'];
6971 $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x*_MPDFK
-$sx*$info['x'], (($this->h
-$y)*_MPDFK
)-$sy*$info['y'], $info['i']);
6974 /*-- END IMAGES-WMF --*/
6975 if ($info['type']=='svg') {
6976 $sx = $w*_MPDFK
/ $info['w'];
6977 $sy = -$h*_MPDFK
/ $info['h'];
6978 $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x*_MPDFK
-$sx*$info['x'], (($this->h
-$y)*_MPDFK
)-$sy*$info['y'], $info['i']);
6981 $outstring = sprintf("q %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q",$w*_MPDFK
,$h*_MPDFK
,$x*_MPDFK
,($this->h
-($y+
$h))*_MPDFK
,$info['i']);
6985 $this->_out($outstring);
6986 if($link) $this->Link($x,$y,$w,$h,$link);
6988 // Avoid writing text on top of the image. // THIS WAS OUTSIDE THE if ($paint) bit!!!!!!!!!!!!!!!!
6992 //Return width-height array
6993 $sizesarray['WIDTH'] = $w;
6994 $sizesarray['HEIGHT'] = $h;
6995 $sizesarray['X'] = $x; //Position before painting image
6996 $sizesarray['Y'] = $y; //Position before painting image
6997 $sizesarray['OUTPUT'] = $outstring;
6999 $sizesarray['IMAGE_ID'] = $info['i'];
7000 $sizesarray['itype'] = $info['type'];
7001 $sizesarray['set-dpi'] = $info['set-dpi'];
7007 //=============================================================
7008 //=============================================================
7009 //=============================================================
7010 //=============================================================
7011 //=============================================================
7014 function _getObjAttr($t) {
7015 $c = explode("\xbb\xa4\xac",$t,2);
7016 $c = explode(",",$c[1],2);
7018 $v = explode("=",$v,2);
7021 return (unserialize($sp['objattr']));
7025 function inlineObject($type,$x,$y,$objattr,$Lmargin,$widthUsed,$maxWidth,$lineHeight,$paint=false,$is_table=false)
7027 if ($is_table) { $k
= $this
->shrin_k
; } else { $k
= 1; }
7029 // NB $x is only used when paint=true
7032 if (isset($objattr['width'])) { $w
= $objattr
['width']/$k
; }
7034 if (isset($objattr['height'])) { $h
= abs($objattr
['height']/$k
); }
7035 $widthLeft = $maxWidth - $widthUsed;
7036 $maxHeight = $this->h
- ($this->tMargin +
$this->bMargin +
10) ;
7037 if ($this->fullImageHeight
) { $maxHeight
= $this
->fullImageHeight
; }
7039 if (isset($objattr['border_left'])) {
7040 $extraWidth = ($objattr['border_left']['w'] +
$objattr['border_right']['w'] +
$objattr['margin_left']+
$objattr['margin_right'])/$k;
7041 $extraHeight = ($objattr['border_top']['w'] +
$objattr['border_bottom']['w'] +
$objattr['margin_top']+
$objattr['margin_bottom'])/$k;
7043 if ($type == 'image' || $type == 'barcode' || $type == 'textcircle') {
7044 $extraWidth +
= ($objattr['padding_left'] +
$objattr['padding_right'])/$k;
7045 $extraHeight +
= ($objattr['padding_top'] +
$objattr['padding_bottom'])/$k;
7049 if (!isset($objattr['vertical-align'])) { $objattr
['vertical-align'] = 'M'; }
7051 if ($type == 'image' || (isset($objattr['subtype']) && $objattr['subtype'] == 'IMAGE')) {
7052 if (isset($objattr['itype']) && ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg')) {
7053 $file = $objattr['file'];
7054 $info=$this->formobjects
[$file];
7056 else if (isset($objattr['file'])) {
7057 $file = $objattr['file'];
7058 $info=$this->images
[$file];
7061 if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
7066 // TEST whether need to skipline
7068 if ($type == 'hr') { // always force new line
7069 if (($y +
$h +
$lineHeight > $this->PageBreakTrigger
) && !$this->InFooter
&& !$is_table) { return array(-2, $w
,$h
); } // New page + new line
7070 else {
return array(1, $w
,$h
); } // new line
7073 if ($widthUsed > 0 && $w > $widthLeft && (!$is_table || $type != 'image')) { // New line needed
7074 if (($y +
$h +
$lineHeight > $this->PageBreakTrigger
) && !$this->InFooter
) { return array(-2,$w
,$h
); } // New page + new line
7075 return array(1,$w ,$h ); // new line
7077 else if ($widthUsed > 0 && $w > $widthLeft && $is_table) { // New line needed in TABLE
7078 return array(1,$w ,$h ); // new line
7080 // Will fit on line but NEW PAGE REQUIRED
7081 else if (($y +
$h > $this->PageBreakTrigger
) && !$this->InFooter
&& !$is_table) { return array(-1,$w
,$h
); }
7082 else {
return array(0,$w
,$h
); }
7086 if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
7089 $objattr['BORDER-WIDTH'] = 0;
7090 $objattr['BORDER-HEIGHT'] = 0;
7091 $objattr['BORDER-X'] = $x;
7092 $objattr['BORDER-Y'] = $y;
7093 $objattr['INNER-WIDTH'] = 0;
7094 $objattr['INNER-HEIGHT'] = 0;
7095 $objattr['INNER-X'] = $x;
7096 $objattr['INNER-Y'] = $y;
7099 if ($type == 'image') {
7100 // Automatically resize to width remaining
7101 if ($w > $widthLeft && !$is_table) {
7103 $h=abs($w*$info['h']/$info['w']);
7105 $img_w = $w - $extraWidth ;
7106 $img_h = $h - $extraHeight ;
7108 $objattr['BORDER-WIDTH'] = $img_w +
$objattr['padding_left']/$k +
$objattr['padding_right']/$k +
(($objattr['border_left']['w']/$k +
$objattr['border_right']['w']/$k)/2) ;
7109 $objattr['BORDER-HEIGHT'] = $img_h +
$objattr['padding_top']/$k +
$objattr['padding_bottom']/$k +
(($objattr['border_top']['w']/$k +
$objattr['border_bottom']['w']/$k)/2) ;
7110 $objattr['BORDER-X'] = $x +
$objattr['margin_left']/$k +
(($objattr['border_left']['w']/$k)/2) ;
7111 $objattr['BORDER-Y'] = $y +
$objattr['margin_top']/$k +
(($objattr['border_top']['w']/$k)/2) ;
7112 $objattr['INNER-WIDTH'] = $img_w;
7113 $objattr['INNER-HEIGHT'] = $img_h;
7114 $objattr['INNER-X'] = $x +
$objattr['padding_left']/$k +
$objattr['margin_left']/$k +
($objattr['border_left']['w']/$k);
7115 $objattr['INNER-Y'] = $y +
$objattr['padding_top']/$k +
$objattr['margin_top']/$k +
($objattr['border_top']['w']/$k) ;
7116 $objattr['ID'] = $info['i'];
7119 if ($type == 'input' && $objattr['subtype'] == 'IMAGE') {
7120 $img_w = $w - $extraWidth ;
7121 $img_h = $h - $extraHeight ;
7122 $objattr['BORDER-WIDTH'] = $img_w +
(($objattr['border_left']['w']/$k +
$objattr['border_right']['w']/$k)/2) ;
7123 $objattr['BORDER-HEIGHT'] = $img_h +
(($objattr['border_top']['w']/$k +
$objattr['border_bottom']['w']/$k)/2) ;
7124 $objattr['BORDER-X'] = $x +
$objattr['margin_left']/$k +
(($objattr['border_left']['w']/$k)/2) ;
7125 $objattr['BORDER-Y'] = $y +
$objattr['margin_top']/$k +
(($objattr['border_top']['w']/$k)/2) ;
7126 $objattr['INNER-WIDTH'] = $img_w;
7127 $objattr['INNER-HEIGHT'] = $img_h;
7128 $objattr['INNER-X'] = $x +
$objattr['margin_left']/$k +
($objattr['border_left']['w']/$k);
7129 $objattr['INNER-Y'] = $y +
$objattr['margin_top']/$k +
($objattr['border_top']['w']/$k) ;
7130 $objattr['ID'] = $info['i'];
7133 if ($type == 'barcode' || $type == 'textcircle') {
7134 $b_w = $w - $extraWidth ;
7135 $b_h = $h - $extraHeight ;
7136 $objattr['BORDER-WIDTH'] = $b_w +
$objattr['padding_left']/$k +
$objattr['padding_right']/$k +
(($objattr['border_left']['w']/$k +
$objattr['border_right']['w']/$k)/2) ;
7137 $objattr['BORDER-HEIGHT'] = $b_h +
$objattr['padding_top']/$k +
$objattr['padding_bottom']/$k +
(($objattr['border_top']['w']/$k +
$objattr['border_bottom']['w']/$k)/2) ;
7138 $objattr['BORDER-X'] = $x +
$objattr['margin_left']/$k +
(($objattr['border_left']['w']/$k)/2) ;
7139 $objattr['BORDER-Y'] = $y +
$objattr['margin_top']/$k +
(($objattr['border_top']['w']/$k)/2) ;
7140 $objattr['INNER-X'] = $x +
$objattr['padding_left']/$k +
$objattr['margin_left']/$k +
($objattr['border_left']['w']/$k);
7141 $objattr['INNER-Y'] = $y +
$objattr['padding_top']/$k +
$objattr['margin_top']/$k +
($objattr['border_top']['w']/$k) ;
7142 $objattr['INNER-WIDTH'] = $b_w;
7143 $objattr['INNER-HEIGHT'] = $b_h;
7147 if ($type == 'textarea') {
7148 // Automatically resize to width remaining
7149 if ($w > $widthLeft && !$is_table) {
7152 if (($y +
$h > $this->PageBreakTrigger
) && !$this->InFooter
) {
7153 $h=$this->h
- $y - $this->bMargin
;
7157 if ($type == 'hr') {
7159 $objattr['INNER-WIDTH'] = $maxWidth * $objattr['W-PERCENT']/100;
7160 $objattr['width'] = $objattr['INNER-WIDTH'];
7164 if ($w>$maxWidth) { $w
= $maxWidth
; }
7165 $objattr['INNER-WIDTH'] = $w;
7172 if (($type == 'select') || ($type == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD'))) {
7173 // Automatically resize to width remaining
7174 if ($w > $widthLeft && !$is_table) {
7179 if ($type == 'textarea' || $type == 'select' || $type == 'input') {
7180 if (isset($objattr['fontsize'])) $objattr['fontsize'] /= $k;
7181 if (isset($objattr['linewidth'])) $objattr['linewidth'] /= $k;
7184 if (!isset($objattr['BORDER-Y'])) { $objattr
['BORDER-Y'] = 0; }
7185 if (!isset($objattr['BORDER-X'])) { $objattr
['BORDER-X'] = 0; }
7186 if (!isset($objattr['INNER-Y'])) { $objattr
['INNER-Y'] = 0; }
7187 if (!isset($objattr['INNER-X'])) { $objattr
['INNER-X'] = 0; }
7189 //Return width-height array
7190 $objattr['OUTER-WIDTH'] = $w;
7191 $objattr['OUTER-HEIGHT'] = $h;
7192 $objattr['OUTER-X'] = $x;
7193 $objattr['OUTER-Y'] = $y;
7197 /*-- END HTML-CSS --*/
7199 //=============================================================
7200 //=============================================================
7201 //=============================================================
7202 //=============================================================
7203 //=============================================================
7205 function SetLineJoin($mode=0)
7207 $s=sprintf('%d j',$mode);
7208 if($this->page
>0 && ((isset($this->pageoutput
[$this->page
]['LineJoin']) && $this->pageoutput
[$this->page
]['LineJoin'] != $s) || !isset($this->pageoutput
[$this->page
]['LineJoin']) || $this->keep_block_together
)) { $this
->_out($s
); }
7209 $this->pageoutput
[$this->page
]['LineJoin'] = $s;
7212 function SetLineCap($mode=2) {
7213 $s=sprintf('%d J',$mode);
7214 if($this->page
>0 && ((isset($this->pageoutput
[$this->page
]['LineCap']) && $this->pageoutput
[$this->page
]['LineCap'] != $s) || !isset($this->pageoutput
[$this->page
]['LineCap']) || $this->keep_block_together
)) { $this
->_out($s
); }
7215 $this->pageoutput
[$this->page
]['LineCap'] = $s;
7219 function SetDash($black=false,$white=false)
7221 if($black and $white) $s=sprintf('[%.3F %.3F] 0 d',$black*_MPDFK
,$white*_MPDFK
);
7223 if($this->page
>0 && ((isset($this->pageoutput
[$this->page
]['Dash']) && $this->pageoutput
[$this->page
]['Dash'] != $s) || !isset($this->pageoutput
[$this->page
]['Dash']) || $this->keep_block_together
)) { $this
->_out($s
); }
7224 $this->pageoutput
[$this->page
]['Dash'] = $s;
7228 function SetDisplayPreferences($preferences) {
7229 // String containing any or none of /HideMenubar/HideToolbar/HideWindowUI/DisplayDocTitle/CenterWindow/FitWindow
7230 $this->DisplayPreferences
.= $preferences;
7234 function Ln($h='',$collapsible=0)
7236 // Added collapsible to allow collapsible top-margin on new page
7237 //Line feed; default value is last cell height
7238 $this->x
= $this->lMargin +
$this->blk
[$this->blklvl
]['outer_left_margin'];
7239 if ($collapsible && ($this->y
==$this->tMargin
) && (!$this->ColActive
)) { $h
= 0; }
7240 if(is_string($h)) $this->y+
=$this->lasth
;
7245 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
7246 function DivLn($h,$level=-3,$move_y=true,$collapsible=false,$state=0) {
7247 // this->x is returned as it was
7248 // adds lines (y) where DIV bgcolors are filled in
7249 // allows .00001 as nominal height used for bookmarks/annotations etc.
7250 if ($collapsible && (sprintf("%0.4f", $this->y
)==sprintf("%0.4f", $this->tMargin
)) && (!$this->ColActive
)) { return; }
7251 if ($collapsible && (sprintf("%0.4f", $this->y
)==sprintf("%0.4f", $this->y0
)) && ($this->ColActive
) && $this->CurrCol
== 0) { return; } // *COLUMNS*
7253 // Still use this method if columns or page-break-inside: avoid, as it allows repositioning later
7254 // otherwise, now uses PaintDivBB()
7255 if (!$this->ColActive
&& !$this->keep_block_together
&& !$this->kwt
) {
7256 if ($move_y && !$this->ColActive
) { $this
->y +
= $h
; }
7260 if ($level == -3) { $level
= $this
->blklvl
; }
7261 $firstblockfill = $this->GetFirstBlockFill();
7262 if ($firstblockfill && $this->blklvl
> 0 && $this->blklvl
>= $firstblockfill) {
7265 $last_fc = $this->FillColor
;
7267 $bak_h = $this->divheight
;
7268 $this->divheight
= 0; // Temporarily turn off divheight - as Cell() uses it to check for PageBreak
7269 for ($blvl=$firstblockfill;$blvl<=$level;$blvl++
) {
7270 $this->SetBlockFill($blvl);
7271 $this->x
= $this->lMargin +
$this->blk
[$blvl]['outer_left_margin'];
7272 if ($last_x != $this->lMargin +
$this->blk
[$blvl]['outer_left_margin'] || $last_w != $this->blk
[$blvl]['width'] || $last_fc != $this->FillColor
|| $this->blk
[$blvl]['border_top']['s'] || $this->blk
[$blvl]['border_bottom']['s'] || $this->blk
[$blvl]['border_left']['s'] || $this->blk
[$blvl]['border_right']['s']) { // mPDF 5.6.55
7274 $this->Cell( ($this->blk
[$blvl]['width']), $h, '', '', 0, '', 1);
7275 if (!$this->keep_block_together
&& !$this->writingHTMLheader
&& !$this->writingHTMLfooter
) {
7277 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
7278 if ($blvl == $this->blklvl
) { $this
->PaintDivLnBorder($state
,$blvl
,$h
); }
7279 else { $this
->PaintDivLnBorder(0,$blvl
,$h
); }
7282 $last_x = $this->lMargin +
$this->blk
[$blvl]['outer_left_margin'];
7283 $last_w = $this->blk
[$blvl]['width'];
7284 $last_fc = $this->FillColor
;
7286 // Reset current block fill
7287 if (isset($this->blk
[$this->blklvl
]['bgcolorarray'])) {
7288 $bcor = $this->blk
[$this->blklvl
]['bgcolorarray'];
7289 $this->SetFColor($bcor);
7292 $this->divheight
= $bak_h;
7294 if ($move_y) { $this
->y +
= $h
; }
7296 /*-- END HTML-CSS --*/
7302 if($x >= 0) $this->x
=$x;
7303 else $this->x
= $this->w +
$x;
7308 //Set y position and reset x
7309 $this->x
=$this->lMargin
;
7313 $this->y
=$this->h+
$y;
7316 function SetXY($x,$y)
7318 //Set x and y positions
7324 function Output($name='',$dest='')
7326 //Output PDF to some destination
7327 if ($this->showStats
) {
7328 echo '<div>Generated in '.sprintf('%.2F',(microtime(true) - $this->time0
)).' seconds</div>';
7330 //Finish document if necessary
7331 if ($this->progressBar
) { $this
->UpdateProgressBar(1,'100','Finished'); } // *PROGRESS-BAR*
7332 if($this->state
< 3) $this->Close();
7333 if ($this->progressBar
) { $this
->UpdateProgressBar(2,'100','Finished'); } // *PROGRESS-BAR*
7334 // fn. error_get_last is only in PHP>=5.2
7335 if ($this->debug
&& function_exists('error_get_last') && error_get_last()) {
7336 $e = error_get_last();
7337 if (($e['type'] < 2048 && $e['type'] != 8) || (intval($e['type']) & intval(ini_get("error_reporting")))) {
7338 echo "<p>Error message detected - PDF file generation aborted.</p>";
7339 echo $e['message'].'<br />';
7340 echo 'File: '.$e['file'].'<br />';
7341 echo 'Line: '.$e['line'].'<br />';
7347 if (($this->PDFA
|| $this->PDFX
) && $this->encrypted
) { $this
->Error("PDFA1-b or PDFX/1-a does not permit encryption of documents."); }
7348 if (count($this->PDFAXwarnings
) && (($this->PDFA
&& !$this->PDFAauto
) || ($this->PDFX
&& !$this->PDFXauto
))) {
7350 echo '<div>WARNING - This file could not be generated as it stands as a PDFA1-b compliant file.</div>';
7351 echo '<div>These issues can be automatically fixed by mPDF using <i>$mpdf->PDFAauto=true;</i></div>';
7352 echo '<div>Action that mPDF will take to automatically force PDFA1-b compliance are shown in brackets.</div>';
7355 echo '<div>WARNING - This file could not be generated as it stands as a PDFX/1-a compliant file.</div>';
7356 echo '<div>These issues can be automatically fixed by mPDF using <i>$mpdf->PDFXauto=true;</i></div>';
7357 echo '<div>Action that mPDF will take to automatically force PDFX/1-a compliance are shown in brackets.</div>';
7359 echo '<div>Warning(s) generated:</div><ul>';
7360 $this->PDFAXwarnings
= array_unique($this->PDFAXwarnings
);
7361 foreach($this->PDFAXwarnings
AS $w) {
7362 echo '<li>'.$w.'</li>';
7368 if ($this->showStats
) {
7369 echo '<div>Compiled in '.sprintf('%.2F',(microtime(true) - $this->time0
)).' seconds (total)</div>';
7370 echo '<div>Peak Memory usage '.number_format((memory_get_peak_usage(true)/(1024*1024)),2).' MB</div>';
7371 echo '<div>PDF file size '.number_format((strlen($this->buffer
)/1024)).' kB</div>';
7372 echo '<div>Number of fonts '.count($this->fonts
).'</div>';
7377 if(is_bool($dest)) $dest=$dest ? 'D' : 'F';
7378 $dest=strtoupper($dest);
7387 /*-- PROGRESS-BAR --*/
7388 if ($this->progressBar
&& ($dest=='D' || $dest=='I')) {
7389 if($name=='') { $name
='mpdf.pdf'; }
7390 $tempfile = '_tempPDF'.RAND(1,10000);
7391 //Save to local file
7392 $f=fopen(_MPDF_TEMP_PATH
.$tempfile.'.pdf','wb');
7393 if(!$f) $this->Error('Unable to create temporary output file: '.$tempfile.'.pdf');
7394 fwrite($f,$this->buffer
,strlen($this->buffer
));
7396 $this->UpdateProgressBar(3,'','Finished');
7398 echo '<script type="text/javascript">
7400 var form = document.createElement("form");
7401 form.setAttribute("method", "post");
7402 form.setAttribute("action", "'._MPDF_URI
.'includes/out.php");
7404 var hiddenField = document.createElement("input");
7405 hiddenField.setAttribute("type", "hidden");
7406 hiddenField.setAttribute("name", "filename");
7407 hiddenField.setAttribute("value", "'.$tempfile.'");
7408 form.appendChild(hiddenField);
7410 var hiddenField = document.createElement("input");
7411 hiddenField.setAttribute("type", "hidden");
7412 hiddenField.setAttribute("name", "dest");
7413 hiddenField.setAttribute("value", "'.$dest.'");
7414 form.appendChild(hiddenField);
7416 var hiddenField = document.createElement("input");
7417 hiddenField.setAttribute("type", "hidden");
7418 hiddenField.setAttribute("name", "opname");
7419 hiddenField.setAttribute("value", "'.$name.'");
7420 form.appendChild(hiddenField);
7422 var hiddenField = document.createElement("input");
7423 hiddenField.setAttribute("type", "hidden");
7424 hiddenField.setAttribute("name", "path");
7425 hiddenField.setAttribute("value", "'.urlencode(_MPDF_TEMP_PATH
).'");
7426 form.appendChild(hiddenField);
7428 document.body.appendChild(form);
7438 if ($this->progressBar
) { $this
->UpdateProgressBar(3,'','Finished'); }
7439 /*-- END PROGRESS-BAR --*/
7443 if ($this->debug
&& !$this->allow_output_buffering
&& ob_get_contents()) { echo "<p>Output has already been sent from the script - PDF file generation aborted.</p>"; exit; }
7444 //Send to standard output
7445 if(PHP_SAPI
!='cli') {
7446 //We send to a browser
7447 header('Content-Type: application/pdf');
7449 $this->Error('Some data has already been output to browser, can\'t send PDF file');
7450 if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
7451 // don't use length if server using compression
7452 header('Content-Length: '.strlen($this->buffer
));
7454 header('Content-disposition: inline; filename="'.$name.'"');
7455 header('Cache-Control: public, must-revalidate, max-age=0');
7456 header('Pragma: public');
7457 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
7458 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
7464 header('Content-Description: File Transfer');
7466 $this->Error('Some data has already been output to browser, can\'t send PDF file');
7467 header('Content-Transfer-Encoding: binary');
7468 header('Cache-Control: public, must-revalidate, max-age=0');
7469 header('Pragma: public');
7470 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
7471 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
7472 header('Content-Type: application/force-download');
7473 header('Content-Type: application/octet-stream', false);
7474 header('Content-Type: application/download', false);
7475 header('Content-Type: application/pdf', false);
7476 if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
7477 // don't use length if server using compression
7478 header('Content-Length: '.strlen($this->buffer
));
7480 header('Content-disposition: attachment; filename="'.$name.'"');
7484 //Save to local file
7485 $f=fopen($name,'wb');
7486 if(!$f) $this->Error('Unable to create output file: '.$name);
7487 fwrite($f,$this->buffer
,strlen($this->buffer
));
7491 //Return as a string
7492 return $this->buffer
;
7494 $this->Error('Incorrect output destination: '.$dest);
7498 //======================================================================================================
7499 // DELETE OLD TMP FILES - Housekeeping
7500 // Delete any files in tmp/ directory that are >1 hrs old
7502 if ($handle = opendir(preg_replace('/\/$/','',_MPDF_TEMP_PATH
))) {
7503 while (false !== ($file = readdir($handle))) {
7504 if (!is_dir($file) && ((filemtime(_MPDF_TEMP_PATH
.$file)+
$interval) < time()) && ($file != "..") && ($file != ".")) { // mPDF 5.4.19
7505 unlink(_MPDF_TEMP_PATH
.$file);
7510 //==============================================================================================================
7516 // *****************************************************************************
7518 // Protected methods *
7520 // *****************************************************************************
7521 function _dochecks()
7523 //Check for locale-related bug
7525 $this->Error('Don\'t alter the locale before including mPDF');
7526 //Check for decimal separator
7527 if(sprintf('%.1f',1.0)!='1.0')
7528 setlocale(LC_NUMERIC
,'C');
7530 $mqr=ini_get("magic_quotes_runtime");
7531 if ($mqr) { $this
->Error('mPDF requires magic_quotes_runtime to be turned off e.g. by using ini_set("magic_quotes_runtime", 0);'); }
7534 function _begindoc()
7538 $this->_out('%PDF-'.$this->pdf_version
);
7539 $this->_out('%'.chr(226).chr(227).chr(207).chr(211)); // 4 chars > 128 to show binary file
7543 /*-- HTMLHEADERS-FOOTERS --*/
7544 function _puthtmlheaders() {
7547 for($n=1;$n<=$nb;$n++
) {
7548 if ($this->mirrorMargins
&& $n%
2==0) { $OE
= 'E'; } // EVEN
7551 if (isset($this->saveHTMLHeader
[$n][$OE])) {
7552 $html = $this->saveHTMLHeader
[$n][$OE]['html'];
7553 $this->lMargin
= $this->saveHTMLHeader
[$n][$OE]['ml'];
7554 $this->rMargin
= $this->saveHTMLHeader
[$n][$OE]['mr'];
7555 $this->tMargin
= $this->saveHTMLHeader
[$n][$OE]['mh'];
7556 $this->bMargin
= $this->saveHTMLHeader
[$n][$OE]['mf'];
7557 $this->margin_header
= $this->saveHTMLHeader
[$n][$OE]['mh'];
7558 $this->margin_footer
= $this->saveHTMLHeader
[$n][$OE]['mf'];
7559 $this->w
= $this->saveHTMLHeader
[$n][$OE]['pw'];
7560 $this->h
= $this->saveHTMLHeader
[$n][$OE]['ph'];
7561 $rotate = (isset($this->saveHTMLHeader
[$n][$OE]['rotate']) ? $this->saveHTMLHeader
[$n][$OE]['rotate'] : null);
7563 $this->pageoutput
[$n] = array();
7564 $this->pgwidth
= $this->w
- $this->lMargin
- $this->rMargin
;
7565 $this->x
= $this->lMargin
;
7566 $this->y
= $this->margin_header
;
7568 $pn = $this->docPageNum($n);
7570 $pnstr = $this->pagenumPrefix
.$pn.$this->pagenumSuffix
;
7571 else { $pnstr
= ''; }
7572 $html = str_replace('{PAGENO}',$pnstr,$html);
7573 $pnt = $this->docPageNumTotal($n);
7575 $pntstr = $this->nbpgPrefix
.$pnt.$this->nbpgSuffix
;
7576 else { $pntstr
= ''; }
7577 $html = str_replace($this->aliasNbPgGp
,$pntstr,$html ); // {nbpg}
7578 $html = str_replace($this->aliasNbPg
,$nb,$html ); // {nb}
7579 $html = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$html );
7581 $this->HTMLheaderPageLinks
= array();
7582 $this->HTMLheaderPageAnnots
= array();
7583 $this->HTMLheaderPageForms
= array();
7584 $this->pageBackgrounds
= array();
7586 $this->writingHTMLheader
= true;
7587 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
7588 $this->writingHTMLheader
= false;
7590 $this->pageoutput
[$n] = array();
7592 $s = $this->PrintPageBackgrounds();
7593 $this->headerbuffer
= $s . $this->headerbuffer
;
7596 $os .= sprintf('q 0 -1 1 0 0 %.3F cm ',($this->w
*_MPDFK
));
7598 $os .= $this->headerbuffer
;
7603 // Writes over the page background but behind any other output on page
7604 $os = preg_replace('/\\\\/','\\\\\\\\',$os);
7605 $this->pages
[$n] = preg_replace('/(___HEADER___MARKER'.date('jY').')/', "\n".$os."\n".'\\1', $this->pages
[$n]);
7607 $lks = $this->HTMLheaderPageLinks
;
7608 foreach($lks AS $lk) {
7613 $lk[3] = $lw; // swap width and height
7614 $ax = $lk[0]/_MPDFK
;
7615 $ay = $lk[1]/_MPDFK
;
7616 $bx = $ay-($lh/_MPDFK
);
7618 $lk[0] = $bx*_MPDFK
;
7619 $lk[1] = ($this->h
-$by)*_MPDFK
- $lw;
7621 $this->PageLinks
[$n][]=$lk;
7624 foreach($this->HTMLheaderPageForms
AS $f) {
7625 $this->form
->forms
[$f['n']] = $f;
7631 if (isset($this->saveHTMLFooter
[$n][$OE])) {
7632 $html = $this->saveHTMLFooter
[$this->page
][$OE]['html'];
7633 $this->lMargin
= $this->saveHTMLFooter
[$n][$OE]['ml'];
7634 $this->rMargin
= $this->saveHTMLFooter
[$n][$OE]['mr'];
7635 $this->tMargin
= $this->saveHTMLFooter
[$n][$OE]['mh'];
7636 $this->bMargin
= $this->saveHTMLFooter
[$n][$OE]['mf'];
7637 $this->margin_header
= $this->saveHTMLFooter
[$n][$OE]['mh'];
7638 $this->margin_footer
= $this->saveHTMLFooter
[$n][$OE]['mf'];
7639 $this->w
= $this->saveHTMLFooter
[$n][$OE]['pw'];
7640 $this->h
= $this->saveHTMLFooter
[$n][$OE]['ph'];
7641 $rotate = (isset($this->saveHTMLFooter
[$n][$OE]['rotate']) ? $this->saveHTMLFooter
[$n][$OE]['rotate'] : null);
7643 $this->pageoutput
[$n] = array();
7644 $this->pgwidth
= $this->w
- $this->lMargin
- $this->rMargin
;
7645 $this->x
= $this->lMargin
;
7646 $top_y = $this->y
= $this->h
- $this->margin_footer
;
7648 // if bottom-margin==0, corrects to avoid division by zero
7649 if ($this->y
== $this->h
) { $top_y
= $this
->y
= ($this
->h
- 0.1); }
7651 $pn = $this->docPageNum($n);
7653 $pnstr = $this->pagenumPrefix
.$pn.$this->pagenumSuffix
;
7654 else { $pnstr
= ''; }
7655 $html = str_replace('{PAGENO}',$pnstr,$html);
7656 $pnt = $this->docPageNumTotal($n);
7658 $pntstr = $this->nbpgPrefix
.$pnt.$this->nbpgSuffix
;
7659 else { $pntstr
= ''; }
7660 $html = str_replace($this->aliasNbPgGp
,$pntstr,$html ); // {nbpg}
7661 $html = str_replace($this->aliasNbPg
,$nb,$html ); // {nb}
7662 $html = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$html );
7665 $this->HTMLheaderPageLinks
= array();
7666 $this->HTMLheaderPageAnnots
= array();
7667 $this->HTMLheaderPageForms
= array();
7668 $this->pageBackgrounds
= array();
7670 $this->writingHTMLfooter
= true;
7671 $this->InFooter
= true;
7672 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
7673 $this->writingHTMLfooter
= false;
7674 $this->InFooter
= false;
7676 $this->pageoutput
[$n] = array();
7678 $fheight = $this->y
- $top_y;
7681 $s = $this->PrintPageBackgrounds(-$adj);
7682 $this->headerbuffer
= $s . $this->headerbuffer
;
7685 $os .= $this->StartTransform(true)."\n";
7687 $os .= sprintf('q 0 -1 1 0 0 %.3F cm ',($this->w
*_MPDFK
));
7689 $os .= $this->transformTranslate(0, $adj, true)."\n";
7690 $os .= $this->headerbuffer
;
7694 $os .= $this->StopTransform(true)."\n";
7695 // Writes over the page background but behind any other output on page
7696 $os = preg_replace('/\\\\/','\\\\\\\\',$os);
7697 $this->pages
[$n] = preg_replace('/(___HEADER___MARKER'.date('jY').')/', "\n".$os."\n".'\\1', $this->pages
[$n]);
7699 $lks = $this->HTMLheaderPageLinks
;
7700 foreach($lks AS $lk) {
7701 $lk[1] -= $adj*_MPDFK
;
7706 $lk[3] = $lw; // swap width and height
7708 $ax = $lk[0]/_MPDFK
;
7709 $ay = $lk[1]/_MPDFK
;
7710 $bx = $ay-($lh/_MPDFK
);
7712 $lk[0] = $bx*_MPDFK
;
7713 $lk[1] = ($this->h
-$by)*_MPDFK
- $lw;
7715 $this->PageLinks
[$n][]=$lk;
7718 foreach($this->HTMLheaderPageForms
AS $f) {
7720 $this->form
->forms
[$f['n']] = $f;
7728 /*-- END HTMLHEADERS-FOOTERS --*/
7731 function _putpages()
7734 $filter=($this->compress
) ? '/Filter /FlateDecode ' : '';
7736 if($this->DefOrientation
=='P') {
7737 $defwPt=$this->fwPt
;
7738 $defhPt=$this->fhPt
;
7741 $defwPt=$this->fhPt
;
7742 $defhPt=$this->fwPt
;
7748 for($n=1;$n<=$nb;$n++
) {
7749 if (isset($this->PageLinks
[$n])) { $totaladdnum +
= count($this
->PageLinks
[$n
]); }
7750 /*-- ANNOTATIONS --*/
7751 if (isset($this->PageAnnots
[$n])) {
7752 foreach ($this->PageAnnots
[$n] as $k => $pl) {
7753 if (!empty($pl['opt']['popup']) || !empty($pl['opt']['file'])) { $totaladdnum +
= 2 ; }
7754 else { $totaladdnum++
; }
7757 /*-- END ANNOTATIONS --*/
7760 if ( count($this->form
->forms
) > 0 ) {
7761 $this->form
->countPageForms($n, $totaladdnum);
7766 // Make a note in the radio button group of the obj_id it will have
7768 if (count($this->form
->form_radio_groups
)) {
7769 foreach($this->form
->form_radio_groups
AS $name=>$frg) {
7770 $this->form
->form_radio_groups
[$name]['obj_id'] = $annotid +
$totaladdnum +
$ctr;
7776 // Select unused fonts (usually default font)
7778 foreach($this->fonts
as $fk=>$font) {
7779 if (!$font['used'] && ($font['type']=='TTF')) {
7785 for($n=1;$n<=$nb;$n++
)
7787 $thispage = $this->pages
[$n];
7788 // unset($this->pages[$n]); // mPDF 5.6.47
7789 if(isset($this->OrientationChanges
[$n])) {
7790 $hPt=$this->pageDim
[$n]['w']*_MPDFK
;
7791 $wPt=$this->pageDim
[$n]['h']*_MPDFK
;
7792 $owidthPt_LR = $this->pageDim
[$n]['outer_width_TB']*_MPDFK
;
7793 $owidthPt_TB = $this->pageDim
[$n]['outer_width_LR']*_MPDFK
;
7796 $wPt=$this->pageDim
[$n]['w']*_MPDFK
;
7797 $hPt=$this->pageDim
[$n]['h']*_MPDFK
;
7798 $owidthPt_LR = $this->pageDim
[$n]['outer_width_LR']*_MPDFK
;
7799 $owidthPt_TB = $this->pageDim
[$n]['outer_width_TB']*_MPDFK
;
7801 // Remove references to unused fonts (usually default font)
7802 foreach($unused as $fk) {
7803 if ($this->fonts
[$fk]['sip'] || $this->fonts
[$fk]['smp']) {
7804 foreach($this->fonts
[$fk]['subsetfontids'] AS $k => $fid) {
7805 $thispage = preg_replace('/\s\/F'.$fid.' \d[\d.]* Tf\s/is',' ',$thispage);
7809 $thispage = preg_replace('/\s\/F'.$this->fonts
[$fk]['i'].' \d[\d.]* Tf\s/is',' ',$thispage);
7812 //Replace number of pages
7813 if(!empty($this->aliasNbPg
)) {
7814 if (!$this->onlyCoreFonts
) { $s1
= $this
->UTF8ToUTF16BE($this
->aliasNbPg
, false); }
7815 $s2 = $this->aliasNbPg
;
7816 if (!$this->onlyCoreFonts
) { $r1
= $this
->UTF8ToUTF16BE($nb
, false); }
7818 if (preg_match_all('/{mpdfheadernbpg (C|R) ff=(\S*) fs=(\S*) fz=(.*?)}/',$thispage,$m)) {
7819 for($hi=0;$hi<count($m[0]);$hi++
) {
7824 $this->SetFont($hff,$hfst,$hfsz, false);
7825 $x1 = $this->GetStringWidth($this->aliasNbPg
);
7826 $x2 = $this->GetStringWidth($nb);
7828 if ($pos=='C') { $xadj
/= 2; }
7829 $rep = sprintf(' q 1 0 0 1 %.3F 0 cm ', $xadj*_MPDFK
);
7830 $thispage = str_replace($m[0][$hi], $rep, $thispage);
7833 if (!$this->onlyCoreFonts
) { $thispage
=str_replace($s1
,$r1
,$thispage
); }
7834 $thispage=str_replace($s2,$r2,$thispage);
7836 // And now for any SMP/SIP fonts subset using <HH> format
7839 for($i=0;$i<strlen($nstr);$i++) {
7840 $r .= sprintf("%
02s
", strtoupper(dechex(intval($nstr[$i])+48)));
7842 $thispage=str_replace($this->aliasNbPgHex,$r,$thispage);
7845 //Replace number of pages in group
7846 if(!empty($this->aliasNbPgGp)) {
7847 if (!$this->onlyCoreFonts) { $s1 = $this->UTF8ToUTF16BE($this->aliasNbPgGp, false); }
7848 $s2 = $this->aliasNbPgGp;
7849 $nbt = $this->docPageNumTotal($n);
7850 if (!$this->onlyCoreFonts) { $r1 = $this->UTF8ToUTF16BE($nbt, false); }
7852 if (preg_match_all('/{mpdfheadernbpggp (C|R) ff=(\S*) fs=(\S*) fz=(.*?)}/',$thispage,$m)) {
7853 for($hi=0;$hi<count($m[0]);$hi++) {
7858 $this->SetFont($hff,$hfst,$hfsz, false);
7859 $x1 = $this->GetStringWidth($this->aliasNbPgGp);
7860 $x2 = $this->GetStringWidth($nbt);
7862 if ($pos=='C') { $xadj /= 2; }
7863 $rep = sprintf(' q 1 0 0 1 %.3F 0 cm ', $xadj*_MPDFK);
7864 $thispage = str_replace($m[0][$hi], $rep, $thispage);
7867 if (!$this->onlyCoreFonts) { $thispage=str_replace($s1,$r1,$thispage); }
7868 $thispage=str_replace($s2,$r2,$thispage);
7870 // And now for any SMP/SIP fonts subset using <HH> format
7873 for($i=0;$i<strlen($nstr);$i++
) {
7874 $r .= sprintf("%02s", strtoupper(dechex(intval($nstr[$i])+
48)));
7876 $thispage=str_replace($this->aliasNbPgGpHex
,$r,$thispage);
7879 $thispage = preg_replace('/(\s*___BACKGROUND___PATTERNS'.date('jY').'\s*)/', " ", $thispage);
7880 $thispage = preg_replace('/(\s*___HEADER___MARKER'.date('jY').'\s*)/', " ", $thispage);
7881 $thispage = preg_replace('/(\s*___PAGE___START'.date('jY').'\s*)/', " ", $thispage);
7882 $thispage = preg_replace('/(\s*___TABLE___BACKGROUNDS'.date('jY').'\s*)/', " ", $thispage);
7886 $this->_out('<</Type /Page');
7887 $this->_out('/Parent 1 0 R');
7888 if(isset($this->OrientationChanges
[$n])) {
7889 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$hPt,$wPt));
7890 //If BleedBox is defined, it must be larger than the TrimBox, but smaller than the MediaBox
7891 $bleedMargin = $this->pageDim
[$n]['bleedMargin']*_MPDFK
;
7892 if ($bleedMargin && ($owidthPt_TB || $owidthPt_LR)) {
7893 $x0 = $owidthPt_TB-$bleedMargin;
7894 $y0 = $owidthPt_LR-$bleedMargin;
7895 $x1 = $hPt-$owidthPt_TB+
$bleedMargin;
7896 $y1 = $wPt-$owidthPt_LR+
$bleedMargin;
7897 $this->_out(sprintf('/BleedBox [%.3F %.3F %.3F %.3F]', $x0, $y0, $x1, $y1));
7899 $this->_out(sprintf('/TrimBox [%.3F %.3F %.3F %.3F]', $owidthPt_TB, $owidthPt_LR, ($hPt-$owidthPt_TB), ($wPt-$owidthPt_LR)));
7900 if (isset($this->OrientationChanges
[$n]) && $this->displayDefaultOrientation
) {
7901 if ($this->DefOrientation
=='P') { $this
->_out('/Rotate 270'); }
7902 else { $this
->_out('/Rotate 90'); }
7905 //else if($wPt != $defwPt || $hPt != $defhPt) {
7907 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$wPt,$hPt));
7908 $bleedMargin = $this->pageDim
[$n]['bleedMargin']*_MPDFK
;
7909 if ($bleedMargin && ($owidthPt_TB || $owidthPt_LR)) {
7910 $x0 = $owidthPt_LR-$bleedMargin;
7911 $y0 = $owidthPt_TB-$bleedMargin;
7912 $x1 = $wPt-$owidthPt_LR+
$bleedMargin;
7913 $y1 = $hPt-$owidthPt_TB+
$bleedMargin;
7914 $this->_out(sprintf('/BleedBox [%.3F %.3F %.3F %.3F]', $x0, $y0, $x1, $y1));
7916 $this->_out(sprintf('/TrimBox [%.3F %.3F %.3F %.3F]', $owidthPt_LR, $owidthPt_TB, ($wPt-$owidthPt_LR), ($hPt-$owidthPt_TB)));
7918 $this->_out('/Resources 2 0 R');
7920 // Important to keep in RGB colorSpace when using transparency
7921 if (!$this->PDFA
&& !$this->PDFX
) {
7922 if ($this->restrictColorSpace
== 3)
7923 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceCMYK >> ');
7924 else if ($this->restrictColorSpace
== 1)
7925 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceGray >> ');
7927 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceRGB >> ');
7931 if (isset($this->PageLinks
[$n])) { $annotsnum +
= count($this
->PageLinks
[$n
]); }
7932 /*-- ANNOTATIONS --*/
7933 if (isset($this->PageAnnots
[$n])) {
7934 foreach ($this->PageAnnots
[$n] as $k => $pl) {
7935 if (!empty($pl['opt']['popup']) || !empty($pl['opt']['file'])) { $annotsnum +
= 2 ; }
7936 else { $annotsnum++
; }
7937 $this->PageAnnots
[$n][$k]['pageobj'] = $this->n
;
7940 /*-- END ANNOTATIONS --*/
7945 if ( count($this->form
->forms
) > 0 ) {
7946 foreach( $this->form
->forms
as $val ) {
7947 if ( $val['page'] == $n )
7952 if ($annotsnum || $formsnum) {
7954 for($i=0;$i<$annotsnum;$i++
) {
7955 $s .= ($annotid +
$i) . ' 0 R ';
7957 $annotid +
= $annotsnum;
7959 if ( count($this->form
->forms
) > 0 ) {
7960 $this->form
->addFormIds($n, $s, $annotid);
7967 $this->_out('/Contents '.($this->n+
1).' 0 R>>');
7968 $this->_out('endobj');
7972 $p=($this->compress
) ? gzcompress($thispage) : $thispage;
7973 $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
7974 $this->_putstream($p);
7975 $this->_out('endobj');
7977 $this->_putannots($n);
7980 $this->offsets
[1]=strlen($this->buffer
);
7981 $this->_out('1 0 obj');
7982 $this->_out('<</Type /Pages');
7984 for($i=0;$i<$nb;$i++
)
7985 $kids.=(3+
2*$i).' 0 R ';
7986 $this->_out($kids.']');
7987 $this->_out('/Count '.$nb);
7988 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$defwPt,$defhPt));
7990 $this->_out('endobj');
7994 function _putannots($n) {
7995 $filter=($this->compress
) ? '/Filter /FlateDecode ' : '';
7997 for($n=1;$n<=$nb;$n++
)
7999 $annotobjs = array();
8000 if(isset($this->PageLinks
[$n]) || isset($this->PageAnnots
[$n]) || count($this->form
->forms
) > 0 ) {
8001 $wPt=$this->pageDim
[$n]['w']*_MPDFK
;
8002 $hPt=$this->pageDim
[$n]['h']*_MPDFK
;
8005 if(isset($this->PageLinks
[$n])) {
8006 foreach($this->PageLinks
[$n] as $key => $pl) {
8009 $rect=sprintf('%.3F %.3F %.3F %.3F',$pl[0],$pl[1],$pl[0]+
$pl[2],$pl[1]-$pl[3]);
8010 $annot .= '<</Type /Annot /Subtype /Link /Rect ['.$rect.']';
8011 $annot .= ' /Contents '.$this->_UTF16BEtextstring($pl[4]);
8012 $annot .= ' /NM '.$this->_textstring(sprintf('%04u-%04u', $n, $key));
8013 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
8014 $annot .= ' /Border [0 0 0]';
8015 // Use this (instead of /Border) to specify border around link
8016 // $annot .= ' /BS <</W 1'; // Width on points; 0 = no line
8017 // $annot .= ' /S /D'; // style - [S]olid, [D]ashed, [B]eveled, [I]nset, [U]nderline
8018 // $annot .= ' /D [3 2]'; // Dash array - if dashed
8020 // $annot .= ' /C [1 0 0]'; // Color RGB
8022 if ($this->PDFA
|| $this->PDFX
) { $annot
.= ' /F 28'; }
8023 if (strpos($pl[4],'@')===0) {
8024 $p=substr($pl[4],1);
8025 // $h=isset($this->OrientationChanges[$p]) ? $wPt : $hPt;
8026 $htarg=$this->pageDim
[$p]['h']*_MPDFK
;
8027 $annot.=sprintf(' /Dest [%d 0 R /XYZ 0 %.3F null]>>',1+
2*$p,$htarg);
8029 else if(is_string($pl[4])) {
8030 $annot .= ' /A <</S /URI /URI '.$this->_textstring($pl[4]).'>> >>';
8033 $l=$this->links
[$pl[4]];
8034 // may not be set if #link points to non-existent target
8035 if (isset($this->pageDim
[$l[0]]['h'])) { $htarg
=$this
->pageDim
[$l
[0]]['h']*_MPDFK
; }
8036 else { $htarg
=$this
->h
*_MPDFK
; } // doesn't really matter
8037 $annot.=sprintf(' /Dest [%d 0 R /XYZ 0 %.3F null]>>',1+
2*$l[0],$htarg-$l[1]*_MPDFK
);
8039 $this->_out($annot);
8040 $this->_out('endobj');
8045 /*-- ANNOTATIONS --*/
8046 if(isset($this->PageAnnots
[$n])) {
8047 foreach ($this->PageAnnots
[$n] as $key => $pl) {
8048 if ($pl['opt']['file']) { $FileAttachment
=true; }
8049 else { $FileAttachment
=false; }
8052 $pl['opt'] = array_change_key_case($pl['opt'], CASE_LOWER
);
8054 if ($this->annotMargin
<> 0 || $x==0 || $x<0) { // Odd page
8055 $x = ($wPt/_MPDFK
) - $this->annotMargin
;
8059 $b = $hPt - ($pl['y'] * _MPDFK
);
8060 $annot .= '<</Type /Annot ';
8061 if ($FileAttachment) {
8062 $annot .= '/Subtype /FileAttachment';
8063 // Need to set a size for FileAttachment icons
8064 if ($pl['opt']['icon']=='Paperclip') { $w
=8.235; $h
=20; } // 7,17
8065 else if ($pl['opt']['icon']=='Tag') { $w
=20; $h
=16; }
8066 else if ($pl['opt']['icon']=='Graph') { $w
=20; $h
=20; }
8067 else { $w
=14; $h
=20; } // PushPin
8068 $f = $pl['opt']['file'];
8069 $f = preg_replace('/^.*\//', '', $f);
8070 $f = preg_replace('/[^a-zA-Z0-9._]/', '', $f);
8071 $annot .= '/FS <</Type /Filespec /F ('.$f.')';
8072 $annot .= '/EF <</F '.($this->n+
1).' 0 R>>';
8076 $annot .= '/Subtype /Text';
8078 $rect = sprintf('%.3F %.3F %.3F %.3F', $a, $b-$h, $a+
$w, $b);
8079 $annot .= '/Rect ['.$rect.']';
8081 // contents = description of file in free text
8082 $annot .= ' /Contents '.$this->_UTF16BEtextstring($pl['txt']);
8083 $annot .= ' /NM '.$this->_textstring(sprintf('%04u-%04u', $n, (2000 +
$key)));
8084 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
8085 $annot .= ' /CreationDate '.$this->_textstring('D:'.date('YmdHis'));
8086 $annot .= ' /Border [0 0 0]';
8087 if ($this->PDFA
|| $this->PDFX
) {
8091 else if ($pl['opt']['ca']>0) { $annot
.= ' /CA '.$pl
['opt']['ca']; }
8093 $annotcolor = ' /C [';
8094 if (isset($pl['opt']['c']) AND $pl['opt']['c']) {
8095 $col = $pl['opt']['c'];
8096 if ($col{0}==3 || $col{0}==5) { $annotcolor
.= sprintf("%.3F %.3F %.3F", ord($col
{1})/255,ord($col{2})/255,ord($col{3})/255); }
8097 else if ($col{0}==1) { $annotcolor
.= sprintf("%.3F", ord($col
{1})/255); }
8098 else if ($col{0}==4 || $col{0}==6) { $annotcolor
.= sprintf("%.3F %.3F %.3F %.3F", ord($col
{1})/100,ord($col{2})/100,ord($col{3})/100,ord($col{4})/100); }
8099 else { $annotcolor
.= '1 1 0'; }
8101 else { $annotcolor
.= '1 1 0'; }
8103 $annot .= $annotcolor;
8105 // Use as Title for fileattachment
8106 if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) {
8107 $annot .= ' /T '.$this->_UTF16BEtextstring($pl['opt']['t']);
8109 if ($FileAttachment) {
8110 $iconsapp = array('Paperclip', 'Graph', 'PushPin', 'Tag');
8112 else { $iconsapp
= array('Comment', 'Help', 'Insert', 'Key', 'NewParagraph', 'Note', 'Paragraph'); }
8113 if (isset($pl['opt']['icon']) AND in_array($pl['opt']['icon'], $iconsapp)) {
8114 $annot .= ' /Name /'.$pl['opt']['icon'];
8116 else if ($FileAttachment) { $annot
.= ' /Name /PushPin'; }
8117 else { $annot
.= ' /Name /Note'; }
8118 if (!$FileAttachment) {
8119 // /Subj is PDF 1.5 spec.
8120 if (isset($pl['opt']['subj']) && !$this->PDFA
&& !$this->PDFX
) {
8121 $annot .= ' /Subj '.$this->_UTF16BEtextstring($pl['opt']['subj']);
8123 if (!empty($pl['opt']['popup'])) {
8124 $annot .= ' /Open true';
8125 $annot .= ' /Popup '.($this->n+
1).' 0 R';
8127 else { $annot
.= ' /Open false'; }
8129 $annot .= ' /P '.$pl['pageobj'].' 0 R';
8131 $this->_out($annot);
8132 $this->_out('endobj');
8134 if ($FileAttachment) {
8135 $file = @file_get_contents($pl['opt']['file']) or die('mPDF Error: Cannot access file attachment - '.$pl['opt']['file']);
8136 $filestream = gzcompress($file);
8138 $this->_out('<</Type /EmbeddedFile');
8139 $this->_out('/Length '.strlen($filestream));
8140 $this->_out('/Filter /FlateDecode');
8142 $this->_putstream($filestream);
8143 $this->_out('endobj');
8145 else if (!empty($pl['opt']['popup'])) {
8148 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][0])) { $x
= $pl
['opt']['popup'][0] * _MPDFK
; }
8149 else { $x
= $pl
['x'] * _MPDFK
; }
8150 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][1])) { $y
= $hPt
- ($pl
['opt']['popup'][1] * _MPDFK
); }
8151 else { $y
= $hPt
- ($pl
['y'] * _MPDFK
); }
8152 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][2])) { $w
= $pl
['opt']['popup'][2] * _MPDFK
; }
8154 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][3])) { $h
= $pl
['opt']['popup'][3] * _MPDFK
; }
8156 $rect = sprintf('%.3F %.3F %.3F %.3F', $x, $y-$h, $x+
$w, $y);
8157 $annot .= '<</Type /Annot /Subtype /Popup /Rect ['.$rect.']';
8158 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
8159 if ($this->PDFA
|| $this->PDFX
) { $annot
.= ' /F 28'; }
8160 $annot .= ' /Parent '.($this->n
-1).' 0 R';
8162 $this->_out($annot);
8163 $this->_out('endobj');
8167 /*-- END ANNOTATIONS --*/
8171 if ( count($this->form
->forms
) > 0 ) {
8172 $this->form
->_putFormItems($n, $hPt);
8178 // Active Forms - Radio Button Group entries
8179 // Output Radio Button Group form entries (radio_on_obj_id already determined)
8180 if (count($this->form
->form_radio_groups
)) {
8181 $this->form
->_putRadioItems($n);
8187 /*-- ANNOTATIONS --*/
8188 function Annotation($text, $x=0, $y=0, $icon='Note', $author='', $subject='', $opacity=0, $colarray=false, $popup='', $file='') {
8189 if (is_array($colarray) && count($colarray)==3) { $colarray
= $this
->ConvertColor('rgb('.$colarray
[0].','.$colarray
[1].','.$colarray
[2].')'); }
8190 if ($colarray === false) { $colarray
= $this
->ConvertColor('yellow'); }
8191 if ($x==0) { $x
= $this
->x
; }
8192 if ($y==0) { $y
= $this
->y
; }
8193 $page = $this->page
;
8194 if ($page < 1) { // Document has not been started - assume it's for first page
8196 if ($x==0) { $x
= $this
->lMargin
; }
8197 if ($y==0) { $y
= $this
->tMargin
; }
8200 if ($this->PDFA
|| $this->PDFX
) {
8201 if (($this->PDFA
&& !$this->PDFAauto
) || ($this->PDFX
&& !$this->PDFXauto
)) { $this
->PDFAXwarnings
[] = "Annotation markers cannot be semi-transparent in PDFA1-b or PDFX/1-a, so they may make underlying text unreadable. (Annotation markers moved to right margin)"; }
8202 $x = ($this->w
) - $this->rMargin
*0.66;
8204 if (!$this->annotMargin
) { $y
-= $this
->FontSize
/ 2; }
8206 if (!$opacity && $this->annotMargin
) { $opacity
= 1; }
8207 else if (!$opacity) { $opacity
= $this
->annotOpacity
; }
8209 $an = array('txt' => $text, 'x' => $x, 'y' => $y, 'opt' => array('Icon'=>$icon, 'T'=>$author, 'Subj'=>$subject, 'C'=>$colarray, 'CA'=>$opacity, 'popup'=>$popup, 'file'=>$file));
8211 if ($this->keep_block_together
) { // Save to array - don't write yet
8212 $this->ktAnnots
[$this->page
][]= $an;
8215 else if ($this->table_rotate
) {
8216 $this->tbrot_Annots
[$this->page
][]= $an;
8219 else if ($this->kwt
) {
8220 $this->kwt_Annots
[$this->page
][]= $an;
8224 if ($this->writingHTMLheader
|| $this->writingHTMLfooter
) {
8225 $this->HTMLheaderPageAnnots
[]= $an;
8228 //Put an Annotation on the page
8229 $this->PageAnnots
[$page][] = $an;
8231 // Save cross-reference to Column buffer
8232 $ref = count($this->PageAnnots
[$this->page
])-1;
8233 $this->columnAnnots
[$this->CurrCol
][INTVAL($this->x
)][INTVAL($this->y
)] = $ref;
8234 /*-- END COLUMNS --*/
8236 /*-- END ANNOTATIONS --*/
8239 function _putfonts() {
8241 foreach($this->FontFiles
as $fontkey=>$info) {
8242 // TrueType embedded
8243 if (isset($info['type']) && $info['type']=='TTF' && !$info['sip'] && !$info['smp']) {
8246 foreach($this->fonts
AS $k=>$f) {
8247 if ($f['fontkey'] == $fontkey && $f['type']=='TTF') {
8250 $nChars = (ord($f['cw'][0]) << 8) +
ord($f['cw'][1]);
8251 $usage = intval(count($f['subset'])*100 / $nChars);
8252 $fsize = $info['length1'];
8253 // Always subset the very large TTF files
8254 if ($fsize > ($this->maxTTFFilesize
*1024)) { $asSubset
= true; }
8255 else if ($usage < $this->percentSubset
) { $asSubset
= true; }
8257 if ($f['unAGlyphs']) $aaSubset = true; // mPDF 5.4.05
8258 if ($this->PDFA
|| $this->PDFX
) $asSubset = false;
8259 $this->fonts
[$k]['asSubset'] = $asSubset;
8263 if ($used && !$asSubset) {
8264 //Font file embedding
8266 $this->FontFiles
[$fontkey]['n']=$this->n
;
8268 $originalsize = $info['length1'];
8269 if ($this->repackageTTF
|| $this->fonts
[$fontkey]['TTCfontID']>0) {
8270 // First see if there is a cached compressed file
8271 if (file_exists(_MPDF_TTFONTDATAPATH
.$fontkey.'.ps.z')) {
8272 $f=fopen(_MPDF_TTFONTDATAPATH
.$fontkey.'.ps.z','rb');
8273 if(!$f) { $this
->Error('Font file .ps.z not found'); }
8274 while(!feof($f)) { $font
.= fread($f
, 2048); }
8276 include(_MPDF_TTFONTDATAPATH
.$fontkey.'.ps.php'); // sets $originalsize (of repackaged font)
8279 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH
.'classes/ttfontsuni.php'); }
8280 $ttf = new TTFontFile();
8281 $font = $ttf->repackageTTF($this->FontFiles
[$fontkey]['ttffile'], $this->fonts
[$fontkey]['TTCfontID'], $this->debugfonts
, $this->fonts
[$fontkey]['unAGlyphs']); // mPDF 5.4.05
8283 $originalsize = strlen($font);
8284 $font = gzcompress($font);
8286 if (is_writable(dirname(_MPDF_TTFONTDATAPATH
.'x'))) {
8287 $fh = fopen(_MPDF_TTFONTDATAPATH
.$fontkey.'.ps.z',"wb");
8288 fwrite($fh,$font,strlen($font));
8290 $fh = fopen(_MPDF_TTFONTDATAPATH
.$fontkey.'.ps.php',"wb");
8292 $len.='$originalsize='.$originalsize.";\n";
8294 fwrite($fh,$len,strlen($len));
8300 // First see if there is a cached compressed file
8301 if (file_exists(_MPDF_TTFONTDATAPATH
.$fontkey.'.z')) {
8302 $f=fopen(_MPDF_TTFONTDATAPATH
.$fontkey.'.z','rb');
8303 if(!$f) { $this
->Error('Font file not found'); }
8304 while(!feof($f)) { $font
.= fread($f
, 2048); }
8308 $f=fopen($this->FontFiles
[$fontkey]['ttffile'],'rb');
8309 if(!$f) { $this
->Error('Font file not found'); }
8310 while(!feof($f)) { $font
.= fread($f
, 2048); }
8312 $font = gzcompress($font);
8313 if (is_writable(dirname(_MPDF_TTFONTDATAPATH
.'x'))) {
8314 $fh = fopen(_MPDF_TTFONTDATAPATH
.$fontkey.'.z',"wb");
8315 fwrite($fh,$font,strlen($font));
8321 $this->_out('<</Length '.strlen($font));
8322 $this->_out('/Filter /FlateDecode');
8323 $this->_out('/Length1 '.$originalsize);
8325 $this->_putstream($font);
8326 $this->_out('endobj');
8331 $nfonts = count($this->fonts
);
8333 foreach($this->fonts
as $k=>$font) {
8335 $type=$font['type'];
8336 $name=$font['name'];
8337 if ((!isset($font['used']) || !$font['used']) && $type=='TTF') { continue; }
8338 if ($this->progressBar
) { $this
->UpdateProgressBar(2,intval($fctr
*100/$nfonts
),'Writing Fonts'); $fctr++
; } // *PROGRESS-BAR*
8339 if (isset($font['asSubset'])) { $asSubset
= $font
['asSubset']; }
8340 else { $asSubset
= ''; }
8342 if($type=='Type0') { // = Adobe CJK Fonts
8343 $this->fonts
[$k]['n']=$this->n+
1;
8345 $this->_out('<</Type /Font');
8346 $this->_putType0($font);
8349 /*-- END CJK-FONTS --*/
8352 $this->fonts
[$k]['n']=$this->n+
1;
8353 if ($this->PDFA
|| $this->PDFX
) { $this
->Error('Core fonts are not allowed in PDF/A1-b or PDFX/1-a files (Times, Helvetica, Courier etc.)'); }
8355 $this->_out('<</Type /Font');
8356 $this->_out('/BaseFont /'.$name);
8357 $this->_out('/Subtype /Type1');
8358 if($name!='Symbol' && $name!='ZapfDingbats') {
8359 $this->_out('/Encoding /WinAnsiEncoding');
8362 $this->_out('endobj');
8364 // TrueType embedded SUBSETS for SIP (CJK extB containing Supplementary Ideographic Plane 2)
8365 // Or Unicode Plane 1 - Supplementary Multilingual Plane
8366 else if ($type=='TTF' && ($font['sip'] || $font['smp'])) {
8367 if (!$font['used']) { continue; }
8369 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH
.'classes/ttfontsuni.php'); }
8370 $ttf = new TTFontFile();
8371 for($sfid=0;$sfid<count($font['subsetfontids']);$sfid++
) {
8372 $this->fonts
[$k]['n'][$sfid]=$this->n+
1; // NB an array for subset
8373 $subsetname = 'MPDF'.$ssfaid.'+'.$font['name'];
8375 $subset = $font['subsets'][$sfid];
8377 $ttfontstream = $ttf->makeSubsetSIP($font['ttffile'], $subset, $font['TTCfontID'], $this->debugfonts
);
8378 $ttfontsize = strlen($ttfontstream);
8379 $fontstream = gzcompress($ttfontstream);
8382 foreach($font['subsets'][$sfid] AS $cp=>$u) {
8383 $w = $this->_getCharWidth($font['cw'], $u);
8385 $widthstring .= $w.' ';
8388 $widthstring .= round($ttf->defaultWidth
).' ';
8391 $utf8 = chr(($u>>18)+
240).chr((($u>>12)&63)+
128).chr((($u>>6)&63)+
128) .chr(($u&63)+
128);
8392 $utf16 = mb_convert_encoding($utf8, 'UTF-16BE', 'UTF-8');
8393 $l1 = ord($utf16[0]);
8394 $h1 = ord($utf16[1]);
8395 $l2 = ord($utf16[2]);
8396 $h2 = ord($utf16[3]);
8397 $toUnistring .= sprintf("<%02s> <%02s%02s%02s%02s>\n", strtoupper(dechex($cp)), strtoupper(dechex($l1)), strtoupper(dechex($h1)), strtoupper(dechex($l2)), strtoupper(dechex($h2)));
8400 $toUnistring .= sprintf("<%02s> <%04s>\n", strtoupper(dechex($cp)), strtoupper(dechex($u)));
8404 //Additional Type1 or TrueType font
8406 $this->_out('<</Type /Font');
8407 $this->_out('/BaseFont /'.$subsetname);
8408 $this->_out('/Subtype /TrueType');
8409 $this->_out('/FirstChar 0 /LastChar '.(count($font['subsets'][$sfid])-1));
8410 $this->_out('/Widths '.($this->n+
1).' 0 R');
8411 $this->_out('/FontDescriptor '.($this->n+
2).' 0 R');
8412 $this->_out('/ToUnicode '.($this->n +
3).' 0 R');
8414 $this->_out('endobj');
8418 $this->_out('['.$widthstring.']');
8419 $this->_out('endobj');
8423 $s='<</Type /FontDescriptor /FontName /'.$subsetname."\n";
8424 foreach($font['desc'] as $kd=>$v) {
8425 if ($kd == 'Flags') { $v
= $v
| 4; $v
= $v
& ~
32; } // SYMBOLIC font flag
8426 $s.=' /'.$kd.' '.$v."\n";
8428 $s.='/FontFile2 '.($this->n +
2).' 0 R';
8429 $this->_out($s.'>>');
8430 $this->_out('endobj');
8434 $toUni = "/CIDInit /ProcSet findresource begin\n";
8435 $toUni .= "12 dict begin\n";
8436 $toUni .= "begincmap\n";
8437 $toUni .= "/CIDSystemInfo\n";
8438 $toUni .= "<</Registry (Adobe)\n";
8439 $toUni .= "/Ordering (UCS)\n";
8440 $toUni .= "/Supplement 0\n";
8441 $toUni .= ">> def\n";
8442 $toUni .= "/CMapName /Adobe-Identity-UCS def\n";
8443 $toUni .= "/CMapType 2 def\n";
8444 $toUni .= "1 begincodespacerange\n";
8445 $toUni .= "<00> <FF>\n";
8446 $toUni .= "endcodespacerange\n";
8447 $toUni .= count($font['subsets'][$sfid])." beginbfchar\n";
8448 $toUni .= $toUnistring;
8449 $toUni .= "endbfchar\n";
8450 $toUni .= "endcmap\n";
8451 $toUni .= "CMapName currentdict /CMap defineresource pop\n";
8455 $this->_out('<</Length '.(strlen($toUni)).'>>');
8456 $this->_putstream($toUni);
8457 $this->_out('endobj');
8461 $this->_out('<</Length '.strlen($fontstream));
8462 $this->_out('/Filter /FlateDecode');
8463 $this->_out('/Length1 '.$ttfontsize);
8465 $this->_putstream($fontstream);
8466 $this->_out('endobj');
8470 // TrueType embedded SUBSETS or FULL
8471 else if ($type=='TTF') {
8472 $this->fonts
[$k]['n']=$this->n+
1;
8475 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH
.'classes/ttfontsuni.php'); }
8476 $ttf = new TTFontFile();
8477 $fontname = 'MPDFA'.$ssfaid.'+'.$font['name'];
8478 $subset = $font['subset'];
8480 $ttfontstream = $ttf->makeSubset($font['ttffile'], $subset, $font['TTCfontID'], $this->debugfonts
, $font['unAGlyphs']); // mPDF 5.4.05
8481 $ttfontsize = strlen($ttfontstream);
8482 $fontstream = gzcompress($ttfontstream);
8483 $codeToGlyph = $ttf->codeToGlyph
;
8484 unset($codeToGlyph[0]);
8486 else { $fontname
= $font
['name']; }
8488 // A composite font - a font composed of other fonts, organized hierarchically
8490 $this->_out('<</Type /Font');
8491 $this->_out('/Subtype /Type0');
8492 $this->_out('/BaseFont /'.$fontname.'');
8493 $this->_out('/Encoding /Identity-H');
8494 $this->_out('/DescendantFonts ['.($this->n +
1).' 0 R]');
8495 $this->_out('/ToUnicode '.($this->n +
2).' 0 R');
8497 $this->_out('endobj');
8500 // A CIDFont whose glyph descriptions are based on TrueType font technology
8502 $this->_out('<</Type /Font');
8503 $this->_out('/Subtype /CIDFontType2');
8504 $this->_out('/BaseFont /'.$fontname.'');
8505 $this->_out('/CIDSystemInfo '.($this->n +
2).' 0 R');
8506 $this->_out('/FontDescriptor '.($this->n +
3).' 0 R');
8507 if (isset($font['desc']['MissingWidth'])){
8508 $this->_out('/DW '.$font['desc']['MissingWidth'].'');
8511 if (!$asSubset && file_exists(_MPDF_TTFONTDATAPATH
.$font['fontkey'].'.cw')) {
8513 $w=file_get_contents(_MPDF_TTFONTDATAPATH
.$font['fontkey'].'.cw');
8517 $this->_putTTfontwidths($font, $asSubset, $ttf->maxUni
);
8520 $this->_out('/CIDToGIDMap '.($this->n +
4).' 0 R');
8522 $this->_out('endobj');
8526 $toUni = "/CIDInit /ProcSet findresource begin\n";
8527 $toUni .= "12 dict begin\n";
8528 $toUni .= "begincmap\n";
8529 $toUni .= "/CIDSystemInfo\n";
8530 $toUni .= "<</Registry (Adobe)\n";
8531 $toUni .= "/Ordering (UCS)\n";
8532 $toUni .= "/Supplement 0\n";
8533 $toUni .= ">> def\n";
8534 $toUni .= "/CMapName /Adobe-Identity-UCS def\n";
8535 $toUni .= "/CMapType 2 def\n";
8536 $toUni .= "1 begincodespacerange\n";
8537 $toUni .= "<0000> <FFFF>\n";
8538 $toUni .= "endcodespacerange\n";
8539 $toUni .= "1 beginbfrange\n";
8540 $toUni .= "<0000> <FFFF> <0000>\n";
8541 $toUni .= "endbfrange\n";
8542 $toUni .= "endcmap\n";
8543 $toUni .= "CMapName currentdict /CMap defineresource pop\n";
8546 $this->_out('<</Length '.(strlen($toUni)).'>>');
8547 $this->_putstream($toUni);
8548 $this->_out('endobj');
8551 // CIDSystemInfo dictionary
8553 $this->_out('<</Registry (Adobe)');
8554 $this->_out('/Ordering (UCS)');
8555 $this->_out('/Supplement 0');
8557 $this->_out('endobj');
8561 $this->_out('<</Type /FontDescriptor');
8562 $this->_out('/FontName /'.$fontname);
8563 foreach($font['desc'] as $kd=>$v) {
8564 if ($asSubset && $kd == 'Flags') { $v
= $v
| 4; $v
= $v
& ~
32; } // SYMBOLIC font flag
8565 $this->_out(' /'.$kd.' '.$v);
8567 if ($font['panose']) {
8568 $this->_out(' /Style << /Panose <'.$font['panose'].'> >>');
8571 $this->_out('/FontFile2 '.($this->n +
2).' 0 R');
8573 else if ($font['fontkey']) {
8574 // obj ID of a stream containing a TrueType font program
8575 $this->_out('/FontFile2 '.$this->FontFiles
[$font['fontkey']]['n'].' 0 R');
8578 $this->_out('endobj');
8580 // Embed CIDToGIDMap
8581 // A specification of the mapping from CIDs to glyph indices
8584 $cidtogidmap = str_pad('', 256*256*2, "\x00");
8585 foreach($codeToGlyph as $cc=>$glyph) {
8586 $cidtogidmap[$cc*2] = chr($glyph >> 8);
8587 $cidtogidmap[$cc*2 +
1] = chr($glyph & 0xFF);
8589 $cidtogidmap = gzcompress($cidtogidmap);
8592 // First see if there is a cached CIDToGIDMapfile
8594 if (file_exists(_MPDF_TTFONTDATAPATH
.$font['fontkey'].'.cgm')) {
8595 $f=fopen(_MPDF_TTFONTDATAPATH
.$font['fontkey'].'.cgm','rb');
8596 while(!feof($f)) { $cidtogidmap
.= fread($f
, 2048); }
8600 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH
.'classes/ttfontsuni.php'); }
8601 $ttf = new TTFontFile();
8602 $charToGlyph = $ttf->getCTG($font['ttffile'], $font['TTCfontID'], $this->debugfonts
, $font['unAGlyphs']); // mPDF 5.4.05
8603 $cidtogidmap = str_pad('', 256*256*2, "\x00");
8604 foreach($charToGlyph as $cc=>$glyph) {
8605 $cidtogidmap[$cc*2] = chr($glyph >> 8);
8606 $cidtogidmap[$cc*2 +
1] = chr($glyph & 0xFF);
8609 $cidtogidmap = gzcompress($cidtogidmap);
8610 if (is_writable(dirname(_MPDF_TTFONTDATAPATH
.'x'))) {
8611 $fh = fopen(_MPDF_TTFONTDATAPATH
.$font['fontkey'].'.cgm',"wb");
8612 fwrite($fh,$cidtogidmap,strlen($cidtogidmap));
8618 $this->_out('<</Length '.strlen($cidtogidmap).'');
8619 $this->_out('/Filter /FlateDecode');
8621 $this->_putstream($cidtogidmap);
8622 $this->_out('endobj');
8627 $this->_out('<</Length '.strlen($fontstream));
8628 $this->_out('/Filter /FlateDecode');
8629 $this->_out('/Length1 '.$ttfontsize);
8631 $this->_putstream($fontstream);
8632 $this->_out('endobj');
8636 else { $this
->Error('Unsupported font type: '.$type
.' ('.$name
.')'); }
8642 function _putTTfontwidths(&$font, $asSubset, $maxUni) {
8643 if ($asSubset && file_exists(_MPDF_TTFONTDATAPATH
.$font['fontkey'].'.cw127.php')) {
8644 include(_MPDF_TTFONTDATAPATH
.$font['fontkey'].'.cw127.php') ;
8655 if ($asSubset) { $cwlen
= $maxUni +
1; }
8656 else { $cwlen
= (strlen($font
['cw'])/2); }
8658 // for each character
8659 for ($cid=$startcid; $cid<$cwlen; $cid++
) {
8660 if ($cid==128 && $asSubset && (!file_exists(_MPDF_TTFONTDATAPATH
.$font['fontkey'].'.cw127.php'))) {
8661 if (is_writable(dirname(_MPDF_TTFONTDATAPATH
.'x'))) {
8662 $fh = fopen(_MPDF_TTFONTDATAPATH
.$font['fontkey'].'.cw127.php',"wb");
8663 $cw127='<?php'."\n";
8664 $cw127.='$rangeid='.$rangeid.";\n";
8665 $cw127.='$prevcid='.$prevcid.";\n";
8666 $cw127.='$prevwidth='.$prevwidth.";\n";
8667 if ($interval) { $cw127
.='$interval=true'.";\n"; }
8668 else { $cw127
.='$interval=false'.";\n"; }
8669 $cw127.='$range='.var_export($range,true).";\n";
8671 fwrite($fh,$cw127,strlen($cw127));
8675 if ($font['cw'][$cid*2] == "\00" && $font['cw'][$cid*2+
1] == "\00") { continue; }
8676 $width = (ord($font['cw'][$cid*2]) << 8) +
ord($font['cw'][$cid*2+
1]);
8677 if ($width == 65535) { $width
= 0; }
8678 if ($asSubset && $cid > 255 && (!isset($font['subset'][$cid]) || !$font['subset'][$cid])) {
8681 if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) {
8682 if ($cid == ($prevcid +
1)) {
8684 if ($width == $prevwidth) {
8685 if ($width == $range[$rangeid][0]) {
8686 $range[$rangeid][] = $width;
8688 array_pop($range[$rangeid]);
8690 $rangeid = $prevcid;
8691 $range[$rangeid] = array();
8692 $range[$rangeid][] = $prevwidth;
8693 $range[$rangeid][] = $width;
8696 $range[$rangeid]['interval'] = true;
8701 $range[$rangeid] = array();
8702 $range[$rangeid][] = $width;
8704 $range[$rangeid][] = $width;
8711 $range[$rangeid] = array();
8712 $range[$rangeid][] = $width;
8716 $prevwidth = $width;
8719 $w = $this->_putfontranges($range);
8722 if (is_writable(dirname(_MPDF_TTFONTDATAPATH
.'x'))) {
8723 $fh = fopen(_MPDF_TTFONTDATAPATH
.$font['fontkey'].'.cw',"wb");
8724 fwrite($fh,$w,strlen($w));
8730 function _putfontranges(&$range) {
8735 foreach ($range as $k => $ws) {
8737 if (($k == $nextk) AND (!$prevint) AND ((!isset($ws['interval'])) OR ($cws < 4))) {
8738 if (isset($range[$k]['interval'])) {
8739 unset($range[$k]['interval']);
8741 $range[$prevk] = array_merge($range[$prevk], $range[$k]);
8747 if (isset($ws['interval'])) {
8753 unset($range[$k]['interval']);
8761 foreach ($range as $k => $ws) {
8762 if (count(array_count_values($ws)) == 1) {
8763 // interval mode is more compact
8764 $w .= ' '.$k.' '.($k +
count($ws) - 1).' '.$ws[0];
8767 $w .= ' '.$k.' [ '.implode(' ', $ws).' ]' . "\n";
8770 return '/W ['.$w.' ]';
8774 function _putfontwidths(&$font, $cidoffset=0) {
8776 unset($font['cw'][65535]);
8782 // for each character
8783 foreach ($font['cw'] as $cid => $width) {
8785 if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) {
8786 if ($cid == ($prevcid +
1)) {
8788 if ($width == $prevwidth) {
8789 if ($width == $range[$rangeid][0]) {
8790 $range[$rangeid][] = $width;
8792 array_pop($range[$rangeid]);
8794 $rangeid = $prevcid;
8795 $range[$rangeid] = array();
8796 $range[$rangeid][] = $prevwidth;
8797 $range[$rangeid][] = $width;
8800 $range[$rangeid]['interval'] = true;
8805 $range[$rangeid] = array();
8806 $range[$rangeid][] = $width;
8808 $range[$rangeid][] = $width;
8815 $range[$rangeid] = array();
8816 $range[$rangeid][] = $width;
8820 $prevwidth = $width;
8823 $this->_out($this->_putfontranges($range));
8829 // from class PDF_Chinese CJK EXTENSIONS
8830 function _putType0(&$font)
8833 $this->_out('/Subtype /Type0');
8834 $this->_out('/BaseFont /'.$font['name'].'-'.$font['CMap']);
8835 $this->_out('/Encoding /'.$font['CMap']);
8836 $this->_out('/DescendantFonts ['.($this->n+
1).' 0 R]');
8838 $this->_out('endobj');
8841 $this->_out('<</Type /Font');
8842 $this->_out('/Subtype /CIDFontType0');
8843 $this->_out('/BaseFont /'.$font['name']);
8845 $cidinfo = '/Registry '.$this->_textstring('Adobe');
8846 $cidinfo .= ' /Ordering '.$this->_textstring($font['registry']['ordering']);
8847 $cidinfo .= ' /Supplement '.$font['registry']['supplement'];
8848 $this->_out('/CIDSystemInfo <<'.$cidinfo.'>>');
8850 $this->_out('/FontDescriptor '.($this->n+
1).' 0 R');
8851 if (isset($font['MissingWidth'])){
8852 $this->_out('/DW '.$font['MissingWidth'].'');
8854 $this->_putfontwidths($font, 31);
8856 $this->_out('endobj');
8860 $s = '<</Type /FontDescriptor /FontName /'.$font['name'];
8861 foreach ($font['desc'] as $k => $v) {
8862 if ($k != 'Style') {
8863 $s .= ' /'.$k.' '.$v.'';
8866 $this->_out($s.'>>');
8867 $this->_out('endobj');
8869 /*-- END CJK-FONTS --*/
8873 function _putimages()
8875 $filter=($this->compress
) ? '/Filter /FlateDecode ' : '';
8876 reset($this->images
);
8877 while(list($file,$info)=each($this->images
)) {
8879 $this->images
[$file]['n']=$this->n
;
8880 $this->_out('<</Type /XObject');
8881 $this->_out('/Subtype /Image');
8882 $this->_out('/Width '.$info['w']);
8883 $this->_out('/Height '.$info['h']);
8884 if (isset($info['masked'])) {
8885 $this->_out('/SMask '.($this->n
- 1).' 0 R');
8887 if($info['cs']=='Indexed') {
8888 if ($this->PDFX
|| ($this->PDFA
&& $this->restrictColorSpace
==3)) { $this
->Error("PDFA1-b and PDFX/1-a files do not permit using mixed colour space (".$file
.")."); }
8889 $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+
1).' 0 R]');
8892 $this->_out('/ColorSpace /'.$info['cs']);
8893 if($info['cs']=='DeviceCMYK') {
8894 if ($this->PDFA
&& $this->restrictColorSpace
!=3) { $this
->Error("PDFA1-b does not permit Images using mixed colour space (".$file
.")."); }
8895 if($info['type']=='jpg') { $this
->_out('/Decode [1 0 1 0 1 0 1 0]'); }
8897 else if ($info['cs']=='DeviceRGB' && ($this->PDFX
|| ($this->PDFA
&& $this->restrictColorSpace
==3))) { $this
->Error("PDFA1-b and PDFX/1-a files do not permit using mixed colour space (".$file
.")."); }
8899 $this->_out('/BitsPerComponent '.$info['bpc']);
8900 if (isset($info['f']) && $info['f']) { $this
->_out('/Filter /'.$info
['f']); }
8901 if(isset($info['parms'])) { $this
->_out($info
['parms']); }
8902 if(isset($info['trns']) and is_array($info['trns'])) {
8904 for($i=0;$i<count($info['trns']);$i++
)
8905 $trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
8906 $this->_out('/Mask ['.$trns.']');
8908 $this->_out('/Length '.strlen($info['data']).'>>');
8909 $this->_putstream($info['data']);
8911 unset($this->images
[$file]['data']);
8912 $this->_out('endobj');
8914 if($info['cs']=='Indexed') {
8916 $pal=($this->compress
) ? gzcompress($info['pal']) : $info['pal'];
8917 $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
8918 $this->_putstream($pal);
8919 $this->_out('endobj');
8926 $this->_out('/Producer '.$this->_UTF16BEtextstring('mPDF '.mPDF_VERSION
));
8927 if(!empty($this->title
))
8928 $this->_out('/Title '.$this->_UTF16BEtextstring($this->title
));
8929 if(!empty($this->subject
))
8930 $this->_out('/Subject '.$this->_UTF16BEtextstring($this->subject
));
8931 if(!empty($this->author
))
8932 $this->_out('/Author '.$this->_UTF16BEtextstring($this->author
));
8933 if(!empty($this->keywords
))
8934 $this->_out('/Keywords '.$this->_UTF16BEtextstring($this->keywords
));
8935 if(!empty($this->creator
))
8936 $this->_out('/Creator '.$this->_UTF16BEtextstring($this->creator
));
8938 $z = date('O'); // +0200
8939 $offset = substr($z,0,3)."'".substr($z,3,2)."'";
8940 $this->_out('/CreationDate '.$this->_textstring(date('YmdHis').$offset));
8941 $this->_out('/ModDate '.$this->_textstring(date('YmdHis').$offset));
8943 $this->_out('/Trapped/False');
8944 $this->_out('/GTS_PDFXVersion(PDF/X-1a:2003)');
8948 function _putmetadata() {
8950 $this->MetadataRoot
= $this->n
;
8951 $Producer = 'mPDF '.mPDF_VERSION
;
8952 $z = date('O'); // +0200
8953 $offset = substr($z,0,3).':'.substr($z,3,2);
8954 $CreationDate = date('Y-m-d\TH:i:s').$offset; // 2006-03-10T10:47:26-05:00 2006-06-19T09:05:17Z
8955 $uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff),
8956 mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
8957 mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) );
8960 $m = '<?xpacket begin="'.chr(239).chr(187).chr(191).'" id="W5M0MpCehiHzreSzNTczkc9d"?>'."\n"; // begin = FEFF BOM
8961 $m .= ' <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="3.1-701">'."\n";
8962 $m .= ' <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">'."\n";
8963 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:pdf="http://ns.adobe.com/pdf/1.3/">'."\n";
8964 $m .= ' <pdf:Producer>'.$Producer.'</pdf:Producer>'."\n";
8965 if(!empty($this->keywords
)) { $m
.= ' <pdf:Keywords>'.$this
->keywords
.'</pdf:Keywords>'."\n"; }
8966 $m .= ' </rdf:Description>'."\n";
8968 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:xmp="http://ns.adobe.com/xap/1.0/">'."\n";
8969 $m .= ' <xmp:CreateDate>'.$CreationDate.'</xmp:CreateDate>'."\n";
8970 $m .= ' <xmp:ModifyDate>'.$CreationDate.'</xmp:ModifyDate>'."\n";
8971 $m .= ' <xmp:MetadataDate>'.$CreationDate.'</xmp:MetadataDate>'."\n";
8972 if(!empty($this->creator
)) { $m
.= ' <xmp:CreatorTool>'.$this
->creator
.'</xmp:CreatorTool>'."\n"; }
8973 $m .= ' </rdf:Description>'."\n";
8976 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:dc="http://purl.org/dc/elements/1.1/">'."\n";
8977 $m .= ' <dc:format>application/pdf</dc:format>'."\n";
8978 if(!empty($this->title
)) {
8981 <rdf:li xml:lang="x-default">'.$this->title
.'</rdf:li>
8985 if(!empty($this->keywords
)) {
8986 $m .= ' <dc:subject>
8988 <rdf:li>'.$this->keywords
.'</rdf:li>
8990 </dc:subject>'."\n";
8992 if(!empty($this->subject
)) {
8993 $m .= ' <dc:description>
8995 <rdf:li xml:lang="x-default">'.$this->subject
.'</rdf:li>
8997 </dc:description>'."\n";
8999 if(!empty($this->author
)) {
9000 $m .= ' <dc:creator>
9002 <rdf:li>'.$this->author
.'</rdf:li>
9004 </dc:creator>'."\n";
9006 $m .= ' </rdf:Description>'."\n";
9009 // This bit is specific to PDFX-1a
9011 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/" pdfx:Apag_PDFX_Checkup="1.3" pdfx:GTS_PDFXConformance="PDF/X-1a:2003" pdfx:GTS_PDFXVersion="PDF/X-1:2003"/>'."\n";
9014 // This bit is specific to PDFA-1b
9015 else if ($this->PDFA
) {
9016 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/" >'."\n";
9017 $m .= ' <pdfaid:part>1</pdfaid:part>'."\n";
9018 $m .= ' <pdfaid:conformance>B</pdfaid:conformance>'."\n";
9019 $m .= ' <pdfaid:amd>2005</pdfaid:amd>'."\n";
9020 $m .= ' </rdf:Description>'."\n";
9023 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">'."\n";
9024 $m .= ' <xmpMM:DocumentID>uuid:'.$uuid.'</xmpMM:DocumentID>'."\n";
9025 $m .= ' </rdf:Description>'."\n";
9026 $m .= ' </rdf:RDF>'."\n";
9027 $m .= ' </x:xmpmeta>'."\n";
9028 $m .= str_repeat(str_repeat(' ',100)."\n",20); // 2-4kB whitespace padding required
9029 $m .= '<?xpacket end="w"?>'; // "r" read only
9030 $this->_out('<</Type/Metadata/Subtype/XML/Length '.strlen($m).'>>');
9031 $this->_putstream($m);
9032 $this->_out('endobj');
9035 function _putoutputintent() {
9037 $this->OutputIntentRoot
= $this->n
;
9038 $this->_out('<</Type /OutputIntent');
9041 $this->_out('/S /GTS_PDFA1');
9042 if ($this->ICCProfile
) {
9043 $this->_out('/Info ('.preg_replace('/_/',' ',$this->ICCProfile
).')');
9044 $this->_out('/OutputConditionIdentifier (Custom)');
9045 $this->_out('/OutputCondition ()');
9048 $this->_out('/Info (sRGB IEC61966-2.1)');
9049 $this->_out('/OutputConditionIdentifier (sRGB IEC61966-2.1)');
9050 $this->_out('/OutputCondition ()');
9052 $this->_out('/DestOutputProfile '.($this->n+
1).' 0 R');
9054 else if ($this->PDFX
) { // always a CMYK profile
9055 $this->_out('/S /GTS_PDFX');
9056 if ($this->ICCProfile
) {
9057 $this->_out('/Info ('.preg_replace('/_/',' ',$this->ICCProfile
).')');
9058 $this->_out('/OutputConditionIdentifier (Custom)');
9059 $this->_out('/OutputCondition ()');
9060 $this->_out('/DestOutputProfile '.($this->n+
1).' 0 R');
9063 $this->_out('/Info (CGATS TR 001)');
9064 $this->_out('/OutputConditionIdentifier (CGATS TR 001)');
9065 $this->_out('/OutputCondition (CGATS TR 001 (SWOP))');
9066 $this->_out('/RegistryName (http://www.color.org)');
9070 $this->_out('endobj');
9072 if ($this->PDFX
&& !$this->ICCProfile
) { return; } // no ICCProfile embedded
9075 if ($this->ICCProfile
)
9076 $s = file_get_contents(_MPDF_PATH
.'iccprofiles/'.$this->ICCProfile
.'.icc');
9078 $s = file_get_contents(_MPDF_PATH
.'iccprofiles/sRGB_IEC61966-2-1.icc');
9079 if ($this->compress
) { $s
= gzcompress($s
); }
9081 if ($this->PDFX
|| ($this->PDFA
&& $this->restrictColorSpace
== 3)) { $this
->_out('/N 4'); }
9082 else { $this
->_out('/N 3'); }
9083 if ($this->compress
)
9084 $this->_out('/Filter /FlateDecode ');
9085 $this->_out('/Length '.strlen($s).'>>');
9086 $this->_putstream($s);
9087 $this->_out('endobj');
9091 function _putcatalog() {
9092 $this->_out('/Type /Catalog');
9093 $this->_out('/Pages 1 0 R');
9094 if($this->ZoomMode
=='fullpage') $this->_out('/OpenAction [3 0 R /Fit]');
9095 elseif($this->ZoomMode
=='fullwidth') $this->_out('/OpenAction [3 0 R /FitH null]');
9096 elseif($this->ZoomMode
=='real') $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
9097 elseif(!is_string($this->ZoomMode
)) $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode
/100).']');
9098 else $this->_out('/OpenAction [3 0 R /XYZ null null null]');
9099 if($this->LayoutMode
=='single') $this->_out('/PageLayout /SinglePage');
9100 elseif($this->LayoutMode
=='continuous') $this->_out('/PageLayout /OneColumn');
9101 elseif($this->LayoutMode
=='twoleft') $this->_out('/PageLayout /TwoColumnLeft');
9102 elseif($this->LayoutMode
=='tworight') $this->_out('/PageLayout /TwoColumnRight');
9103 elseif($this->LayoutMode
=='two') {
9104 if ($this->mirrorMargins
) { $this
->_out('/PageLayout /TwoColumnRight'); }
9105 else { $this
->_out('/PageLayout /TwoColumnLeft'); }
9109 if(count($this->BMoutlines
)>0) {
9110 $this->_out('/Outlines '.$this->OutlineRoot
.' 0 R');
9111 $this->_out('/PageMode /UseOutlines');
9113 /*-- END BOOKMARKS --*/
9114 if(is_int(strpos($this->DisplayPreferences
,'FullScreen'))) $this->_out('/PageMode /FullScreen');
9117 if ($this->PDFA
|| $this->PDFX
) {
9118 $this->_out('/Metadata '.$this->MetadataRoot
.' 0 R');
9121 if ($this->PDFA
|| $this->PDFX
|| $this->ICCProfile
) {
9122 $this->_out('/OutputIntents ['.$this->OutputIntentRoot
.' 0 R]');
9126 if (count($this->form
->forms
)>0) {
9127 $this->form
->_putFormsCatalog();
9130 if ( isset($this->js
) ) {
9131 $this->_out('/Names << /JavaScript '.($this->n_js
).' 0 R >> ');
9134 if($this->DisplayPreferences
|| $this->directionality
== 'rtl' || $this->mirrorMargins
) {
9135 $this->_out('/ViewerPreferences<<');
9136 if(is_int(strpos($this->DisplayPreferences
,'HideMenubar'))) $this->_out('/HideMenubar true');
9137 if(is_int(strpos($this->DisplayPreferences
,'HideToolbar'))) $this->_out('/HideToolbar true');
9138 if(is_int(strpos($this->DisplayPreferences
,'HideWindowUI'))) $this->_out('/HideWindowUI true');
9139 if(is_int(strpos($this->DisplayPreferences
,'DisplayDocTitle'))) $this->_out('/DisplayDocTitle true');
9140 if(is_int(strpos($this->DisplayPreferences
,'CenterWindow'))) $this->_out('/CenterWindow true');
9141 if(is_int(strpos($this->DisplayPreferences
,'FitWindow'))) $this->_out('/FitWindow true');
9142 // /PrintScaling is PDF 1.6 spec.
9143 if(is_int(strpos($this->DisplayPreferences
,'NoPrintScaling')) && !$this->PDFA
&& !$this->PDFX
)
9144 $this->_out('/PrintScaling /None');
9145 if($this->directionality
== 'rtl') $this->_out('/Direction /R2L');
9146 // /Duplex is PDF 1.7 spec.
9147 if($this->mirrorMargins
&& !$this->PDFA
&& !$this->PDFX
) {
9148 // if ($this->DefOrientation=='P') $this->_out('/Duplex /DuplexFlipShortEdge');
9149 $this->_out('/Duplex /DuplexFlipLongEdge'); // PDF v1.7+
9154 if($this->open_layer_pane
&& ($this->hasOC
|| count($this->layers
)))
9155 $this->_out('/PageMode /UseOC');
9158 if ($this->hasOC
|| count($this->layers
)) {
9159 $p = $v = $h = $l = $loff = $lall = $as = ''; // mPDF 5.6.28
9161 if (($this->hasOC
& 1) == 1) $p=$this->n_ocg_print
.' 0 R';
9162 if (($this->hasOC
& 2) == 2) $v=$this->n_ocg_view
.' 0 R';
9163 if (($this->hasOC
& 4) == 4) $h=$this->n_ocg_hidden
.' 0 R';
9164 $as="<</Event /Print /OCGs [$p $v $h] /Category [/Print]>> <</Event /View /OCGs [$p $v $h] /Category [/View]>>";
9167 if(count($this->layers
)) {
9168 foreach($this->layers
as $k=>$layer) { // mPDF 5.6.28
9169 if (strtolower($this->layerDetails
[$k]['state'])=='hidden') { $loff
.= $layer
['n'].' 0 R '; }
9170 else { $l
.= $layer
['n'].' 0 R '; }
9171 $lall .= $layer['n'].' 0 R ';
9174 $this->_out("/OCProperties <</OCGs [$p $v $h $lall] /D <</ON [$p $l] /OFF [$v $h $loff] "); // mPDF 5.6.28
9175 $this->_out("/Order [$v $p $h $lall] "); // mPDF 5.6.28
9176 if ($as) $this->_out("/AS [$as] ");
9177 $this->_out(">>>>");
9183 // Inactive function left for backwards compatability
9184 function SetUserRights($enable=true, $annots="", $form="", $signature="") {
9188 function _enddoc() {
9189 if ($this->progressBar
) { $this
->UpdateProgressBar(2,'10','Writing Headers & Footers'); } // *PROGRESS-BAR*
9190 $this->_puthtmlheaders(); // *HTMLHEADERS-FOOTERS*
9191 if ($this->progressBar
) { $this
->UpdateProgressBar(2,'20','Writing Pages'); } // *PROGRESS-BAR*
9192 // Remove references to unused fonts (usually default font)
9193 foreach($this->fonts
as $fk=>$font) {
9194 if (!$font['used'] && ($font['type']=='TTF')) {
9195 if ($font['sip'] || $font['smp']) {
9196 foreach($font['subsetfontids'] AS $k => $fid) {
9197 foreach($this->pages
AS $pn=>$page) {
9198 $this->pages
[$pn] = preg_replace('/\s\/F'.$fid.' \d[\d.]* Tf\s/is',' ',$this->pages
[$pn]);
9203 foreach($this->pages
AS $pn=>$page) {
9204 $this->pages
[$pn] = preg_replace('/\s\/F'.$font['i'].' \d[\d.]* Tf\s/is',' ',$this->pages
[$pn]);
9210 // mPDF 5.6.01 - LAYERS
9211 if (count($this->layers
)) {
9212 foreach($this->pages
AS $pn=>$page) {
9213 preg_match_all('/\/OCZ-index \/ZI(\d+) BDC(.*?)(EMCZ)-index/is',$this->pages
[$pn],$m1);
9214 preg_match_all('/\/OCBZ-index \/ZI(\d+) BDC(.*?)(EMCBZ)-index/is',$this->pages
[$pn],$m2);
9215 preg_match_all('/\/OCGZ-index \/ZI(\d+) BDC(.*?)(EMCGZ)-index/is',$this->pages
[$pn],$m3);
9217 for ($i=0;$i<4;$i++
) {
9218 $m[$i] = array_merge($m1[$i],$m2[$i],$m3[$i]);
9222 for($i=0;$i<count($m[0]);$i++
) {
9224 if ($m[3][$i]=='EMCZ') $key +
=2; // background first then gradient then normal
9225 else if ($m[3][$i]=='EMCGZ') $key +
=1;
9226 $sortarr[$i] = $key;
9229 foreach($sortarr AS $i=>$k) {
9230 $this->pages
[$pn] = str_replace($m[0][$i],'',$this->pages
[$pn] );
9231 $this->pages
[$pn] .= "\n".$m[0][$i]."\n";
9233 $this->pages
[$pn] = preg_replace('/\/OC[BG]{0,1}Z-index \/ZI(\d+) BDC/is','/OC /ZI\\1 BDC ',$this->pages
[$pn]);
9234 $this->pages
[$pn] = preg_replace('/EMC[BG]{0,1}Z-index/is','EMC',$this->pages
[$pn]);
9240 if ($this->progressBar
) { $this
->UpdateProgressBar(2,'30','Writing document resources'); } // *PROGRESS-BAR*
9242 $this->_putresources();
9245 $this->InfoRoot
= $this->n
;
9247 if ($this->progressBar
) { $this
->UpdateProgressBar(2,'80','Writing document info'); } // *PROGRESS-BAR*
9250 $this->_out('endobj');
9253 if ($this->PDFA
|| $this->PDFX
) { $this
->_putmetadata(); }
9255 if ($this->PDFA
|| $this->PDFX
|| $this->ICCProfile
) { $this
->_putoutputintent(); }
9260 if ($this->progressBar
) { $this
->UpdateProgressBar(2,'90','Writing document catalog'); } // *PROGRESS-BAR*
9261 $this->_putcatalog();
9263 $this->_out('endobj');
9265 $o=strlen($this->buffer
);
9266 $this->_out('xref');
9267 $this->_out('0 '.($this->n+
1));
9268 $this->_out('0000000000 65535 f ');
9269 for($i=1; $i <= $this->n
; $i++
)
9270 $this->_out(sprintf('%010d 00000 n ',$this->offsets
[$i]));
9272 $this->_out('trailer');
9274 $this->_puttrailer();
9276 $this->_out('startxref');
9279 $this->buffer
.= '%%EOF';
9283 if ($this->enableImports
&& count($this->parsers
) > 0) {
9284 foreach ($this->parsers
as $k => $_){
9285 $this->parsers
[$k]->closeFile();
9286 $this->parsers
[$k] = null;
9287 unset($this->parsers
[$k]);
9290 /*-- END IMPORTS --*/
9293 function _beginpage($orientation,$mgl='',$mgr='',$mgt='',$mgb='',$mgh='',$mgf='',$ohname='',$ehname='',$ofname='',$efname='',$ohvalue=0,$ehvalue=0,$ofvalue=0,$efvalue=0,$pagesel='',$newformat='') {
9294 if (!($pagesel && $this->page
==1 && (sprintf("%0.4f", $this->y
)==sprintf("%0.4f", $this->tMargin
)))) {
9296 $this->pages
[$this->page
]='';
9299 $resetHTMLHeadersrequired = false;
9301 if ($newformat) { $this
->_setPageSize($newformat
, $orientation
); }
9303 // Paged media (page-box)
9305 if ($pagesel || (isset($this->page_box
['using']) && $this->page_box
['using'])) {
9306 if ($pagesel || $this->page
==1) { $first
= true; }
9307 else { $first
= false; }
9308 if ($this->mirrorMargins
&& ($this->page %
2==0)) { $oddEven
= 'E'; }
9309 else { $oddEven
= 'O'; }
9310 if ($pagesel) { $psel
= $pagesel
; }
9311 else if ($this->page_box
['current']) { $psel
= $this
->page_box
['current']; }
9312 else { $psel
= ''; }
9313 list($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS($psel, $first, $oddEven);
9314 if ($this->mirrorMargins
&& ($this->page %
2==0)) {
9315 if ($hname) { $ehvalue
= 1; $ehname
= $hname
; } else { $ehvalue
= -1; }
9316 if ($fname) { $efvalue
= 1; $efname
= $fname
; } else { $efvalue
= -1; }
9319 if ($hname) { $ohvalue
= 1; $ohname
= $hname
; } else { $ohvalue
= -1; }
9320 if ($fname) { $ofvalue
= 1; $ofname
= $fname
; } else { $ofvalue
= -1; }
9322 if ($resetpagenum || $pagenumstyle || $suppress) {
9323 $this->PageNumSubstitutions
[] = array('from'=>($this->page
), 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=>$suppress);
9325 // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
9326 $this->show_marks
= $marks;
9329 if (isset($bg['BACKGROUND-COLOR'])) {
9330 $cor = $this->ConvertColor($bg['BACKGROUND-COLOR']);
9332 $this->bodyBackgroundColor
= $cor;
9335 else { $this
->bodyBackgroundColor
= false; }
9337 /*-- BACKGROUNDS --*/
9338 if (isset($bg['BACKGROUND-GRADIENT'])) {
9339 $this->bodyBackgroundGradient
= $bg['BACKGROUND-GRADIENT'];
9341 else { $this
->bodyBackgroundGradient
= false; }
9344 if (isset($bg['BACKGROUND-IMAGE']) && $bg['BACKGROUND-IMAGE']) {
9345 $ret = $this->SetBackground($bg, $this->pgwidth
);
9346 if ($ret) { $this
->bodyBackgroundImage
= $ret
; }
9348 else { $this
->bodyBackgroundImage
= false; }
9349 /*-- END BACKGROUNDS --*/
9351 $this->page_box
['current'] = $psel;
9352 $this->page_box
['using'] = true;
9354 /*-- END CSS-PAGE --*/
9358 $orientation=$this->DefOrientation
;
9360 $orientation=strtoupper(substr($orientation,0,1));
9361 if($orientation!=$this->DefOrientation
)
9362 $this->OrientationChanges
[$this->page
]=true;
9364 if($orientation!=$this->CurOrientation
|| $newformat) {
9366 //Change orientation
9367 if($orientation=='P') {
9368 $this->wPt
=$this->fwPt
;
9369 $this->hPt
=$this->fhPt
;
9372 if (($this->forcePortraitHeaders
|| $this->forcePortraitMargins
) && $this->DefOrientation
=='P') {
9373 $this->tMargin
= $this->orig_tMargin
;
9374 $this->bMargin
= $this->orig_bMargin
;
9375 $this->DeflMargin
= $this->orig_lMargin
;
9376 $this->DefrMargin
= $this->orig_rMargin
;
9377 $this->margin_header
= $this->orig_hMargin
;
9378 $this->margin_footer
= $this->orig_fMargin
;
9380 else { $resetHTMLHeadersrequired
= true; } // *HTMLHEADERS-FOOTERS*
9383 $this->wPt
=$this->fhPt
;
9384 $this->hPt
=$this->fwPt
;
9387 if (($this->forcePortraitHeaders
|| $this->forcePortraitMargins
) && $this->DefOrientation
=='P') {
9388 $this->tMargin
= $this->orig_lMargin
;
9389 $this->bMargin
= $this->orig_rMargin
;
9390 $this->DeflMargin
= $this->orig_bMargin
;
9391 $this->DefrMargin
= $this->orig_tMargin
;
9392 $this->margin_header
= $this->orig_hMargin
;
9393 $this->margin_footer
= $this->orig_fMargin
;
9395 else { $resetHTMLHeadersrequired
= true; } // *HTMLHEADERS-FOOTERS*
9398 $this->CurOrientation
=$orientation;
9399 $this->ResetMargins();
9400 $this->pgwidth
= $this->w
- $this->lMargin
- $this->rMargin
;
9401 $this->PageBreakTrigger
=$this->h
-$this->bMargin
;
9404 $this->pageDim
[$this->page
]['w']=$this->w
;
9405 $this->pageDim
[$this->page
]['h']=$this->h
;
9407 $this->pageDim
[$this->page
]['outer_width_LR'] = isset($this->page_box
['outer_width_LR']) ? $this->page_box
['outer_width_LR'] : 0;
9408 $this->pageDim
[$this->page
]['outer_width_TB'] = isset($this->page_box
['outer_width_TB']) ? $this->page_box
['outer_width_TB'] : 0;
9409 if (!isset($this->page_box
['outer_width_LR']) && !isset($this->page_box
['outer_width_TB'])) {
9410 $this->pageDim
[$this->page
]['bleedMargin'] = 0;
9412 else if ($this->bleedMargin
<= $this->page_box
['outer_width_LR'] && $this->bleedMargin
<= $this->page_box
['outer_width_TB']) {
9413 $this->pageDim
[$this->page
]['bleedMargin'] = $this->bleedMargin
;
9416 $this->pageDim
[$this->page
]['bleedMargin'] = min($this->page_box
['outer_width_LR'], $this->page_box
['outer_width_TB'])-0.01;
9419 // If Page Margins are re-defined
9420 // strlen()>0 is used to pick up (integer) 0, (string) '0', or set value
9421 if ((strlen($mgl)>0 && $this->DeflMargin
!= $mgl) || (strlen($mgr)>0 && $this->DefrMargin
!= $mgr) || (strlen($mgt)>0 && $this->tMargin
!= $mgt) || (strlen($mgb)>0 && $this->bMargin
!= $mgb) || (strlen($mgh)>0 && $this->margin_header
!=$mgh) || (strlen($mgf)>0 && $this->margin_footer
!=$mgf)) {
9422 if (strlen($mgl)>0) $this->DeflMargin
= $mgl;
9423 if (strlen($mgr)>0) $this->DefrMargin
= $mgr;
9424 if (strlen($mgt)>0) $this->tMargin
= $mgt;
9425 if (strlen($mgb)>0) $this->bMargin
= $mgb;
9426 if (strlen($mgh)>0) $this->margin_header
=$mgh;
9427 if (strlen($mgf)>0) $this->margin_footer
=$mgf;
9428 $this->ResetMargins();
9429 $this->SetAutoPageBreak($this->autoPageBreak
,$this->bMargin
);
9430 $this->pgwidth
= $this->w
- $this->lMargin
- $this->rMargin
;
9431 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9434 $this->ResetMargins();
9435 $this->pgwidth
= $this->w
- $this->lMargin
- $this->rMargin
;
9436 $this->SetAutoPageBreak($this->autoPageBreak
,$this->bMargin
);
9438 // Reset column top margin
9439 $this->y0
= $this->tMargin
;
9441 $this->x
=$this->lMargin
;
9442 $this->y
=$this->tMargin
;
9443 $this->FontFamily
='';
9445 // HEADERS AND FOOTERS
9446 if ($ohvalue<0 || strtoupper($ohvalue)=='OFF') {
9447 $this->HTMLHeader
= '';
9448 $this->headerDetails
['odd'] = array();
9449 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9451 else if ($ohname && $ohvalue>0) {
9452 /*-- HTMLHEADERS-FOOTERS --*/
9453 if (preg_match('/^html_(.*)$/i',$ohname,$n)) {
9454 if (isset($this->pageHTMLheaders
[$n[1]])) { $this
->HTMLHeader
= $this
->pageHTMLheaders
[$n
[1]]; }
9455 else { $this
->HTMLHeader
= ''; }
9456 $this->headerDetails
['odd'] = array();
9457 $resetHTMLHeadersrequired = true;
9460 /*-- END HTMLHEADERS-FOOTERS --*/
9461 if (isset($this->pageheaders
[$ohname])) { $this
->headerDetails
['odd'] = $this
->pageheaders
[$ohname
]; }
9462 else if ($ohname!='_default') { $this
->headerDetails
['odd'] = array(); }
9463 $this->HTMLHeader
= '';
9464 /*-- HTMLHEADERS-FOOTERS --*/
9465 $resetHTMLHeadersrequired = false;
9467 /*-- END HTMLHEADERS-FOOTERS --*/
9470 if ($ehvalue<0 || strtoupper($ehvalue)=='OFF') {
9471 $this->HTMLHeaderE
= '';
9472 $this->headerDetails
['even'] = array();
9473 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9475 else if ($ehname && $ehvalue>0) {
9476 /*-- HTMLHEADERS-FOOTERS --*/
9477 if (preg_match('/^html_(.*)$/i',$ehname,$n)) {
9478 if (isset($this->pageHTMLheaders
[$n[1]])) { $this
->HTMLHeaderE
= $this
->pageHTMLheaders
[$n
[1]]; }
9479 else { $this
->HTMLHeaderE
= ''; }
9480 $this->headerDetails
['even'] = array();
9481 $resetHTMLHeadersrequired = true;
9484 /*-- END HTMLHEADERS-FOOTERS --*/
9485 if (isset($this->pageheaders
[$ehname])) { $this
->headerDetails
['even'] = $this
->pageheaders
[$ehname
]; }
9486 else if ($ehname!='_default') { $this
->headerDetails
['even'] = array(); }
9487 $this->HTMLHeaderE
= '';
9488 /*-- HTMLHEADERS-FOOTERS --*/
9489 $resetHTMLHeadersrequired = false;
9491 /*-- END HTMLHEADERS-FOOTERS --*/
9494 if ($ofvalue<0 || strtoupper($ofvalue)=='OFF') {
9495 $this->HTMLFooter
= '';
9496 $this->footerDetails
['odd'] = array();
9497 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9499 else if ($ofname && $ofvalue>0) {
9500 /*-- HTMLHEADERS-FOOTERS --*/
9501 if (preg_match('/^html_(.*)$/i',$ofname,$n)) {
9502 if (isset($this->pageHTMLfooters
[$n[1]])) { $this
->HTMLFooter
= $this
->pageHTMLfooters
[$n
[1]]; }
9503 else { $this
->HTMLFooter
= ''; }
9504 $this->footerDetails
['odd'] = array();
9505 $resetHTMLHeadersrequired = true;
9508 /*-- END HTMLHEADERS-FOOTERS --*/
9509 if (isset($this->pagefooters
[$ofname])) { $this
->footerDetails
['odd'] = $this
->pagefooters
[$ofname
]; }
9510 else if ($ofname!='_default') { $this
->footerDetails
['odd'] = array(); }
9511 $this->HTMLFooter
= '';
9512 /*-- HTMLHEADERS-FOOTERS --*/
9513 $resetHTMLHeadersrequired = true;
9515 /*-- END HTMLHEADERS-FOOTERS --*/
9518 if ($efvalue<0 || strtoupper($efvalue)=='OFF') {
9519 $this->HTMLFooterE
= '';
9520 $this->footerDetails
['even'] = array();
9521 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9523 else if ($efname && $efvalue>0) {
9524 /*-- HTMLHEADERS-FOOTERS --*/
9525 if (preg_match('/^html_(.*)$/i',$efname,$n)) {
9526 if (isset($this->pageHTMLfooters
[$n[1]])) { $this
->HTMLFooterE
= $this
->pageHTMLfooters
[$n
[1]]; }
9527 else { $this
->HTMLFooterE
= ''; }
9528 $this->footerDetails
['even'] = array();
9529 $resetHTMLHeadersrequired = true;
9532 /*-- END HTMLHEADERS-FOOTERS --*/
9533 if (isset($this->pagefooters
[$efname])) { $this
->footerDetails
['even'] = $this
->pagefooters
[$efname
]; }
9534 else if ($efname!='_default') { $this
->footerDetails
['even'] = array(); }
9535 $this->HTMLFooterE
= '';
9536 /*-- HTMLHEADERS-FOOTERS --*/
9537 $resetHTMLHeadersrequired = true;
9539 /*-- END HTMLHEADERS-FOOTERS --*/
9541 /*-- HTMLHEADERS-FOOTERS --*/
9542 if ($resetHTMLHeadersrequired) {
9543 $this->SetHTMLHeader($this->HTMLHeader
);
9544 $this->SetHTMLHeader($this->HTMLHeaderE
,'E');
9545 $this->SetHTMLFooter($this->HTMLFooter
);
9546 $this->SetHTMLFooter($this->HTMLFooterE
,'E');
9548 /*-- END HTMLHEADERS-FOOTERS --*/
9551 if (($this->mirrorMargins
) && (($this->page
)%
2==0)) { // EVEN
9552 $this->_setAutoHeaderHeight($this->headerDetails
['even'], $this->HTMLHeaderE
);
9553 $this->_setAutoFooterHeight($this->footerDetails
['even'], $this->HTMLFooterE
);
9555 else { // ODD or DEFAULT
9556 $this->_setAutoHeaderHeight($this->headerDetails
['odd'], $this->HTMLHeader
);
9557 $this->_setAutoFooterHeight($this->footerDetails
['odd'], $this->HTMLFooter
);
9559 // Reset column top margin
9560 $this->y0
= $this->tMargin
;
9562 $this->x
=$this->lMargin
;
9563 $this->y
=$this->tMargin
;
9568 function _setAutoHeaderHeight(&$det, &$htmlh) {
9569 if ($this->setAutoTopMargin
=='pad') {
9570 if ($htmlh['h']) { $h
= $htmlh
['h']; }
9571 else if ($det) { $h
= $this
->_getHFHeight($det
,'H'); }
9573 $this->tMargin
= $this->margin_header +
$h +
$this->orig_tMargin
;
9575 else if ($this->setAutoTopMargin
=='stretch') {
9576 if ($htmlh['h']) { $h
= $htmlh
['h']; }
9577 else if ($det) { $h
= $this
->_getHFHeight($det
,'H'); }
9579 $this->tMargin
= max($this->orig_tMargin
, $this->margin_header +
$h +
$this->autoMarginPadding
);
9584 function _setAutoFooterHeight(&$det, &$htmlf) {
9585 if ($this->setAutoBottomMargin
=='pad') {
9586 if ($htmlf['h']) { $h
= $htmlf
['h']; }
9587 else if ($det) { $h
= $this
->_getHFHeight($det
,'F'); }
9589 $this->bMargin
= $this->margin_footer +
$h +
$this->orig_bMargin
;
9590 $this->PageBreakTrigger
=$this->h
-$this->bMargin
;
9592 else if ($this->setAutoBottomMargin
=='stretch') {
9593 if ($htmlf['h']) { $h
= $htmlf
['h']; }
9594 else if ($det) { $h
= $this
->_getHFHeight($det
,'F'); }
9596 $this->bMargin
= max($this->orig_bMargin
, $this->margin_footer +
$h +
$this->autoMarginPadding
);
9597 $this->PageBreakTrigger
=$this->h
-$this->bMargin
;
9601 function _getHFHeight(&$det,$end) {
9604 foreach(array('L','C','R') AS $pos) {
9605 if (isset($det[$pos]['content']) && $det[$pos]['content']) {
9606 if (isset($det[$pos]['font-size']) && $det[$pos]['font-size']) { $hfsz
= $det
[$pos
]['font-size']; }
9607 else { $hfsz
= $this
->default_font_size
; }
9608 $h = max($h,$hfsz/_MPDFK
);
9611 if ($det['line'] && $end=='H') { $h +
= $h
/_MPDFK
*$this
->header_line_spacing
; }
9612 else if ($det['line'] && $end=='F') { $h +
= $h
/_MPDFK
*$this
->footer_line_spacing
; }
9618 function _endpage() {
9619 /*-- CSS-IMAGE-FLOAT --*/
9620 $this->printfloatbuffer();
9621 /*-- END CSS-IMAGE-FLOAT --*/
9623 if($this->visibility
!='visible')
9624 $this->SetVisibility('visible');
9625 $this->EndLayer(); // mPDF 5.6.01
9626 //End of page contents
9630 function _newobj($obj_id=false,$onlynewobj=false) {
9632 $obj_id = ++
$this->n
;
9634 //Begin a new object
9636 $this->offsets
[$obj_id] = strlen($this->buffer
);
9637 $this->_out($obj_id.' 0 obj');
9638 $this->_current_obj_id
= $obj_id; // for later use with encryption
9642 function _dounderline($x,$y,$txt) {
9643 // Now print line exactly where $y secifies - called from Text() and Cell() - adjust position there
9645 $w =($this->GetStringWidth($txt)*_MPDFK
) +
($this->charspacing
* mb_strlen( $txt, $this->mb_enc
))
9646 +
( $this->ws
* mb_substr_count( $txt, ' ', $this->mb_enc
));
9648 return sprintf('%.3F %.3F m %.3F %.3F l S',$x*_MPDFK
,($this->h
-$y)*_MPDFK
,($x*_MPDFK
)+
$w,($this->h
-$y)*_MPDFK
);
9652 function _imageError($file, $firsttime, $msg) {
9653 // Save re-trying image URL's which have already failed
9654 $this->failedimages
[$file] = true;
9655 if ($firsttime && ($this->showImageErrors
|| $this->debug
)) {
9656 $this->Error("IMAGE Error (".$file."): ".$msg);
9662 function _getImage(&$file, $firsttime=true, $allowvector=true, $orig_srcpath=false) {
9663 // firsttime i.e. whether to add to this->images - use false when calling iteratively
9664 // Image Data passed directly as var:varname
9665 if (preg_match('/var:\s*(.*)/',$file, $v)) {
9666 $data = $this->$v[1];
9670 if (preg_match('/data:image\/(gif|jpeg|png);base64,(.*)/',$file, $v)) {
9672 $data = base64_decode($v[2]);
9677 if ($firsttime && $file && substr($file,0,5)!='data:') { $file
= urlencode_part($file
); }
9678 if ($firsttime && $orig_srcpath && substr($orig_srcpath,0,5)!='data:') { $orig_srcpath
= urlencode_part($orig_srcpath
); }
9681 if ($orig_srcpath && isset($this->images
[$orig_srcpath])) { $file
=$orig_srcpath
; return $this
->images
[$orig_srcpath
]; }
9682 if (isset($this->images
[$file])) { return $this
->images
[$file
]; }
9683 else if ($orig_srcpath && isset($this->formobjects
[$orig_srcpath])) { $file
=$orig_srcpath
; return $this
->formobjects
[$file
]; }
9684 else if (isset($this->formobjects
[$file])) { return $this
->formobjects
[$file
]; }
9685 // Save re-trying image URL's which have already failed
9686 else if ($firsttime && isset($this->failedimages
[$file])) { return $this
->_imageError($file
, $firsttime
, ''); }
9691 if ($orig_srcpath && $this->basepathIsLocal
&& $check = @fopen($orig_srcpath,"rb")) {
9693 $file=$orig_srcpath;
9694 $data = file_get_contents($file);
9695 $type = $this->_imageTypeFromString($data);
9697 if (!$data && $check = @fopen($file,"rb")) {
9699 $data = file_get_contents($file);
9700 $type = $this->_imageTypeFromString($data);
9702 if ((!$data || !$type) && !ini_get('allow_url_fopen') ) { // only worth trying if remote file and !ini_get('allow_url_fopen')
9703 $this->file_get_contents_by_socket($file, $data); // needs full url?? even on local (never needed for local)
9704 if ($data) { $type
= $this
->_imageTypeFromString($data
); }
9706 if ((!$data || !$type) && !ini_get('allow_url_fopen') && function_exists("curl_init")) {
9707 $this->file_get_contents_by_curl($file, $data); // needs full url?? even on local (never needed for local)
9708 if ($data) { $type
= $this
->_imageTypeFromString($data
); }
9712 if (!$data) { return $this
->_imageError($file
, $firsttime
, 'Could not find image file'); }
9713 if (empty($type)) { $type
= $this
->_imageTypeFromString($data
); }
9714 if (($type == 'wmf' || $type == 'svg') && !$allowvector) { return $this
->_imageError($file
, $firsttime
, 'WMF or SVG image file not supported in this context'); }
9717 if ($type == 'svg') {
9718 if (!class_exists('SVG', false)) { include(_MPDF_PATH
.'classes/svg.php'); }
9719 $svg = new SVG($this);
9720 $family=$this->FontFamily
;
9721 $style=$this->FontStyle
;
9722 $size=$this->FontSizePt
;
9723 $info = $svg->ImageSVG($data);
9725 if($family) $this->SetFont($family,$style,$size,false);
9726 if (!$info) { return $this
->_imageError($file
, $firsttime
, 'Error parsing SVG file'); }
9727 $info['type']='svg';
9728 $info['i']=count($this->formobjects
)+
1;
9729 $this->formobjects
[$file]=$info;
9734 if ($type == 'jpeg' || $type == 'jpg') {
9735 $hdr = $this->_jpgHeaderFromString($data);
9736 if (!$hdr) { return $this
->_imageError($file
, $firsttime
, 'Error parsing JPG header'); }
9737 $a = $this->_jpgDataFromHeader($hdr);
9738 $j = strpos($data,'JFIF');
9741 $unitSp=ord(substr($data,($j+
7),1));
9743 $ppUx=$this->_twobytes2int(substr($data,($j+
8),2)); // horizontal pixels per meter, usually set to zero
9744 if ($unitSp == 2) { // = dots per cm (if == 1 set as dpi)
9745 $ppUx=round($ppUx/10 *25.4);
9749 if ($a[2] == 'DeviceCMYK' && (($this->PDFA
&& $this->restrictColorSpace
!=3) || $this->restrictColorSpace
==2)) {
9750 // convert to RGB image
9751 if (!function_exists("gd_info")) { $this
->Error("JPG image may not use CMYK color space (".$file
.")."); }
9752 if ($this->PDFA
&& !$this->PDFAauto
) { $this
->PDFAXwarnings
[] = "JPG image may not use CMYK color space - ".$file
." - (Image converted to RGB. NB This will alter the colour profile of the image.)"; }
9753 $im = @imagecreatefromstring($data);
9755 $tempfile = _MPDF_TEMP_PATH
.'_tempImgPNG'.RAND(1,10000).'.png';
9756 imageinterlace($im, false);
9757 $check = @imagepng($im, $tempfile);
9758 if (!$check) { return $this
->_imageError($file
, $firsttime
, 'Error creating temporary file ('.$tempfile
.') whilst using GD library to parse JPG(CMYK) image'); }
9759 $info = $this->_getImage($tempfile, false);
9760 if (!$info) { return $this
->_imageError($file
, $firsttime
, 'Error parsing temporary file ('.$tempfile
.') created with GD library to parse JPG(CMYK) image'); }
9763 $info['type']='jpg';
9765 $info['i']=count($this->images
)+
1;
9766 $this->images
[$file]=$info;
9770 else {
return $this
->_imageError($file
, $firsttime
, 'Error creating GD image file from JPG(CMYK) image'); }
9772 else if ($a[2] == 'DeviceRGB' && ($this->PDFX
|| $this->restrictColorSpace
==3)) {
9773 // Convert to CMYK image stream - nominally returned as type='png'
9774 $info = $this->_convImage($data, $a[2], 'DeviceCMYK', $a[0], $a[1], $ppUx, false);
9775 if (($this->PDFA
&& !$this->PDFAauto
) || ($this->PDFX
&& !$this->PDFXauto
)) { $this
->PDFAXwarnings
[] = "JPG image may not use RGB color space - ".$file
." - (Image converted to CMYK. NB This will alter the colour profile of the image.)"; }
9777 else if (($a[2] == 'DeviceRGB' || $a[2] == 'DeviceCMYK') && $this->restrictColorSpace
==1) {
9778 // Convert to Grayscale image stream - nominally returned as type='png'
9779 $info = $this->_convImage($data, $a[2], 'DeviceGray', $a[0], $a[1], $ppUx, false);
9782 $info = array('w'=>$a[0],'h'=>$a[1],'cs'=>$a[2],'bpc'=>$a[3],'f'=>'DCTDecode','data'=>$data, 'type'=>'jpg');
9783 if ($ppUx) { $info
['set-dpi'] = $ppUx
; }
9785 if (!$info) { return $this
->_imageError($file
, $firsttime
, 'Error parsing or converting JPG image'); }
9788 $info['i']=count($this->images
)+
1;
9789 $this->images
[$file]=$info;
9795 else if ($type == 'png') {
9797 if(substr($data,0,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
9798 return $this->_imageError($file, $firsttime, 'Error parsing PNG identifier');
9801 if(substr($data,12,4)!='IHDR') {
9802 return $this->_imageError($file, $firsttime, 'Incorrect PNG file (no IHDR block found)');
9805 $w=$this->_fourbytes2int(substr($data,16,4));
9806 $h=$this->_fourbytes2int(substr($data,20,4));
9807 $bpc=ord(substr($data,24,1));
9810 if($bpc>8) { $errpng
= 'not 8-bit depth'; }
9811 $ct=ord(substr($data,25,1));
9812 if($ct==0) { $colspace
='DeviceGray'; }
9813 elseif($ct==2) { $colspace
='DeviceRGB'; }
9814 elseif($ct==3) { $colspace
='Indexed'; }
9815 elseif($ct==4) { $colspace
='DeviceGray'; $errpng
= 'alpha channel'; $pngalpha
= true; }
9816 else { $colspace
='DeviceRGB'; $errpng
= 'alpha channel'; $pngalpha
= true; }
9817 if(ord(substr($data,26,1))!=0) { $errpng
= 'compression method'; }
9818 if(ord(substr($data,27,1))!=0) { $errpng
= 'filter method'; }
9819 if(ord(substr($data,28,1))!=0) { $errpng
= 'interlaced file'; }
9820 $j = strpos($data,'pHYs');
9823 $unitSp=ord(substr($data,($j+
12),1));
9825 $ppUx=$this->_fourbytes2int(substr($data,($j+
4),4)); // horizontal pixels per meter, usually set to zero
9826 $ppUx=round($ppUx/1000 *25.4);
9829 if (($colspace == 'DeviceRGB' || $colspace == 'Indexed') && ($this->PDFX
|| $this->restrictColorSpace
==3)) {
9830 // Convert to CMYK image stream - nominally returned as type='png'
9831 $info = $this->_convImage($data, $colspace, 'DeviceCMYK', $w, $h, $ppUx, $pngalpha);
9832 if (($this->PDFA
&& !$this->PDFAauto
) || ($this->PDFX
&& !$this->PDFXauto
)) { $this
->PDFAXwarnings
[] = "PNG image may not use RGB color space - ".$file
." - (Image converted to CMYK. NB This will alter the colour profile of the image.)"; }
9834 else if (($colspace == 'DeviceRGB' || $colspace == 'Indexed') && $this->restrictColorSpace
==1) {
9835 // Convert to Grayscale image stream - nominally returned as type='png'
9836 $info = $this->_convImage($data, $colspace, 'DeviceGray', $w, $h, $ppUx, $pngalpha);
9838 else if (($this->PDFA
|| $this->PDFX
) && $pngalpha) {
9839 // Remove alpha channel
9840 if ($this->restrictColorSpace
==1) { // Grayscale
9841 $info = $this->_convImage($data, $colspace, 'DeviceGray', $w, $h, $ppUx, $pngalpha);
9843 else if ($this->restrictColorSpace
==3) { // CMYK
9844 $info = $this->_convImage($data, $colspace, 'DeviceCMYK', $w, $h, $ppUx, $pngalpha);
9846 else if ($this->PDFA
) { // RGB
9847 $info = $this->_convImage($data, $colspace, 'DeviceRGB', $w, $h, $ppUx, $pngalpha);
9849 if (($this->PDFA
&& !$this->PDFAauto
) || ($this->PDFX
&& !$this->PDFXauto
)) { $this
->PDFAXwarnings
[] = "Transparency (alpha channel) not permitted in PDFA or PDFX files - ".$file
." - (Image converted to one without transparency.)"; }
9851 else if ($errpng || $pngalpha) {
9852 if (function_exists('gd_info')) { $gd
= gd_info(); }
9853 else {$gd
= array(); }
9854 if (!isset($gd['PNG Support'])) { return $this
->_imageError($file
, $firsttime
, 'GD library required for PNG image ('.$errpng
.')'); }
9855 $im = imagecreatefromstring($data);
9856 if (!$im) { return $this
->_imageError($file
, $firsttime
, 'Error creating GD image from PNG file ('.$errpng
.')'); }
9860 $tempfile = _MPDF_TEMP_PATH
.'_tempImgPNG'.RAND(1,10000).'.png';
9861 // Alpha channel set
9863 if ($this->PDFA
) { $this
->Error("PDFA1-b does not permit images with alpha channel transparency (".$file
.")."); }
9864 $imgalpha = imagecreate($w, $h);
9865 // generate gray scale pallete
9866 for ($c = 0; $c < 256; ++
$c) { ImageColorAllocate($imgalpha
, $c
, $c
, $c
); }
9867 // extract alpha channel
9868 $gammacorr = 2.2; // gamma correction
9869 for ($xpx = 0; $xpx < $w; ++
$xpx) {
9870 for ($ypx = 0; $ypx < $h; ++
$ypx) {
9871 //$colorindex = imagecolorat($im, $xpx, $ypx);
9872 //$col = imagecolorsforindex($im, $colorindex);
9873 //$gamma2 = (pow((((127 - $col['alpha']) * 255 / 127) / 255), $gammacorr) * 255);
9874 $alpha = (imagecolorat($im, $xpx, $ypx) & 0x7F000000) >> 24;
9876 if ($alpha==0) { $gamma
= 255; }
9878 $gamma = (pow((((127 - $alpha) * 255 / 127) / 255), $gammacorr) * 255);
9879 imagesetpixel($imgalpha, $xpx, $ypx, $gamma);
9883 // create temp alpha file
9884 $tempfile_alpha = _MPDF_TEMP_PATH
.'_tempMskPNG'.RAND(1,10000).'.png';
9885 if (!is_writable($tempfile_alpha)) {
9887 $check = @imagepng($imgalpha);
9888 if (!$check) { return $this
->_imageError($file
, $firsttime
, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
9889 imagedestroy($imgalpha);
9890 $this->_tempimg
= ob_get_contents();
9891 $this->_tempimglnk
= 'var:_tempimg';
9893 // extract image without alpha channel
9894 $imgplain = imagecreatetruecolor($w, $h);
9895 imagecopy($imgplain, $im, 0, 0, 0, 0, $w, $h);
9896 // create temp image file
9897 $minfo = $this->_getImage($this->_tempimglnk
, false);
9898 if (!$minfo) { return $this
->_imageError($file
, $firsttime
, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
9900 $check = @imagepng($imgplain);
9901 if (!$check) { return $this
->_imageError($file
, $firsttime
, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
9902 $this->_tempimg
= ob_get_contents();
9903 $this->_tempimglnk
= 'var:_tempimg';
9905 $info = $this->_getImage($this->_tempimglnk
, false);
9906 if (!$info) { return $this
->_imageError($file
, $firsttime
, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
9907 imagedestroy($imgplain);
9908 $imgmask = count($this->images
)+
1;
9909 $minfo['cs'] = 'DeviceGray';
9910 $minfo['i']=$imgmask ;
9911 $this->images
[$tempfile_alpha] = $minfo;
9915 $check = @imagepng($imgalpha, $tempfile_alpha);
9916 if (!$check) { return $this
->_imageError($file
, $firsttime
, 'Failed to create temporary image file ('.$tempfile_alpha
.') parsing PNG image with alpha channel ('.$errpng
.')'); }
9917 imagedestroy($imgalpha);
9919 // extract image without alpha channel
9920 $imgplain = imagecreatetruecolor($w, $h);
9921 imagecopy($imgplain, $im, 0, 0, 0, 0, $w, $h);
9923 // create temp image file
9924 $check = @imagepng($imgplain, $tempfile);
9925 if (!$check) { return $this
->_imageError($file
, $firsttime
, 'Failed to create temporary image file ('.$tempfile
.') parsing PNG image with alpha channel ('.$errpng
.')'); }
9926 imagedestroy($imgplain);
9928 $minfo = $this->_getImage($tempfile_alpha, false);
9929 unlink($tempfile_alpha);
9930 if (!$minfo) { return $this
->_imageError($file
, $firsttime
, 'Error parsing temporary file ('.$tempfile_alpha
.') created with GD library to parse PNG image'); }
9931 $imgmask = count($this->images
)+
1;
9932 $minfo['cs'] = 'DeviceGray';
9933 $minfo['i']=$imgmask ;
9934 $this->images
[$tempfile_alpha] = $minfo;
9935 // embed image, masked with previously embedded mask
9936 $info = $this->_getImage($tempfile, false);
9938 if (!$info) { return $this
->_imageError($file
, $firsttime
, 'Error parsing temporary file ('.$tempfile
.') created with GD library to parse PNG image'); }
9941 $info['masked'] = $imgmask;
9942 if ($ppUx) { $info
['set-dpi'] = $ppUx
; }
9943 $info['type']='png';
9945 $info['i']=count($this->images
)+
1;
9946 $this->images
[$file]=$info;
9950 else { // No alpha/transparency set
9951 imagealphablending($im, false);
9952 imagesavealpha($im, false);
9953 imageinterlace($im, false);
9954 if (!is_writable($tempfile)) {
9956 $check = @imagepng($im);
9957 if (!$check) { return $this
->_imageError($file
, $firsttime
, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
9958 $this->_tempimg
= ob_get_contents();
9959 $this->_tempimglnk
= 'var:_tempimg';
9961 $info = $this->_getImage($this->_tempimglnk
, false);
9962 if (!$info) { return $this
->_imageError($file
, $firsttime
, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
9966 $check = @imagepng($im, $tempfile );
9967 if (!$check) { return $this
->_imageError($file
, $firsttime
, 'Failed to create temporary image file ('.$tempfile
.') parsing PNG image ('.$errpng
.')'); }
9969 $info = $this->_getImage($tempfile, false) ;
9971 if (!$info) { return $this
->_imageError($file
, $firsttime
, 'Error parsing temporary file ('.$tempfile
.') created with GD library to parse PNG image'); }
9973 if ($ppUx) { $info
['set-dpi'] = $ppUx
; }
9974 $info['type']='png';
9976 $info['i']=count($this->images
)+
1;
9977 $this->images
[$file]=$info;
9985 $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
9986 //Scan chunks looking for palette, transparency and image data
9992 $n=$this->_fourbytes2int(substr($data,$p,4)); $p +
= 4;
9993 $type=substr($data,$p,4); $p +
= 4;
9996 $pal=substr($data,$p,$n); $p +
= $n;
9999 elseif($type=='tRNS') {
10000 //Read transparency info
10001 $t=substr($data,$p,$n); $p +
= $n;
10002 if($ct==0) $trns=array(ord(substr($t,1,1)));
10003 elseif($ct==2) $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
10006 $pos=strpos($t,chr(0));
10007 if(is_int($pos)) $trns=array($pos);
10011 elseif($type=='IDAT') {
10012 $pngdata.=substr($data,$p,$n); $p +
= $n;
10015 elseif($type=='IEND') { break; }
10016 else if (preg_match('/[a-zA-Z]{4}/',$type)) { $p +
= $n+
4; }
10017 else {
return $this
->_imageError($file
, $firsttime
, 'Error parsing PNG image data'); }
10020 if (!$pngdata) { return $this
->_imageError($file
, $firsttime
, 'Error parsing PNG image data - no IDAT data found'); }
10021 if($colspace=='Indexed' and empty($pal)) { return $this
->_imageError($file
, $firsttime
, 'Error parsing PNG image data - missing colour palette'); }
10022 $info = array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$pngdata);
10023 $info['type']='png';
10024 if ($ppUx) { $info
['set-dpi'] = $ppUx
; }
10027 if (!$info) { return $this
->_imageError($file
, $firsttime
, 'Error parsing or converting PNG image'); }
10030 $info['i']=count($this->images
)+
1;
10031 $this->images
[$file]=$info;
10037 else if ($type == 'gif') {
10038 if (function_exists('gd_info')) { $gd
= gd_info(); }
10039 else {$gd
= array(); }
10040 if (isset($gd['GIF Read Support']) && $gd['GIF Read Support']) {
10041 $im = @imagecreatefromstring($data);
10043 $tempfile = _MPDF_TEMP_PATH
.'_tempImgPNG'.RAND(1,10000).'.png';
10044 imagealphablending($im, false);
10045 imagesavealpha($im, false);
10046 imageinterlace($im, false);
10047 if (!is_writable($tempfile)) {
10049 $check = @imagepng($im);
10050 if (!$check) { return $this
->_imageError($file
, $firsttime
, 'Error creating temporary image object whilst using GD library to parse GIF image'); }
10051 $this->_tempimg
= ob_get_contents();
10052 $this->_tempimglnk
= 'var:_tempimg';
10054 $info = $this->_getImage($this->_tempimglnk
, false);
10055 if (!$info) { return $this
->_imageError($file
, $firsttime
, 'Error parsing temporary file image object created with GD library to parse GIF image'); }
10059 $check = @imagepng($im, $tempfile);
10060 if (!$check) { return $this
->_imageError($file
, $firsttime
, 'Error creating temporary file ('.$tempfile
.') whilst using GD library to parse GIF image'); }
10061 $info = $this->_getImage($tempfile, false);
10062 if (!$info) { return $this
->_imageError($file
, $firsttime
, 'Error parsing temporary file ('.$tempfile
.') created with GD library to parse GIF image'); }
10066 $info['type']='gif';
10068 $info['i']=count($this->images
)+
1;
10069 $this->images
[$file]=$info;
10073 else {
return $this
->_imageError($file
, $firsttime
, 'Error creating GD image file from GIF image'); }
10076 if (!class_exists('gif', false)) {
10077 include_once(_MPDF_PATH
.'classes/gif.php');
10083 $gif->loadFile($data, 0);
10085 if(isset($gif->m_img
->m_gih
->m_bLocalClr
) && $gif->m_img
->m_gih
->m_bLocalClr
) {
10086 $nColors = $gif->m_img
->m_gih
->m_nTableSize
;
10087 $pal = $gif->m_img
->m_gih
->m_colorTable
->toString();
10088 if($bgColor != -1) {
10089 $bgColor = $gif->m_img
->m_gih
->m_colorTable
->colorIndex($bgColor);
10091 $colspace='Indexed';
10092 } elseif(isset($gif->m_gfh
->m_bGlobalClr
) && $gif->m_gfh
->m_bGlobalClr
) {
10093 $nColors = $gif->m_gfh
->m_nTableSize
;
10094 $pal = $gif->m_gfh
->m_colorTable
->toString();
10095 if((isset($bgColor)) and $bgColor != -1) {
10096 $bgColor = $gif->m_gfh
->m_colorTable
->colorIndex($bgColor);
10098 $colspace='Indexed';
10102 $colspace='DeviceGray';
10107 if(isset($gif->m_img
->m_bTrans
) && $gif->m_img
->m_bTrans
&& ($nColors > 0)) {
10108 $trns=array($gif->m_img
->m_nTrans
);
10110 $gifdata=$gif->m_img
->m_data
;
10111 $w=$gif->m_gfh
->m_nWidth
;
10112 $h=$gif->m_gfh
->m_nHeight
;
10115 if($colspace=='Indexed' and empty($pal)) {
10116 return $this->_imageError($file, $firsttime, 'Error parsing GIF image - missing colour palette');
10118 if ($this->compress
) {
10119 $gifdata=gzcompress($gifdata);
10120 $info = array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'f'=>'FlateDecode', 'pal'=>$pal, 'trns'=>$trns, 'data'=>$gifdata);
10123 $info = array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'pal'=>$pal, 'trns'=>$trns, 'data'=>$gifdata);
10125 $info['type']='gif';
10127 $info['i']=count($this->images
)+
1;
10128 $this->images
[$file]=$info;
10133 /*-- IMAGES-BMP --*/
10134 // BMP (Windows Bitmap)
10135 else if ($type == 'bmp') {
10136 if (!class_exists('bmp', false)) { include(_MPDF_PATH
.'classes/bmp.php'); }
10137 if (empty($this->bmp
)) { $this
->bmp
= new bmp($this
); }
10138 $info = $this->bmp
->_getBMPimage($data, $file);
10139 if (isset($info['error'])) {
10140 return $this->_imageError($file, $firsttime, $info['error']);
10143 $info['i']=count($this->images
)+
1;
10144 $this->images
[$file]=$info;
10148 /*-- END IMAGES-BMP --*/
10149 /*-- IMAGES-WMF --*/
10151 else if ($type == 'wmf') {
10152 if (!class_exists('wmf', false)) { include(_MPDF_PATH
.'classes/wmf.php'); }
10153 if (empty($this->wmf
)) { $this
->wmf
= new wmf($this
); }
10154 $wmfres = $this->wmf
->_getWMFimage($data);
10155 if ($wmfres[0]==0) {
10156 if ($wmfres[1]) { return $this
->_imageError($file
, $firsttime
, $wmfres
[1]); }
10157 return $this->_imageError($file, $firsttime, 'Error parsing WMF image');
10159 $info = array('x'=>$wmfres[2][0],'y'=>$wmfres[2][1],'w'=>$wmfres[3][0],'h'=>$wmfres[3][1],'data'=>$wmfres[1]);
10160 $info['i']=count($this->formobjects
)+
1;
10161 $info['type']='wmf';
10162 $this->formobjects
[$file]=$info;
10165 /*-- END IMAGES-WMF --*/
10167 // UNKNOWN TYPE - try GD imagecreatefromstring
10169 if (function_exists('gd_info')) { $gd
= gd_info(); }
10170 else {$gd
= array(); }
10171 if (isset($gd['PNG Support']) && $gd['PNG Support']) {
10172 $im = @imagecreatefromstring($data);
10173 if (!$im) { return $this
->_imageError($file
, $firsttime
, 'Error parsing image file - image type not recognised, and not supported by GD imagecreate'); }
10174 $tempfile = _MPDF_TEMP_PATH
.'_tempImgPNG'.RAND(1,10000).'.png';
10175 imagealphablending($im, false);
10176 imagesavealpha($im, false);
10177 imageinterlace($im, false);
10178 $check = @imagepng($im, $tempfile);
10179 if (!$check) { return $this
->_imageError($file
, $firsttime
, 'Error creating temporary file ('.$tempfile
.') whilst using GD library to parse unknown image type'); }
10180 $info = $this->_getImage($tempfile, false);
10183 if (!$info) { return $this
->_imageError($file
, $firsttime
, 'Error parsing temporary file ('.$tempfile
.') created with GD library to parse unknown image type'); }
10184 $info['type']='png';
10186 $info['i']=count($this->images
)+
1;
10187 $this->images
[$file]=$info;
10193 return $this->_imageError($file, $firsttime, 'Error parsing image file - image type not recognised');
10195 //==============================================================
10196 function _convImage(&$data, $colspace, $targetcs, $w, $h, $dpi, $mask) {
10197 if ($this->PDFA
|| $this->PDFX
) { $mask
=false; }
10198 $im = @imagecreatefromstring($data);
10204 //Read transparency info
10207 if (!$this->PDFA
&& !$this->PDFX
) {
10208 $p = strpos($data,'tRNS');
10210 $n=$this->_fourbytes2int(substr($data,($p-4),4));
10211 $t = substr($data,($p+
4),$n);
10212 if ($colspace=='DeviceGray') {
10213 $trns=array(ord(substr($t,1,1)));
10214 $trnsrgb = array($trns[0],$trns[0],$trns[0]);
10216 else if ($colspace=='DeviceRGB') {
10217 $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
10219 if ($targetcs=='DeviceCMYK') {
10220 $col = $this->rgb2cmyk(array(3,$trns[0],$trns[1],$trns[2]));
10221 $c1 = intval($col[1]*2.55);
10222 $c2 = intval($col[2]*2.55);
10223 $c3 = intval($col[3]*2.55);
10224 $c4 = intval($col[4]*2.55);
10225 $trns = array($c1,$c2,$c3,$c4);
10227 else if ($targetcs=='DeviceGray') {
10228 $c = intval(($trns[0] * .21) +
($trns[1] * .71) +
($trns[2] * .07));
10233 $pos = strpos($t,chr(0));
10234 if (is_int($pos)) {
10235 $pal = imagecolorsforindex($im, $pos);
10237 $g = $pal['green'];
10239 $trns=array($r,$g,$b); // ****
10241 if ($targetcs=='DeviceCMYK') {
10242 $col = $this->rgb2cmyk(array(3,$r,$g,$b));
10243 $c1 = intval($col[1]*2.55);
10244 $c2 = intval($col[2]*2.55);
10245 $c3 = intval($col[3]*2.55);
10246 $c4 = intval($col[4]*2.55);
10247 $trns = array($c1,$c2,$c3,$c4);
10249 else if ($targetcs=='DeviceGray') {
10250 $c = intval(($r * .21) +
($g * .71) +
($b * .07));
10257 for ($i = 0; $i < $h; $i++
) {
10258 for ($j = 0; $j < $w; $j++
) {
10259 $rgb = imagecolorat($im, $j, $i);
10260 $r = ($rgb >> 16) & 0xFF;
10261 $g = ($rgb >> 8) & 0xFF;
10263 if ($colspace=='Indexed') {
10264 $pal = imagecolorsforindex($im, $rgb);
10266 $g = $pal['green'];
10270 if ($targetcs=='DeviceCMYK') {
10271 $col = $this->rgb2cmyk(array(3,$r,$g,$b));
10272 $c1 = intval($col[1]*2.55);
10273 $c2 = intval($col[2]*2.55);
10274 $c3 = intval($col[3]*2.55);
10275 $c4 = intval($col[4]*2.55);
10277 // original pixel was not set as transparent but processed color does match
10278 if ($trnsrgb!=array($r,$g,$b) && $trns==array($c1,$c2,$c3,$c4)) {
10279 if ($c4==0) { $c4
=1; } else { $c4
--; }
10282 $imgdata .= chr($c1).chr($c2).chr($c3).chr($c4);
10284 else if ($targetcs=='DeviceGray') {
10285 $c = intval(($r * .21) +
($g * .71) +
($b * .07));
10287 // original pixel was not set as transparent but processed color does match
10288 if ($trnsrgb!=array($r,$g,$b) && $trns==array($c)) {
10289 if ($c==0) { $c
=1; } else { $c
--; }
10292 $imgdata .= chr($c);
10294 else if ($targetcs=='DeviceRGB') {
10295 $imgdata .= chr($r).chr($g).chr($b);
10298 $col = imagecolorsforindex($im, $rgb);
10299 $gammacorr = 2.2; // gamma correction
10300 $gamma = intval((pow((((127 - $col['alpha']) * 255 / 127) / 255), $gammacorr) * 255));
10301 $mimgdata .= chr($gamma);
10306 if ($targetcs=='DeviceGray') { $ncols
= 1; }
10307 else if ($targetcs=='DeviceRGB') { $ncols
= 3; }
10308 else if ($targetcs=='DeviceCMYK') { $ncols
= 4; }
10310 $imgdata = gzcompress($imgdata);
10311 $info = array('w'=>$w,'h'=>$h,'cs'=>$targetcs,'bpc'=>8,'f'=>'FlateDecode','data'=>$imgdata, 'type'=>'png',
10312 'parms'=>'/DecodeParms <</Colors '.$ncols.' /BitsPerComponent 8 /Columns '.$w.'>>');
10313 if ($dpi) { $info
['set-dpi'] = $dpi
; }
10315 $mimgdata = gzcompress($mimgdata);
10316 $minfo = array('w'=>$w,'h'=>$h,'cs'=>'DeviceGray','bpc'=>8,'f'=>'FlateDecode','data'=>$mimgdata, 'type'=>'png',
10317 'parms'=>'/DecodeParms <</Colors '.$ncols.' /BitsPerComponent 8 /Columns '.$w.'>>');
10318 if ($dpi) { $minfo
['set-dpi'] = $dpi
; }
10319 $tempfile = '_tempImgPNG'.RAND(1,10000).'.png';
10320 $imgmask = count($this->images
)+
1;
10321 $minfo['i']=$imgmask ;
10322 $this->images
[$tempfile] = $minfo;
10323 $info['masked'] = $imgmask;
10325 else if ($trns) { $info
['trns'] = $trns
; }
10334 function _fourbytes2int($s) {
10335 //Read a 4-byte integer from string
10336 return (ord($s[0])<<24) +
(ord($s[1])<<16) +
(ord($s[2])<<8) +
ord($s[3]);
10339 function _twobytes2int($s) {
10340 //Read a 2-byte integer from string
10341 return (ord(substr($s, 0, 1))<<8) +
ord(substr($s, 1, 1));
10344 function _jpgHeaderFromString(&$data) {
10346 $p +
= $this->_twobytes2int(substr($data, $p, 2)); // Length of initial marker block
10347 $marker = substr($data, $p, 2);
10348 while($marker != chr(255).chr(192) && $marker != chr(255).chr(194) && $p<strlen($data)) {
10349 // Start of frame marker (FFC0) or (FFC2) mPDF 4.4.004
10350 $p +
= ($this->_twobytes2int(substr($data, $p+
2, 2))) +
2; // Length of marker block
10351 $marker = substr($data, $p, 2);
10353 if ($marker != chr(255).chr(192) && $marker != chr(255).chr(194)) { return false; }
10354 return substr($data, $p+
2, 10);
10357 function _jpgDataFromHeader($hdr) {
10358 $bpc = ord(substr($hdr, 2, 1));
10359 if (!$bpc) { $bpc
= 8; }
10360 $h = $this->_twobytes2int(substr($hdr, 3, 2));
10361 $w = $this->_twobytes2int(substr($hdr, 5, 2));
10362 $channels = ord(substr($hdr, 7, 1));
10363 if ($channels==3) { $colspace
='DeviceRGB'; }
10364 elseif($channels==4) { $colspace
='DeviceCMYK'; }
10365 else { $colspace
='DeviceGray'; }
10366 return array($w, $h, $colspace, $bpc);
10369 function file_get_contents_by_curl($url, &$data) {
10371 $ch = curl_init($url);
10372 curl_setopt($ch, CURLOPT_HEADER
, 0);
10373 curl_setopt($ch, CURLOPT_NOBODY
, 0);
10374 curl_setopt ( $ch , CURLOPT_RETURNTRANSFER
, 1 );
10375 curl_setopt ( $ch , CURLOPT_CONNECTTIMEOUT
, $timeout );
10376 $data = curl_exec($ch);
10381 function file_get_contents_by_socket($url, &$data) {
10383 $p = parse_url($url);
10384 $file = $p['path'];
10385 if ($p['query']) { $file
.= '?'.$p
['query']; }
10386 if(!($fh = @fsockopen($p['host'], 80, $errno, $errstr, $timeout))) { return false; }
10388 "GET ".$file." HTTP/1.0 \r\n" .
10389 "Host: ".$p['host']." \r\n" .
10390 "Connection: close\r\n\r\n";
10391 fwrite($fh, $getstring);
10392 // Get rid of HTTP header
10393 $s = fgets($fh, 1024);
10394 if (!$s) { return false; }
10396 while (!feof($fh)) {
10397 $s = fgets($fh, 1024);
10398 if ( $s == "\r\n" ) { break; }
10401 while (!feof($fh)) {
10402 $data .= fgets($fh, 1024);
10407 //==============================================================
10409 function _imageTypeFromString(&$data) {
10411 if (substr($data, 6, 4)== 'JFIF' || substr($data, 6, 4)== 'Exif') {
10414 else if (substr($data, 0, 6)== "GIF87a" || substr($data, 0, 6)== "GIF89a") {
10417 else if (substr($data, 0, 8)== chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
10420 /*-- IMAGES-WMF --*/
10421 else if (substr($data, 0, 4)== chr(215).chr(205).chr(198).chr(154)) {
10424 /*-- END IMAGES-WMF --*/
10425 else if (preg_match('/<svg.*<\/svg>/is',$data)) {
10429 else if (substr($data, 0, 2)== "BM") {
10434 //==============================================================
10436 // Moved outside WMF as also needed for SVG
10437 function _putformobjects() {
10438 reset($this->formobjects
);
10439 while(list($file,$info)=each($this->formobjects
)) {
10441 $this->formobjects
[$file]['n']=$this->n
;
10442 $this->_out('<</Type /XObject');
10443 $this->_out('/Subtype /Form');
10444 $this->_out('/Group '.($this->n+
1).' 0 R');
10445 $this->_out('/BBox ['.$info['x'].' '.$info['y'].' '.($info['w']+
$info['x']).' '.($info['h']+
$info['y']).']');
10446 if ($this->compress
)
10447 $this->_out('/Filter /FlateDecode');
10448 $data=($this->compress
) ? gzcompress($info['data']) : $info['data'];
10449 $this->_out('/Length '.strlen($data).'>>');
10450 $this->_putstream($data);
10451 unset($this->formobjects
[$file]['data']);
10452 $this->_out('endobj');
10453 // Required for SVG transparency (opacity) to work
10455 $this->_out('<</Type /Group');
10456 $this->_out('/S /Transparency');
10458 $this->_out('endobj');
10462 function _freadint($f)
10464 //Read a 4-byte integer from file
10465 $i=ord(fread($f,1))<<24;
10466 $i+
=ord(fread($f,1))<<16;
10467 $i+
=ord(fread($f,1))<<8;
10468 $i+
=ord(fread($f,1));
10472 function _UTF16BEtextstring($s) {
10473 $s = $this->UTF8ToUTF16BE($s, true);
10474 /*-- ENCRYPTION --*/
10475 if ($this->encrypted
) {
10476 $s = $this->_RC4($this->_objectkey($this->_current_obj_id
), $s);
10478 /*-- END ENCRYPTION --*/
10479 return '('. $this->_escape($s).')';
10482 function _textstring($s) {
10483 /*-- ENCRYPTION --*/
10484 if ($this->encrypted
) {
10485 $s = $this->_RC4($this->_objectkey($this->_current_obj_id
), $s);
10487 /*-- END ENCRYPTION --*/
10488 return '('. $this->_escape($s).')';
10492 function _escape($s)
10494 // the chr(13) substitution fixes the Bugs item #1421290.
10495 return strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r'));
10498 function _putstream($s) {
10499 /*-- ENCRYPTION --*/
10500 if ($this->encrypted
) {
10501 $s = $this->_RC4($this->_objectkey($this->_current_obj_id
), $s);
10503 /*-- END ENCRYPTION --*/
10504 $this->_out('stream');
10506 $this->_out('endstream');
10510 function _out($s,$ln=true) {
10511 if($this->state
==2) {
10512 if ($this->bufferoutput
) {
10513 $this->headerbuffer
.= $s."\n";
10516 else if (($this->ColActive
) && !$this->processingHeader
&& !$this->processingFooter
) {
10517 // Captures everything in buffer for columns; Almost everything is sent from fn. Cell() except:
10518 // Images sent from Image() or
10519 // later sent as _out($textto) in printbuffer
10521 if (preg_match('/q \d+\.\d\d+ 0 0 (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ cm \/(I|FO)\d+ Do Q/',$s,$m)) { // Image data
10522 $h = ($m[1]/_MPDFK
);
10523 // Update/overwrite the lowest bottom of printing y value for a column
10524 $this->ColDetails
[$this->CurrCol
]['bottom_margin'] = $this->y+
$h;
10527 else if (preg_match('/\d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ ([\-]{0,1}\d+\.\d\d+) re/',$s,$m) && $this->tableLevel
>0) { // Rect in table
10528 $h = ($m[1]/_MPDFK
);
10529 // Update/overwrite the lowest bottom of printing y value for a column
10530 $this->ColDetails
[$this->CurrCol
]['bottom_margin'] = max($this->ColDetails
[$this->CurrCol
]['bottom_margin'],($this->y+
$h));
10532 /*-- END TABLES --*/
10533 else { // Td Text Set in Cell()
10534 if (isset($this->ColDetails
[$this->CurrCol
]['bottom_margin'])) { $h
= $this
->ColDetails
[$this
->CurrCol
]['bottom_margin'] - $this
->y
; }
10537 if ($h < 0) { $h
= -$h
; }
10538 $this->columnbuffer
[] = array(
10539 's' => $s, // Text string to output
10540 'col' => $this->CurrCol
, // Column when printed
10541 'x' => $this->x
, // x when printed
10542 'y' => $this->y
, // this->y when printed (after column break)
10543 'h' => $h // actual y at bottom when printed = y+h
10546 /*-- END COLUMNS --*/
10548 else if ($this->table_rotate
&& !$this->processingHeader
&& !$this->processingFooter
) {
10549 // Captures eveything in buffer for rotated tables;
10550 $this->tablebuffer
.= $s . "\n";
10552 /*-- END TABLES --*/
10553 else if ($this->kwt
&& !$this->processingHeader
&& !$this->processingFooter
) {
10554 // Captures eveything in buffer for keep-with-table (h1-6);
10555 $this->kwt_buffer
[] = array(
10556 's' => $s, // Text string to output
10557 'x' => $this->x
, // x when printed
10558 'y' => $this->y
, // y when printed
10561 else if (($this->keep_block_together
) && !$this->processingHeader
&& !$this->processingFooter
) {
10562 if (!isset($this->ktBlock
[$this->page
]['bottom_margin'])) {
10563 $this->ktBlock
[$this->page
]['bottom_margin'] = $this->y
;
10566 // Captures eveything in buffer;
10567 if (preg_match('/q \d+\.\d\d+ 0 0 (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ cm \/(I|FO)\d+ Do Q/',$s,$m)) { // Image data
10568 $h = ($m[1]/_MPDFK
);
10569 // Update/overwrite the lowest bottom of printing y value for Keep together block
10570 $this->ktBlock
[$this->page
]['bottom_margin'] = $this->y+
$h;
10572 else { // Td Text Set in Cell()
10573 if (isset($this->ktBlock
[$this->page
]['bottom_margin'])) { $h
= $this
->ktBlock
[$this
->page
]['bottom_margin'] - $this
->y
; }
10576 if ($h < 0) { $h
= -$h
; }
10577 $this->divbuffer
[] = array(
10578 'page' => $this->page
,
10579 's' => $s, // Text string to output
10580 'x' => $this->x
, // x when printed
10581 'y' => $this->y
, // y when printed (after column break)
10582 'h' => $h // actual y at bottom when printed = y+h
10586 $this->pages
[$this->page
] .= $s.($ln == true ? "\n" : '');
10591 $this->buffer
.= $s.($ln == true ? "\n" : '');
10595 /*-- WATERMARK --*/
10597 function watermark( $texte, $angle=45, $fontsize=96, $alpha=0.2 ) {
10598 if ($this->PDFA
|| $this->PDFX
) { $this
->Error('PDFA and PDFX do not permit transparency, so mPDF does not allow Watermarks!'); }
10599 if (!$this->watermark_font
) { $this
->watermark_font
= $this
->default_font
; }
10600 $this->SetFont( $this->watermark_font
, "B", $fontsize, false ); // Don't output
10601 $texte= $this->purify_utf8_text($texte);
10602 if ($this->text_input_as_HTML
) {
10603 $texte= $this->all_entities_to_utf8($texte);
10605 if ($this->usingCoreFont
) { $texte
= mb_convert_encoding($texte
,$this
->mb_enc
,'UTF-8'); }
10607 $this->magic_reverse_dir($texte, true, $this->directionality
); // *RTL*
10608 // Font-specific ligature substitution for Indic fonts
10609 if (isset($this->CurrentFont
['indic']) && $this->CurrentFont
['indic']) $this->ConvertIndic($texte); // *INDIC*
10611 $this->SetAlpha($alpha);
10613 $this->SetTColor($this->ConvertColor(0));
10614 $szfont = $fontsize;
10616 $maxlen = (min($this->w
,$this->h
) ); // sets max length of text as 7/8 width/height of page
10617 while ( $loop == 0 )
10619 $this->SetFont( $this->watermark_font
, "B", $szfont, false ); // Don't output
10620 $offset = ((sin(deg2rad($angle))) * ($szfont/_MPDFK
));
10622 $strlen = $this->GetStringWidth($texte);
10623 if ( $strlen > $maxlen - $offset )
10629 $this->SetFont( $this->watermark_font
, "B", $szfont-0.1
, true, true); // Output The -0.1 is because SetFont above is not written to PDF
10630 // Repeating it will not output anything as mPDF thinks it is set
10631 $adj = ((cos(deg2rad($angle))) * ($strlen/2));
10632 $opp = ((sin(deg2rad($angle))) * ($strlen/2));
10633 $wx = ($this->w
/2) - $adj +
$offset/3;
10634 $wy = ($this->h
/2) +
$opp;
10635 $this->Rotate($angle,$wx,$wy);
10636 $this->Text($wx,$wy,$texte);
10638 $this->SetTColor($this->ConvertColor(0));
10640 $this->SetAlpha(1);
10644 function watermarkImg( $src, $alpha=0.2 ) {
10645 if ($this->PDFA
|| $this->PDFX
) { $this
->Error('PDFA and PDFX do not permit transparency, so mPDF does not allow Watermarks!'); }
10646 if ($this->watermarkImgBehind
) { $this
->watermarkImgAlpha
= $this
->SetAlpha($alpha
, 'Normal', true); }
10647 else { $this
->SetAlpha($alpha
, $this
->watermarkImgAlphaBlend
); }
10648 $this->Image($src,0,0,0,0,'','', true, true, true);
10649 if (!$this->watermarkImgBehind
) { $this
->SetAlpha(1); }
10651 /*-- END WATERMARK --*/
10654 function Rotate($angle,$x=-1,$y=-1)
10660 if($this->angle
!=0)
10662 $this->angle
=$angle;
10669 $cy=($this->h
-$y)*_MPDFK
;
10670 $this->_out(sprintf('q %.5F %.5F %.5F %.5F %.3F %.3F cm 1 0 0 1 %.3F %.3F cm',$c,$s,-$s,$c,$cx,$cy,-$cx,-$cy));
10676 function CircularText($x, $y, $r, $text, $align='top', $fontfamily='', $fontsize=0, $fontstyle='', $kerning=120, $fontwidth=100, $divider) { // mPDF 5.5.23
10677 if (!class_exists('directw', false)) { include(_MPDF_PATH
.'classes/directw.php'); }
10678 if (empty($this->directw
)) { $this
->directw
= new directw($this
); }
10679 $this->directw
->CircularText($x, $y, $r, $text, $align, $fontfamily, $fontsize, $fontstyle, $kerning, $fontwidth, $divider); // mPDF 5.5.23
10684 function RoundedRect($x, $y, $w, $h, $r, $style = '')
10689 elseif($style=='FD' or $style=='DF')
10693 $MyArc = 4/3 * (sqrt(2) - 1);
10694 $this->_out(sprintf('%.3F %.3F m',($x+
$r)*_MPDFK
,($hp-$y)*_MPDFK
));
10697 $this->_out(sprintf('%.3F %.3F l', $xc*_MPDFK
,($hp-$y)*_MPDFK
));
10699 $this->_Arc($xc +
$r*$MyArc, $yc - $r, $xc +
$r, $yc - $r*$MyArc, $xc +
$r, $yc);
10702 $this->_out(sprintf('%.3F %.3F l',($x+
$w)*_MPDFK
,($hp-$yc)*_MPDFK
));
10703 $this->_Arc($xc +
$r, $yc +
$r*$MyArc, $xc +
$r*$MyArc, $yc +
$r, $xc, $yc +
$r);
10706 $this->_out(sprintf('%.3F %.3F l',$xc*_MPDFK
,($hp-($y+
$h))*_MPDFK
));
10707 $this->_Arc($xc - $r*$MyArc, $yc +
$r, $xc - $r, $yc +
$r*$MyArc, $xc - $r, $yc);
10710 $this->_out(sprintf('%.3F %.3F l',($x)*_MPDFK
,($hp-$yc)*_MPDFK
));
10711 $this->_Arc($xc - $r, $yc - $r*$MyArc, $xc - $r*$MyArc, $yc - $r, $xc, $yc - $r);
10715 function _Arc($x1, $y1, $x2, $y2, $x3, $y3)
10718 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', $x1*_MPDFK
, ($h-$y1)*_MPDFK
,
10719 $x2*_MPDFK
, ($h-$y2)*_MPDFK
, $x3*_MPDFK
, ($h-$y3)*_MPDFK
));
10725 //====================================================
10730 function Shaded_box( $text,$font='',$fontstyle='B',$szfont='',$width='70%',$style='DF',$radius=2.5,$fill='#FFFFFF',$color='#000000',$pad=2 ) {
10731 // F (shading - no line),S (line, no shading),DF (both)
10732 if (!class_exists('directw', false)) { include(_MPDF_PATH
.'classes/directw.php'); }
10733 if (empty($this->directw
)) { $this
->directw
= new directw($this
); }
10734 $this->directw
->Shaded_box( $text,$font,$fontstyle,$szfont,$width,$style,$radius,$fill,$color,$pad);
10736 /*-- END DIRECTW --*/
10739 function UTF8StringToArray($str, $addSubset=true) {
10741 $len = strlen($str);
10742 for ($i = 0; $i < $len; $i++
) {
10744 $h = ord($str[$i]);
10747 elseif ( $h >= 0xC2 ) {
10748 if ( ($h <= 0xDF) && ($i < $len -1) )
10749 $uni = ($h & 0x1F) << 6 | (ord($str[++
$i]) & 0x3F);
10750 elseif ( ($h <= 0xEF) && ($i < $len -2) )
10751 $uni = ($h & 0x0F) << 12 | (ord($str[++
$i]) & 0x3F) << 6 | (ord($str[++
$i]) & 0x3F);
10752 elseif ( ($h <= 0xF4) && ($i < $len -3) )
10753 $uni = ($h & 0x0F) << 18 | (ord($str[++
$i]) & 0x3F) << 12 | (ord($str[++
$i]) & 0x3F) << 6 | (ord($str[++
$i]) & 0x3F);
10757 if ($addSubset && isset($this->CurrentFont
['subset'])) {
10758 $this->CurrentFont
['subset'][$uni] = $uni;
10766 //Convert utf-8 string to <HHHHHH> for Font Subsets
10767 function UTF8toSubset($str) {
10769 $str = preg_replace('/'.preg_quote($this->aliasNbPg
,'/').'/', chr(7), $str );
10770 $str = preg_replace('/'.preg_quote($this->aliasNbPgGp
,'/').'/', chr(8), $str );
10771 $unicode = $this->UTF8StringToArray($str);
10772 $orig_fid = $this->CurrentFont
['subsetfontids'][0];
10773 $last_fid = $this->CurrentFont
['subsetfontids'][0];
10774 foreach($unicode as $c) {
10775 if ($c == 7 || $c == 8) {
10776 if ($orig_fid != $last_fid) {
10777 $ret .= '> Tj /F'.$orig_fid.' '.$this->FontSizePt
.' Tf <';
10778 $last_fid = $orig_fid;
10780 if ($c == 7) { $ret
.= $this
->aliasNbPgHex
; }
10781 else { $ret
.= $this
->aliasNbPgGpHex
; }
10784 for ($i=0; $i<99; $i++
) {
10785 // return c as decimal char
10786 $init = array_search($c, $this->CurrentFont
['subsets'][$i]);
10787 if ($init!==false) {
10788 if ($this->CurrentFont
['subsetfontids'][$i] != $last_fid) {
10789 $ret .= '> Tj /F'.$this->CurrentFont
['subsetfontids'][$i].' '.$this->FontSizePt
.' Tf <';
10790 $last_fid = $this->CurrentFont
['subsetfontids'][$i];
10792 $ret .= sprintf("%02s", strtoupper(dechex($init)));
10795 // TrueType embedded SUBSETS
10796 else if (count($this->CurrentFont
['subsets'][$i]) < 255) {
10797 $n = count($this->CurrentFont
['subsets'][$i]);
10798 $this->CurrentFont
['subsets'][$i][$n] = $c;
10799 if ($this->CurrentFont
['subsetfontids'][$i] != $last_fid) {
10800 $ret .= '> Tj /F'.$this->CurrentFont
['subsetfontids'][$i].' '.$this->FontSizePt
.' Tf <';
10801 $last_fid = $this->CurrentFont
['subsetfontids'][$i];
10803 $ret .= sprintf("%02s", strtoupper(dechex($n)));
10806 else if (!isset($this->CurrentFont
['subsets'][($i+
1)])) {
10807 // TrueType embedded SUBSETS
10808 $this->CurrentFont
['subsets'][($i+
1)] = array(0=>0);
10809 $new_fid = count($this->fonts
)+
$this->extraFontSubsets+
1;
10810 $this->CurrentFont
['subsetfontids'][($i+
1)] = $new_fid;
10811 $this->extraFontSubsets++
;
10816 if ($last_fid != $orig_fid) {
10817 $ret .= ' Tj /F'.$orig_fid.' '.$this->FontSizePt
.' Tf <> ';
10823 // Converts UTF-8 strings to UTF16-BE.
10824 function UTF8ToUTF16BE($str, $setbom=true) {
10825 if ($this->checkSIP
&& preg_match("/([\x{20000}-\x{2FFFF}])/u", $str)) {
10826 if (!in_array($this->currentfontfamily
, array('gb','big5','sjis','uhc','gbB','big5B','sjisB','uhcB','gbI','big5I','sjisI','uhcI',
10827 'gbBI','big5BI','sjisBI','uhcBI'))) {
10828 $str = preg_replace("/[\x{20000}-\x{2FFFF}]/u", chr(0), $str);
10831 if ($this->checkSMP
&& preg_match("/([\x{10000}-\x{1FFFF}])/u", $str )) {
10832 $str = preg_replace("/[\x{10000}-\x{1FFFF}]/u", chr(0), $str );
10834 $outstr = ""; // string to be returned
10836 $outstr .= "\xFE\xFF"; // Byte Order Mark (BOM)
10838 $outstr .= mb_convert_encoding($str, 'UTF-16BE', 'UTF-8');
10846 // ====================================================
10847 // ====================================================
10848 /*-- CJK-FONTS --*/
10850 // from class PDF_Chinese CJK EXTENSIONS
10851 function AddCIDFont($family,$style,$name,&$cw,$CMap,$registry,$desc)
10853 $fontkey=strtolower($family).strtoupper($style);
10854 if(isset($this->fonts
[$fontkey]))
10855 $this->Error("Font already added: $family $style");
10856 $i=count($this->fonts)+$this->extraFontSubsets+1;
10857 $name=str_replace(' ','',$name);
10858 if ($family == 'sjis') { $up = -120; } else { $up = -130; }
10859 // ? 'up' and 'ut' do not seem to be referenced anywhere
10860 $this->fonts[$fontkey]=array('i'=>$i,'type'=>'Type0','name'=>$name,'up'=>$up,'ut'=>40,'cw'=>$cw,'CMap'=>$CMap,'registry'=>$registry,'MissingWidth'=>1000,'desc'=>$desc);
10863 function AddCJKFont($family) {
10865 if ($this->PDFA || $this->PDFX) {
10866 $this->Error("Adobe CJK fonts cannot be embedded in
mPDF (required
for PDFA1
-b
and PDFX
/1-a
).");
10868 if ($family == 'big5') { $this->AddBig5Font(); }
10869 else if ($family == 'gb') { $this->AddGBFont(); }
10870 else if ($family == 'sjis') { $this->AddSJISFont(); }
10871 else if ($family == 'uhc') { $this->AddUHCFont(); }
10874 function AddBig5Font()
10876 //Add Big5 font with proportional Latin
10878 $name='MSungStd-Light-Acro';
10879 $cw=$this->Big5_widths;
10880 $CMap='UniCNS-UTF16-H';
10881 $registry=array('ordering'=>'CNS1','supplement'=>4);
10885 'CapHeight' => 880,
10887 'FontBBox' => '[-160 -249 1015 1071]',
10888 'ItalicAngle' => 0,
10891 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10892 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10893 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10894 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10898 function AddGBFont()
10900 //Add GB font with proportional Latin
10902 $name='STSongStd-Light-Acro';
10903 $cw=$this->GB_widths;
10904 $CMap='UniGB-UTF16-H';
10905 $registry=array('ordering'=>'GB1','supplement'=>4);
10909 'CapHeight' => 737,
10911 'FontBBox' => '[-25 -254 1000 880]',
10912 'ItalicAngle' => 0,
10914 'Style' => '<< /Panose <000000000400000000000000> >>',
10916 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10917 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10918 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10919 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10923 function AddSJISFont()
10925 //Add SJIS font with proportional Latin
10927 $name='KozMinPro-Regular-Acro';
10928 $cw=$this->SJIS_widths;
10929 $CMap='UniJIS-UTF16-H';
10930 $registry=array('ordering'=>'Japan1','supplement'=>5);
10934 'CapHeight' => 740,
10936 'FontBBox' => '[-195 -272 1110 1075]',
10937 'ItalicAngle' => 0,
10941 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10942 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10943 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10944 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10947 function AddUHCFont()
10949 //Add UHC font with proportional Latin
10951 $name='HYSMyeongJoStd-Medium-Acro';
10952 $cw=$this->UHC_widths;
10953 $CMap='UniKS-UTF16-H';
10954 $registry=array('ordering'=>'Korea1','supplement'=>2);
10958 'CapHeight' => 720,
10960 'FontBBox' => '[-28 -148 1001 880]',
10961 'ItalicAngle' => 0,
10963 'Style' => '<< /Panose <000000000600000000000000> >>',
10965 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
10966 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
10967 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
10968 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
10971 /*-- END CJK-FONTS --*/
10973 //////////////////////////////////////////////////////////////////////////////
10974 //////////////////////////////////////////////////////////////////////////////
10975 //////////////////////////////////////////////////////////////////////////////
10976 //////////////////////////////////////////////////////////////////////////////
10977 //////////////////////////////////////////////////////////////////////////////
10978 //////////////////////////////////////////////////////////////////////////////
10979 //////////////////////////////////////////////////////////////////////////////
10980 function SetAutoFont($af = AUTOFONT_ALL) {
10981 if ($this->onlyCoreFonts) { return false; }
10982 if (!$af && $af !== 0) { $af = AUTOFONT_ALL; }
10983 $this->autoFontGroups = $af;
10984 if ($this->autoFontGroups ) {
10985 $this->useLang = true;
10990 function SetDefaultFont($font) {
10991 // Disallow embedded fonts to be used as defaults in PDFA
10992 if ($this->PDFA || $this->PDFX) {
10993 if (strtolower($font) == 'ctimes') { $font = 'serif'; }
10994 if (strtolower($font) == 'ccourier') { $font = 'monospace'; }
10995 if (strtolower($font) == 'chelvetica') { $font = 'sans-serif'; }
10997 $font = $this->SetFont($font); // returns substituted font if necessary
10998 $this->default_font = $font;
10999 $this->original_default_font = $font;
11000 if (!$this->watermark_font ) { $this->watermark_font = $font; } // *WATERMARK*
11001 $this->defaultCSS['BODY']['FONT-FAMILY'] = $font;
11002 $this->cssmgr->CSS['BODY']['FONT-FAMILY'] = $font;
11005 function SetDefaultFontSize($fontsize) {
11006 $this->default_font_size = $fontsize;
11007 $this->original_default_font_size = $fontsize;
11008 $this->SetFontSize($fontsize);
11009 $this->defaultCSS['BODY']['FONT-SIZE'] = $fontsize . 'pt';
11010 $this->cssmgr->CSS['BODY']['FONT-SIZE'] = $fontsize . 'pt';
11013 function SetDefaultBodyCSS($prop, $val) {
11015 $this->defaultCSS['BODY'][strtoupper($prop)] = $val;
11016 $this->cssmgr->CSS['BODY'][strtoupper($prop)] = $val;
11021 function SetDirectionality($dir='ltr') {
11023 if (strtolower($dir) == 'rtl') {
11024 if ($this->directionality != 'rtl') {
11025 // Swop L/R Margins so page 1 RTL is an 'even' page
11026 $tmp = $this->DeflMargin;
11027 $this->DeflMargin = $this->DefrMargin;
11028 $this->DefrMargin = $tmp;
11029 $this->orig_lMargin = $this->DeflMargin;
11030 $this->orig_rMargin = $this->DefrMargin;
11032 $this->SetMargins($this->DeflMargin,$this->DefrMargin,$this->tMargin);
11034 $this->directionality = 'rtl';
11035 $this->defaultAlign = 'R';
11036 $this->defaultTableAlign = 'R';
11040 $this->directionality = 'ltr';
11041 $this->defaultAlign = 'L';
11042 $this->defaultTableAlign = 'L';
11044 $this->cssmgr->CSS['BODY']['DIRECTION'] = $this->directionality;
11049 // Added to set line-height-correction
11050 function SetLineHeightCorrection($val) {
11051 if ($val > 0) { $this->default_lineheight_correction = $val; }
11052 else { $this->default_lineheight_correction = 1.2; }
11055 // Set a (fixed) lineheight to an actual value - either to named fontsize(pts) or default
11056 function SetLineHeight($FontPt='',$spacing = '') {
11057 if ($this->shrin_k > 1) { $k = $this->shrin_k; }
11059 if ($spacing > 0) {
11060 if (preg_match('/mm/',$spacing)) {
11061 $this->lineheight = ($spacing + 0.0) / $k; // convert to number
11064 if ($FontPt) { $this->lineheight = (($FontPt/_MPDFK) *$spacing); }
11065 else { $this->lineheight = (($this->FontSizePt/_MPDFK) *$spacing); }
11069 if ($FontPt) { $this->lineheight = (($FontPt/_MPDFK) *$this->normalLineheight); }
11070 else { $this->lineheight = (($this->FontSizePt/_MPDFK) *$this->normalLineheight); }
11074 function _computeLineheight($lh, $fs='') {
11075 if ($this->shrin_k > 1) { $k = $this->shrin_k; }
11077 if (!$fs) { $fs = $this->FontSize; }
11078 if (preg_match('/mm/',$lh)) {
11079 return (($lh + 0.0) / $k); // convert to number
11081 else if ($lh > 0) {
11082 return ($fs * $lh);
11084 else if (isset($this->normalLineheight)) { return ($fs * $this->normalLineheight); }
11085 else return ($fs * $this->default_lineheight_correction);
11089 function SetBasePath($str='') {
11090 if ( isset($_SERVER['HTTP_HOST']) ) { $host = $_SERVER['HTTP_HOST']; }
11091 else if ( isset($_SERVER['SERVER_NAME']) ) { $host = $_SERVER['SERVER_NAME']; }
11092 else { $host = ''; }
11094 if ($_SERVER['SCRIPT_NAME']) { $currentPath = dirname($_SERVER['SCRIPT_NAME']); }
11095 else { $currentPath = dirname($_SERVER['PHP_SELF']); }
11096 $currentPath = str_replace("\\
","/",$currentPath);
11097 if ($currentPath == '/') { $currentPath = ''; }
11098 if ($host) { $currpath = 'http://' . $host . $currentPath .'/'; }
11099 else { $currpath = ''; }
11100 $this->basepath = $currpath;
11101 $this->basepathIsLocal = true;
11104 $str = preg_replace('/\?.*/','',$str);
11105 if (!preg_match('/(http|https|ftp):\/\/.*\//i',$str)) { $str .= '/'; }
11106 $str .= 'xxx'; // in case $str ends in / e.g. http://www.bbc.co.uk/
11107 $this->basepath = dirname($str) . "/"; // returns e.g. e.g. http://www.google.com/dir1/dir2/dir3/
11108 $this->basepath = str_replace("\\
","/",$this->basepath); //If on Windows
11109 $tr = parse_url($this->basepath);
11110 if (isset($tr['host']) && ($tr['host'] == $host)) { $this->basepathIsLocal = true; }
11111 else { $this->basepathIsLocal = false; }
11115 function GetFullPath(&$path,$basepath='') {
11116 // When parsing CSS need to pass temporary basepath - so links are relative to current stylesheet
11117 if (!$basepath) { $basepath = $this->basepath; }
11119 $path = str_replace("\\
","/",$path); //If on Windows
11120 $path = preg_replace('/^\/\//','http://',$path); // mPDF 5.6.27
11121 $regexp = '|^./|'; // Inadvertently corrects "./path
/etc
" and "//www.domain.com/etc"
11122 $path = preg_replace($regexp,'',$path);
11125 if(substr($path,0,1) == '#') { return; }
11126 if (stristr($path,"mailto:") !== false) { return; }
11127 if (strpos($path,"../") !== false ) { //It is a Relative Link
11128 $backtrackamount = substr_count($path,"../");
11129 $maxbacktrack = substr_count($basepath,"/") - 3; // mPDF 5.6.18
11130 $filepath = str_replace("../",'',$path);
11132 //If it is an invalid relative link, then make it go to directory root
11133 if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
11134 //Backtrack some directories
11135 for( $i = 0 ; $i < $backtrackamount +
1 ; $i++
) $path = substr( $path, 0 , strrpos($path,"/") );
11136 $path = $path . "/" . $filepath; //Make it an absolute path
11138 else if( strpos($path,":/") === false || strpos($path,":/") > 10) { //It is a Local Link
11139 if (substr($path,0,1) == "/") {
11140 $tr = parse_url($basepath);
11141 $root = $tr['scheme'].'://'.$tr['host'];
11142 $path = $root . $path;
11144 else { $path
= $basepath
. $path
; }
11146 //Do nothing if it is an Absolute Link
11150 // Used for external CSS files
11151 function _get_file($path) {
11152 // If local file try using local path (? quicker, but also allowed even if allow_url_fopen false)
11154 $contents = @file_get_contents($path);
11155 if ($contents) { return $contents
; }
11156 if ($this->basepathIsLocal
) {
11157 $tr = parse_url($path);
11158 $lp=getenv("SCRIPT_NAME");
11160 $ap=str_replace("\\","/",$ap);
11161 $docroot=substr($ap,0,strpos($ap,$lp));
11162 // WriteHTML parses all paths to full URLs; may be local file name
11163 if ($tr['scheme'] && $tr['host'] && $_SERVER["DOCUMENT_ROOT"] ) {
11164 $localpath = $_SERVER["DOCUMENT_ROOT"] . $tr['path'];
11166 // DOCUMENT_ROOT is not returned on IIS
11167 else if ($docroot) {
11168 $localpath = $docroot . $tr['path'];
11170 else { $localpath
= $path
; }
11171 $contents = @file_get_contents($localpath);
11173 // if not use full URL
11174 else if (!$contents && !ini_get('allow_url_fopen') && function_exists("curl_init")) {
11175 $ch = curl_init($path);
11176 curl_setopt($ch, CURLOPT_HEADER
, 0);
11177 curl_setopt ( $ch , CURLOPT_RETURNTRANSFER
, 1 );
11178 $contents = curl_exec($ch);
11185 function docPageNum($num = 0, $extras = false) {
11186 if ($num < 1) { $num
= $this
->page
; }
11187 $type = '1'; // set default decimal
11192 foreach($this->PageNumSubstitutions
AS $psarr) {
11193 if ($num >= $psarr['from']) {
11194 if ($psarr['reset']) {
11195 if ($psarr['reset']>1) { $offset
= $psarr
['reset']-1; }
11196 $ppgno = $num - $psarr['from'] +
1 +
$offset;
11197 $lastreset = $psarr['from'];
11199 if ($psarr['type']) { $type
= $psarr
['type']; }
11200 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress
= 1; }
11201 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress
= 0; }
11204 if ($suppress) { return ''; }
11206 foreach($this->pgsIns
AS $k=>$v) {
11207 if ($k>$lastreset && $k<$num) {
11211 if ($type=='A') { $ppgno
= $this
->dec2alpha($ppgno
,true); }
11212 else if ($type=='a') { $ppgno
= $this
->dec2alpha($ppgno
,false);}
11213 else if ($type=='I') { $ppgno
= $this
->dec2roman($ppgno
,true); }
11214 else if ($type=='i') { $ppgno
= $this
->dec2roman($ppgno
,false); }
11215 if ($extras) { $ppgno
= $this
->pagenumPrefix
. $ppgno
. $this
->pagenumSuffix
; }
11220 function docPageSettings($num = 0) {
11221 // Returns current type (numberstyle), suppression state for this page number;
11222 // reset is only returned if set for this page number
11223 if ($num < 1) { $num
= $this
->page
; }
11224 $type = '1'; // set default decimal
11229 foreach($this->PageNumSubstitutions
AS $psarr) {
11230 if ($num >= $psarr['from']) {
11231 if ($psarr['reset']) {
11232 if ($psarr['reset']>1) { $offset
= $psarr
['reset']-1; }
11233 $ppgno = $num - $psarr['from'] +
1 +
$offset;
11235 if ($psarr['type']) { $type
= $psarr
['type']; }
11236 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress
= 1; }
11237 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress
= 0; }
11239 if ($num == $psarr['from']) { $reset
= $psarr
['reset']; }
11241 if ($suppress) { $suppress
= 'on'; }
11242 else { $suppress
= 'off'; }
11243 return array($type, $suppress, $reset);
11246 function docPageNumTotal($num = 0, $extras = false) {
11247 if ($num < 1) { $num
= $this
->page
; }
11248 $type = '1'; // set default decimal
11250 $ppgend = count($this->pages
)+
1;
11253 foreach($this->PageNumSubstitutions
AS $psarr) {
11254 if ($num >= $psarr['from']) {
11255 if ($psarr['reset']) {
11256 if ($psarr['reset']>1) { $offset
= $psarr
['reset']-1; }
11257 $ppgstart = $psarr['from'] +
$offset;
11258 $ppgend = count($this->pages
)+
1 +
$offset;
11260 if ($psarr['type']) { $type
= $psarr
['type']; }
11261 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress
= 1; }
11262 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress
= 0; }
11264 if ($num < $psarr['from']) {
11265 if ($psarr['reset']) {
11266 $ppgend = $psarr['from'] +
$offset;
11271 if ($suppress) { return ''; }
11272 $ppgno = $ppgend-$ppgstart+
$offset;
11275 foreach($this->pgsIns
AS $k => $v) {
11276 if ($k>$ppgstart && $k<$ppgend) {
11281 if ($extras) { $ppgno
= $this
->nbpgPrefix
. $ppgno
. $this
->nbpgSuffix
; }
11285 function RestartDocTemplate() {
11286 $this->docTemplateStart
= $this->page
;
11292 function Header($content='') {
11294 $this->cMarginL
= 0;
11295 $this->cMarginR
= 0;
11298 /*-- HTMLHEADERS-FOOTERS --*/
11299 if (($this->mirrorMargins
&& ($this->page%
2==0) && $this->HTMLHeaderE
) || ($this->mirrorMargins
&& ($this->page%
2==1) && $this->HTMLHeader
) || (!$this->mirrorMargins
&& $this->HTMLHeader
)) {
11300 $this->writeHTMLHeaders();
11303 /*-- END HTMLHEADERS-FOOTERS --*/
11304 $this->processingHeader
=true;
11305 $h = $this->headerDetails
;
11308 if ($this->forcePortraitHeaders
&& $this->CurOrientation
=='L' && $this->CurOrientation
!=$this->DefOrientation
) {
11309 $this->_out(sprintf('q 0 -1 1 0 0 %.3F cm ',($this->h
*_MPDFK
)));
11310 $yadj = $this->w
- $this->h
;
11311 $headerpgwidth = $this->h
- $this->orig_lMargin
- $this->orig_rMargin
;
11312 if (($this->mirrorMargins
) && (($this->page
)%
2==0)) { // EVEN
11313 $headerlmargin = $this->orig_rMargin
;
11316 $headerlmargin = $this->orig_lMargin
;
11321 $headerpgwidth = $this->pgwidth
;
11322 $headerlmargin = $this->lMargin
;
11325 $this->y
= $this->margin_header
- $yadj ;
11326 $this->SetTColor($this->ConvertColor(0));
11327 $this->SUP
= false;
11328 $this->SUB
= false;
11329 $this->bullet
= false;
11331 // only show pagenumber if numbering on
11332 $pgno = $this->docPageNum($this->page
, true);
11334 if (($this->mirrorMargins
) && (($this->page
)%
2==0)) { // EVEN
11337 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS = DEFAULT
11340 $maxfontheight = 0;
11341 foreach(array('L','C','R') AS $pos) {
11342 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
11343 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz
= $h
[$side
][$pos
]['font-size']; }
11344 else { $hfsz
= $this
->default_font_size
; }
11345 $maxfontheight = max($maxfontheight,$hfsz);
11348 // LEFT-CENTER-RIGHT
11349 foreach(array('L','C','R') AS $pos) {
11350 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
11351 $hd = str_replace('{PAGENO}',$pgno,$h[$side][$pos]['content']);
11352 $hd = str_replace($this->aliasNbPgGp
,$this->nbpgPrefix
.$this->aliasNbPgGp
.$this->nbpgSuffix
,$hd);
11353 $hd = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$hd);
11354 if (isset($h[$side][$pos]['font-family']) && $h[$side][$pos]['font-family']) { $hff
= $h
[$side
][$pos
]['font-family']; }
11355 else { $hff
= $this
->original_default_font
; }
11356 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz
= $h
[$side
][$pos
]['font-size']; }
11357 else { $hfsz
= $this
->original_default_font_size
; } // pts
11358 $maxfontheight = max($maxfontheight,$hfsz);
11360 if (isset($h[$side][$pos]['font-style']) && $h[$side][$pos]['font-style']) {
11361 $hfst = $h[$side][$pos]['font-style'];
11363 if (isset($h[$side][$pos]['color']) && $h[$side][$pos]['color']) {
11364 $hfcol = $h[$side][$pos]['color'];
11365 $cor = $this->ConvertColor($hfcol);
11366 if ($cor) { $this
->SetTColor($cor
); }
11368 else { $hfcol
= ''; }
11369 $this->SetFont($hff,$hfst,$hfsz,true,true);
11370 $this->x
= $headerlmargin ;
11371 $this->y
= $this->margin_header
- $yadj ;
11373 $hd = $this->purify_utf8_text($hd);
11374 if ($this->text_input_as_HTML
) {
11375 $hd = $this->all_entities_to_utf8($hd);
11377 // CONVERT CODEPAGE
11378 if ($this->usingCoreFont
) { $hd
= mb_convert_encoding($hd
,$this
->mb_enc
,'UTF-8'); }
11379 // DIRECTIONALITY RTL
11380 $this->magic_reverse_dir($hd, true, $this->directionality
); // *RTL*
11381 // Font-specific ligature substitution for Indic fonts
11382 if (isset($this->CurrentFont
['indic']) && $this->CurrentFont
['indic']) $this->ConvertIndic($hd); // *INDIC*
11385 if ($this->directionality
== 'rtl') {
11386 if ($pos == 'L') { $align
= 'R'; }
11387 else if ($pos == 'R') { $align
= 'L'; }
11390 if ($pos!='L' && (strpos($hd,$this->aliasNbPg
)!==false || strpos($hd,$this->aliasNbPgGp
)!==false)) {
11391 if (strpos($hd,$this->aliasNbPgGp
)!==false) { $type
= 'nbpggp'; } else { $type
= 'nbpg'; }
11392 $this->_out('{mpdfheader'.$type.' '.$pos.' ff='.$hff.' fs='.$hfst.' fz='.$hfsz.'}');
11393 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK
,$hd,0,0,$align,0,'',0,0,0,'M');
11397 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK
,$hd,0,0,$align,0,'',0,0,0,'M');
11399 if ($hfcol) { $this
->SetTColor($this
->ConvertColor(0)); }
11402 //Return Font to normal
11403 $this->SetFont($this->default_font
,'',$this->original_default_font_size
);
11405 if (isset($h[$side]['line']) && $h[$side]['line']) {
11406 $this->SetLineWidth(0.1);
11407 $this->SetDColor($this->ConvertColor(0));
11408 $this->Line($headerlmargin , $this->margin_header +
($maxfontheight*(1+
$this->header_line_spacing
)/_MPDFK
) - $yadj , $headerlmargin +
$headerpgwidth, $this->margin_header +
($maxfontheight*(1+
$this->header_line_spacing
)/_MPDFK
) - $yadj );
11410 if ($this->forcePortraitHeaders
&& $this->CurOrientation
=='L' && $this->CurOrientation
!=$this->DefOrientation
) {
11414 $this->SetY($this->tMargin
);
11415 if ($this->ColActive
) { $this
->pgwidth
= $this
->ColWidth
; } // *COLUMNS*
11417 $this->processingHeader
=false;
11423 function TableHeaderFooter($content='',$tablestartpage='',$tablestartcolumn ='',$horf = 'H',$level, $firstSpread=true, $finalSpread=true) {
11424 if(($horf=='H' || $horf=='F') && !empty($content) && !empty($content[0])) { // mPDF 5.6.61
11425 $table = &$this->table
[1][1];
11426 // Advance down page by half width of top border
11428 if ($horf=='H') { // Only if header
11429 if ($table['borders_separate']) { $adv
= $table
['border_spacing_V']/2 + $table
['border_details']['T']['w'] + $table
['padding']['T']; }
11430 else { $adv
= $table
['max_cell_border_width']['T'] /2 ; }
11432 if ($this->table_rotate
) {
11433 $this->y +
= ($adv);
11436 $this->DivLn($adv,$this->blklvl
,true);
11441 if ($horf=='F') { // Table Footer
11442 $firstrow = count($table['cells']) - $table['footernrows'];
11443 $lastrow = count($table['cells']) - 1;
11445 else { // Table Header
11447 $lastrow = $table['headernrows'] - 1;
11450 $topy = $content[$firstrow][0]['y']-$this->y
;
11452 for ($i=$firstrow ; $i<=$lastrow; $i++
) {
11457 // If outside columns, this is done in PaintDivBB
11458 if ($this->ColActive
) {
11459 //OUTER FILL BGCOLOR of DIVS
11460 if ($this->blklvl
> 0) {
11461 $firstblockfill = $this->GetFirstBlockFill();
11462 if ($firstblockfill && $this->blklvl
>= $firstblockfill) {
11463 $divh = $content[$i][0]['h'];
11465 $this->DivLn($divh,-3,false);
11466 // Reset current block fill
11467 $bcor = $this->blk
[$this->blklvl
]['bgcolorarray'];
11468 $this->SetFColor($bcor);
11473 /*-- END COLUMNS --*/
11476 foreach($content[$i] as $tablehf) {
11478 $y = $tablehf['y'] - $topy;
11480 //Set some cell values
11481 $x = $tablehf['x'];
11482 if (($this->mirrorMargins
) && ($tablestartpage == 'ODD') && (($this->page
)%
2==0)) { // EVEN
11483 $x = $x +
$this->MarginCorrection
;
11485 else if (($this->mirrorMargins
) && ($tablestartpage == 'EVEN') && (($this->page
)%
2==1)) { // ODD
11486 $x = $x +
$this->MarginCorrection
;
11489 // Added to correct for Columns
11490 if ($this->ColActive
) {
11491 if ($this->directionality
== 'rtl') { // *RTL*
11492 $x -= ($this->CurrCol
- $tablestartcolumn) * ($this->ColWidth+
$this->ColGap
); // *RTL*
11495 $x +
= ($this->CurrCol
- $tablestartcolumn) * ($this->ColWidth+
$this->ColGap
);
11498 /*-- END COLUMNS --*/
11500 if ($colctr==1) { $x0
= $x
; }
11503 if ($this->iterationCounter
) {
11504 foreach($tablehf['textbuffer'] AS $k=>$t) {
11505 if (!is_array($t[0]) && preg_match('/{iteration ([a-zA-Z0-9_]+)}/',$t[0], $m)) { // mPDF 5.5.06
11506 $vname = '__'.$m[1].'_';
11507 if (!isset($this->$vname)) { $this
->$vname
= 1; }
11508 else { $this
->$vname++
; }
11509 $tablehf['textbuffer'][$k][0] = preg_replace('/{iteration '.$m[1].'}/', $this->$vname, $tablehf['textbuffer'][$k][0]);
11515 $w = $tablehf['w'];
11516 $h = $tablehf['h'];
11517 $va = $tablehf['va'];
11518 $R = $tablehf['R'];
11519 $mih = $tablehf['mih'];
11520 $border = $tablehf['border'];
11521 $border_details = $tablehf['border_details'];
11522 $padding = $tablehf['padding'];
11523 $this->tabletheadjustfinished
= true;
11525 $textbuffer = $tablehf['textbuffer'];
11527 $align = $tablehf['a'];
11529 $this->divalign
=$align;
11532 if ($this->ColActive
) {
11533 if ($table['borders_separate']) {
11534 $tablefill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
11536 $color = $this->ConvertColor($tablefill);
11538 $xadj = ($table['border_spacing_H']/2);
11539 $yadj = ($table['border_spacing_V']/2);
11540 $wadj = $table['border_spacing_H'];
11541 $hadj = $table['border_spacing_V'];
11542 if ($i == $firstrow && $horf=='H') { // Top
11543 $yadj +
= $table['padding']['T'] +
$table['border_details']['T']['w'] ;
11544 $hadj +
= $table['padding']['T'] +
$table['border_details']['T']['w'] ;
11546 if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i+
$tablehf['rowspan']) == ($lastrow+
1)) || (!isset($tablehf['rowspan']) && ($i+
1) == ($lastrow+
1))) && $horf=='F') { // Bottom
11547 $hadj +
= $table['padding']['B'] +
$table['border_details']['B']['w'] ;
11549 if ($colctr == 1) { // Left
11550 $xadj +
= $table['padding']['L'] +
$table['border_details']['L']['w'] ;
11551 $wadj +
= $table['padding']['L'] +
$table['border_details']['L']['w'] ;
11553 if ($colctr == count($content[$i]) ) { // Right
11554 $wadj +
= $table['padding']['R'] +
$table['border_details']['R']['w'] ;
11556 $this->SetFColor($color);
11557 $this->Rect($x - $xadj, $y - $yadj, $w +
$wadj, $h +
$hadj, 'F');
11563 if ($table['empty_cells']!='hide' || !empty($textbuffer) || !$table['borders_separate']) { $paintcell
= true; }
11564 else { $paintcell
= false; }
11567 if ($R && INTVAL($R) > 0 && isset($va) && $va!='B') { $va
='B';}
11569 if (!isset($va) || empty($va) || $va=='M') $this->y +
= ($h-$mih)/2;
11570 elseif (isset($va) && $va=='B') $this->y +
= $h-$mih;
11573 //TABLE ROW OR CELL FILL BGCOLOR
11575 if (isset($tablehf['bgcolor']) && $tablehf['bgcolor'] && $tablehf['bgcolor']!='transparent') {
11576 $fill = $tablehf['bgcolor'];
11579 else if (isset($content[$i][0]['trbgcolor']) && $content[$i][0]['trbgcolor'] && $content[$i][0]['trbgcolor']!='transparent') { // Row color
11580 $fill = $content[$i][0]['trbgcolor'];
11583 if ($fill && $paintcell) {
11584 $color = $this->ConvertColor($fill);
11586 if ($table['borders_separate']) {
11587 if ($this->ColActive
) {
11588 $this->SetFColor($color);
11589 $this->Rect($x+
($table['border_spacing_H']/2), $y+
($table['border_spacing_V']/2), $w- $table['border_spacing_H'], $h- $table['border_spacing_V'], 'F');
11592 $this->tableBackgrounds
[$level*9+
$leveladj][] = array('gradient'=>false, 'x'=>($x +
($table['border_spacing_H']/2)), 'y'=>($y +
($table['border_spacing_V']/2)), 'w'=>($w - $table['border_spacing_H']), 'h'=>($h - $table['border_spacing_V']), 'col'=>$color);
11596 if ($this->ColActive
) {
11597 $this->SetFColor($color);
11598 $this->Rect($x, $y, $w, $h, 'F');
11601 $this->tableBackgrounds
[$level*9+
$leveladj][] = array('gradient'=>false, 'x'=>$x, 'y'=>$y, 'w'=>$w, 'h'=>$h, 'col'=>$color);
11608 /*-- BACKGROUNDS --*/
11609 if (isset($tablehf['gradient']) && $tablehf['gradient'] && $paintcell){
11610 $g = $this->grad
->parseBackgroundGradient($tablehf['gradient']);
11612 if ($table['borders_separate']) {
11613 $px = $x+
($table['border_spacing_H']/2);
11614 $py = $y+
($table['border_spacing_V']/2);
11615 $pw = $w- $table['border_spacing_H'];
11616 $ph = $h- $table['border_spacing_V'];
11624 if ($this->ColActive
) {
11625 $this->grad
->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
11628 $this->tableBackgrounds
[$level*9+
7][] = array('gradient'=>true, 'x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
11633 if (isset($tablehf['background-image']) && $paintcell){
11634 if ($tablehf['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $tablehf['background-image']['gradient'] )) {
11635 $g = $this->grad
->parseMozGradient( $tablehf['background-image']['gradient'] );
11637 if ($table['borders_separate']) {
11638 $px = $x+
($table['border_spacing_H']/2);
11639 $py = $y+
($table['border_spacing_V']/2);
11640 $pw = $w- $table['border_spacing_H'];
11641 $ph = $h- $table['border_spacing_V'];
11649 if ($this->ColActive
) {
11650 $this->grad
->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
11653 $this->tableBackgrounds
[$level*9+
7][] = array('gradient'=>true, 'x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
11657 else if ($tablehf['background-image']['image_id']) { // Background pattern
11658 $n = count($this->patterns
)+
1;
11659 if ($table['borders_separate']) {
11660 $px = $x+
($table['border_spacing_H']/2);
11661 $py = $y+
($table['border_spacing_V']/2);
11662 $pw = $w- $table['border_spacing_H'];
11663 $ph = $h- $table['border_spacing_V'];
11671 if ($this->ColActive
) {
11672 list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($tablehf['background-image']['orig_w'], $tablehf['background-image']['orig_h'], $pw, $ph, $tablehf['background-image']['resize'], $tablehf['background-image']['x_repeat'] , $tablehf['background-image']['y_repeat']);
11673 $this->patterns
[$n] = array('x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'pgh'=>$this->h
, 'image_id'=>$tablehf['background-image']['image_id'], 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$tablehf['background-image']['x_pos'] , 'y_pos'=>$tablehf['background-image']['y_pos'] , 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'itype'=>$tablehf['background-image']['itype']);
11674 if ($tablehf['background-image']['opacity']>0 && $tablehf['background-image']['opacity']<1) { $opac
= $this
->SetAlpha($tablehf
['background-image']['opacity'],'Normal',true); }
11675 else { $opac
= ''; }
11676 $this->_out(sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $px*_MPDFK
, ($this->h
-$py)*_MPDFK
, $pw*_MPDFK
, -$ph*_MPDFK
));
11679 $this->tableBackgrounds
[$level*9+
8][] = array('x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'image_id'=>$tablehf['background-image']['image_id'], 'orig_w'=>$tablehf['background-image']['orig_w'], 'orig_h'=>$tablehf['background-image']['orig_h'], 'x_pos'=>$tablehf['background-image']['x_pos'], 'y_pos'=>$tablehf['background-image']['y_pos'], 'x_repeat'=>$tablehf['background-image']['x_repeat'], 'y_repeat'=>$tablehf['background-image']['y_repeat'], 'clippath'=>'', 'resize'=>$tablehf['background-image']['resize'], 'opacity'=>$tablehf['background-image']['opacity'], 'itype'=>$tablehf['background-image']['itype']);
11683 /*-- END BACKGROUNDS --*/
11686 if ($table['borders_separate'] && $paintcell && $border) {
11687 $this->_tableRect($x+
($table['border_spacing_H']/2)+
($border_details['L']['w'] /2), $y+
($table['border_spacing_V']/2)+
($border_details['T']['w'] /2), $w-$table['border_spacing_H']-($border_details['L']['w'] /2)-($border_details['R']['w'] /2), $h- $table['border_spacing_V']-($border_details['T']['w'] /2)-($border_details['B']['w']/2), $border, $border_details, false, $table['borders_separate']);
11689 else if ($paintcell && $border) {
11690 $this->_tableRect($x, $y, $w, $h, $border, $border_details, true, $table['borders_separate']); // true causes buffer
11693 //Print cell content
11694 //$this->divheight = $this->table_lineheight*$this->lineheight;
11695 if (!empty($textbuffer)) {
11696 if ($horf=='F' && preg_match('/{colsum([0-9]*)[_]*}/', $textbuffer[0][0], $m)) {
11697 $rep = sprintf("%01.".intval($m[1])."f", $this->colsums
[$colctr-1]);
11698 $textbuffer[0][0] = preg_replace('/{colsum[0-9_]*}/', $rep ,$textbuffer[0][0]);
11702 $cellPtSize = $textbuffer[0][11] / $this->shrin_k
;
11703 if (!$cellPtSize) { $cellPtSize
= $this
->default_font_size
; }
11704 $cellFontHeight = ($cellPtSize/_MPDFK
);
11707 $angle = INTVAL($R);
11708 // Only allow 45 - 90 degrees (when bottom-aligned) or -90
11709 if ($angle > 90) { $angle
= 90; }
11710 else if ($angle > 0 && (isset($va) && $va!='B')) { $angle
= 90; }
11711 else if ($angle > 0 && $angle <45) { $angle
= 45; }
11712 else if ($angle < 0) { $angle
= -90; }
11713 $offset = ((sin(deg2rad($angle))) * 0.37 * $cellFontHeight);
11714 if (isset($align) && $align =='R') {
11715 $this->x +
= ($w) +
($offset) - ($cellFontHeight/3) - ($padding['R'] +
$border_details['R']['w']);
11717 else if (!isset($align ) || $align =='C') {
11718 $this->x +
= ($w/2) +
($offset);
11721 $this->x +
= ($offset) +
($cellFontHeight/3)+
($padding['L'] +
$border_details['L']['w']);
11724 foreach($tablehf['textbuffer'] AS $t) { $str
.= $t
[0].' '; }
11727 if (!isset($va) || $va=='M') {
11728 $this->y
-= ($h-$mih)/2; //Undo what was added earlier VERTICAL ALIGN
11729 if ($angle > 0) { $this
->y +
= (($h
-$mih
)/2)+
($padding
['T'] + $border_details
['T']['w']) +
($mih
-($padding
['T'] + $border_details
['T']['w']+$border_details
['B']['w']+$padding
['B'])); }
11730 else if ($angle < 0) { $this
->y +
= (($h
-$mih
)/2)+
($padding
['T'] + $border_details
['T']['w']); }
11732 else if (isset($va) && $va=='B') {
11733 $this->y
-= $h-$mih; //Undo what was added earlier VERTICAL ALIGN
11734 if ($angle > 0) { $this
->y +
= $h
-($border_details
['B']['w']+$padding
['B']); }
11735 else if ($angle < 0) { $this
->y +
= $h
-$mih+
($padding
['T'] + $border_details
['T']['w']); }
11737 else if (isset($va) && $va=='T') {
11738 if ($angle > 0) { $this
->y +
= $mih
-($border_details
['B']['w']+$padding
['B']); }
11739 else if ($angle < 0) { $this
->y +
= ($padding
['T'] + $border_details
['T']['w']); }
11742 $this->Rotate($angle,$this->x
,$this->y
);
11743 $s_fs = $this->FontSizePt
;
11744 $s_f = $this->FontFamily
;
11745 $s_st = $this->FontStyle
;
11746 if (!empty($textbuffer[0][3])) { //Font Color
11747 $cor = $textbuffer[0][3];
11748 $this->SetTColor($cor);
11750 $s_str = $this->strike
;
11751 $this->strike
= $textbuffer[0][8]; //Strikethrough
11752 $this->SetFont($textbuffer[0][4],$textbuffer[0][2],$cellPtSize,true,true);
11753 $this->Text($this->x
,$this->y
,$str);
11755 $this->SetFont($s_f,$s_st,$s_fs,true,true);
11756 $this->SetTColor(0);
11757 $this->strike
= $s_str;
11762 if ($table['borders_separate']) { // NB twice border width
11763 $xadj = $border_details['L']['w'] +
$padding['L'] +
($table['border_spacing_H']/2);
11764 $wadj = $border_details['L']['w'] +
$border_details['R']['w'] +
$padding['L'] +
$padding['R'] +
$table['border_spacing_H'];
11765 $yadj = $border_details['T']['w'] +
$padding['T'] +
($table['border_spacing_H']/2);
11768 $xadj = $border_details['L']['w']/2 +
$padding['L'];
11769 $wadj = ($border_details['L']['w'] +
$border_details['R']['w'])/2 +
$padding['L'] +
$padding['R'];
11770 $yadj = $border_details['T']['w']/2 +
$padding['T'];
11773 $this->divwidth
=$w-($wadj);
11776 $this->printbuffer($textbuffer,'',true);
11780 $textbuffer = array();
11782 /*-- BACKGROUNDS --*/
11783 if (!$this->ColActive
) {
11784 if (isset($content[$i][0]['trgradients']) && ($colctr==1 || $table['borders_separate'])) {
11785 $g = $this->grad
->parseBackgroundGradient($content[$i][0]['trgradients']);
11790 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
11791 if ($table['borders_separate']) {
11792 $gw -= ($table['padding']['L'] +
$table['border_details']['L']['w'] +
$table['padding']['R'] +
$table['border_details']['R']['w'] +
$table['border_spacing_H']);
11794 $clx = $x+
($table['border_spacing_H']/2);
11795 $cly = $y+
($table['border_spacing_V']/2);
11796 $clw = $w- $table['border_spacing_H'];
11797 $clh = $h- $table['border_spacing_V'];
11798 // Set clipping path
11799 $s = ' q 0 w '; // Line width=0
11800 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // start point TL before the arc
11801 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK
, ($this->h
-($cly+
$clh))*_MPDFK
); // line to BL
11802 $s .= sprintf('%.3F %.3F l ', ($clx+
$clw)*_MPDFK
, ($this->h
-($cly+
$clh))*_MPDFK
); // line to BR
11803 $s .= sprintf('%.3F %.3F l ', ($clx+
$clw)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // line to TR
11804 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // line to TL
11805 $s .= ' W n '; // Ends path no-op & Sets the clipping path
11806 $this->tableBackgrounds
[$level*9+
4][] = array('gradient'=>true, 'x'=>$gx +
($table['border_spacing_H']/2), 'y'=>$gy +
($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s);
11809 $this->tableBackgrounds
[$level*9+
4][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
11814 if (isset($content[$i][0]['trbackground-images']) && ($colctr==1 || $table['borders_separate'])) {
11815 if ($content[$i][0]['trbackground-images']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $content[$i][0]['trbackground-images']['gradient'] )) {
11816 $g = $this->grad
->parseMozGradient( $content[$i][0]['trbackground-images']['gradient'] );
11821 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
11822 if ($table['borders_separate']) {
11823 $gw -= ($table['padding']['L'] +
$table['border_details']['L']['w'] +
$table['padding']['R'] +
$table['border_details']['R']['w'] +
$table['border_spacing_H']);
11825 $clx = $x+
($table['border_spacing_H']/2);
11826 $cly = $y+
($table['border_spacing_V']/2);
11827 $clw = $w- $table['border_spacing_H'];
11828 $clh = $h- $table['border_spacing_V'];
11829 // Set clipping path
11830 $s = ' q 0 w '; // Line width=0
11831 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // start point TL before the arc
11832 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK
, ($this->h
-($cly+
$clh))*_MPDFK
); // line to BL
11833 $s .= sprintf('%.3F %.3F l ', ($clx+
$clw)*_MPDFK
, ($this->h
-($cly+
$clh))*_MPDFK
); // line to BR
11834 $s .= sprintf('%.3F %.3F l ', ($clx+
$clw)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // line to TR
11835 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // line to TL
11836 $s .= ' W n '; // Ends path no-op & Sets the clipping path
11837 $this->tableBackgrounds
[$level*9+
4][] = array('gradient'=>true, 'x'=>$gx +
($table['border_spacing_H']/2), 'y'=>$gy +
($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s);
11840 $this->tableBackgrounds
[$level*9+
4][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
11845 $image_id = $content[$i][0]['trbackground-images']['image_id'];
11846 $orig_w = $content[$i][0]['trbackground-images']['orig_w'];
11847 $orig_h = $content[$i][0]['trbackground-images']['orig_h'];
11848 $x_pos = $content[$i][0]['trbackground-images']['x_pos'];
11849 $y_pos = $content[$i][0]['trbackground-images']['y_pos'];
11850 $x_repeat = $content[$i][0]['trbackground-images']['x_repeat'];
11851 $y_repeat = $content[$i][0]['trbackground-images']['y_repeat'];
11852 $resize = $content[$i][0]['trbackground-images']['resize'];
11853 $opacity = $content[$i][0]['trbackground-images']['opacity'];
11854 $itype = $content[$i][0]['trbackground-images']['itype'];
11860 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
11861 if ($table['borders_separate']) {
11862 $gw -= ($table['padding']['L'] +
$table['border_details']['L']['w'] +
$table['padding']['R'] +
$table['border_details']['R']['w'] +
$table['border_spacing_H']);
11864 $clx = $x+
($table['border_spacing_H']/2);
11865 $cly = $y+
($table['border_spacing_V']/2);
11866 $clw = $w- $table['border_spacing_H'];
11867 $clh = $h- $table['border_spacing_V'];
11868 // Set clipping path
11869 $s = ' q 0 w '; // Line width=0
11870 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // start point TL before the arc
11871 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK
, ($this->h
-($cly+
$clh))*_MPDFK
); // line to BL
11872 $s .= sprintf('%.3F %.3F l ', ($clx+
$clw)*_MPDFK
, ($this->h
-($cly+
$clh))*_MPDFK
); // line to BR
11873 $s .= sprintf('%.3F %.3F l ', ($clx+
$clw)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // line to TR
11874 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // line to TL
11875 $s .= ' W n '; // Ends path no-op & Sets the clipping path
11876 $this->tableBackgrounds
[$level*9+
5][] = array('x'=>$gx +
($table['border_spacing_H']/2), 'y'=>$gy +
($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>$s, 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
11879 $this->tableBackgrounds
[$level*9+
5][] = array('x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>'', 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
11884 /*-- END BACKGROUNDS --*/
11886 // TABLE BORDER - if separate OR collapsed and only table border
11887 if (($table['borders_separate'] || ($this->simpleTables
&& !$table['simple']['border'])) && $table['border']) {
11888 $halfspaceL = $table['padding']['L'] +
($table['border_spacing_H']/2);
11889 $halfspaceR = $table['padding']['R'] +
($table['border_spacing_H']/2);
11890 $halfspaceT = $table['padding']['T'] +
($table['border_spacing_V']/2);
11891 $halfspaceB = $table['padding']['B'] +
($table['border_spacing_V']/2);
11898 if ($i == $firstrow && $horf=='H') { // Top
11899 $tby -= $halfspaceT +
($table['border_details']['T']['w']/2);
11900 $tbh +
= $halfspaceT +
($table['border_details']['T']['w']/2);
11901 $this->setBorder($tab_bord , _BORDER_TOP
);
11904 if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i+
$tablehf['rowspan']) == ($lastrow+
1))) && $horf=='F') { // Bottom
11905 $tbh +
= $halfspaceB +
($table['border_details']['B']['w']/2);
11906 $this->setBorder($tab_bord , _BORDER_BOTTOM
);
11909 if ($colctr == 1 && $firstSpread) { // Left
11910 $tbx -= $halfspaceL +
($table['border_details']['L']['w']/2);
11911 $tbw +
= $halfspaceL +
($table['border_details']['L']['w']/2);
11912 $this->setBorder($tab_bord , _BORDER_LEFT
);
11915 if ($colctr == count($content[$i]) && $finalSpread) { // Right
11916 $tbw +
= $halfspaceR +
($table['border_details']['R']['w']/2);
11917 $this->setBorder($tab_bord , _BORDER_RIGHT
);
11920 $this->_tableRect($tbx, $tby, $tbw, $tbh, $tab_bord , $table['border_details'], false, $table['borders_separate'], 'table', $corner, $table['border_spacing_V'], $table['border_spacing_H'] );
11924 }// end column $content
11925 $this->y
= $y +
$h; //Update y coordinate
11928 $this->colsums
= array();
11931 /*-- END TABLES --*/
11933 /*-- HTMLHEADERS-FOOTERS --*/
11934 function SetHTMLHeader($header='',$OE='',$write=false) {
11937 if (is_array($header) && isset($header['html']) && $header['html']) {
11938 $Hhtml = $header['html'];
11939 if ($this->setAutoTopMargin
) {
11940 if (isset($header['h'])) { $height
= $header
['h']; }
11941 else { $height
= $this
->_gethtmlheight($Hhtml
); }
11944 else if (!is_array($header) && $header) {
11946 if ($this->setAutoTopMargin
) { $height
= $this
->_gethtmlheight($Hhtml
); }
11948 else { $Hhtml
= ''; }
11950 if ($OE != 'E') { $OE
= 'O'; }
11954 $this->HTMLHeaderE
['html'] = $Hhtml;
11955 $this->HTMLHeaderE
['h'] = $height;
11957 else { $this
->HTMLHeaderE
= ''; }
11962 $this->HTMLHeader
['html'] = $Hhtml;
11963 $this->HTMLHeader
['h'] = $height;
11965 else { $this
->HTMLHeader
= ''; }
11967 if (!$this->mirrorMargins
&& $OE == 'E') { return; }
11968 if ($Hhtml=='') { return; }
11970 $this->headerDetails
['even'] = array(); // override and clear any other non-HTML header/footer
11973 $this->headerDetails
['odd'] = array(); // override and clear any non-HTML other header/footer
11976 if ($this->setAutoTopMargin
=='pad') {
11977 $this->tMargin
= $this->margin_header +
$height +
$this->orig_tMargin
;
11978 if (isset($this->saveHTMLHeader
[$this->page
][$OE]['mt'])) { $this
->saveHTMLHeader
[$this
->page
][$OE
]['mt'] = $this
->tMargin
; }
11980 else if ($this->setAutoTopMargin
=='stretch') {
11981 $this->tMargin
= max($this->orig_tMargin
, $this->margin_header +
$height +
$this->autoMarginPadding
);
11982 if (isset($this->saveHTMLHeader
[$this->page
][$OE]['mt'])) { $this
->saveHTMLHeader
[$this
->page
][$OE
]['mt'] = $this
->tMargin
; }
11984 if ($write && $this->state
!=0 && (($this->mirrorMargins
&& $OE == 'E' && ($this->page
)%
2==0) || ($this->mirrorMargins
&& $OE != 'E' && ($this->page
)%
2==1) || !$this->mirrorMargins
)) { $this
->writeHTMLHeaders(); }
11987 function SetHTMLFooter($footer='',$OE='') {
11990 if (is_array($footer) && isset($footer['html']) && $footer['html']) {
11991 $Fhtml = $footer['html'];
11992 if ($this->setAutoBottomMargin
) {
11993 if (isset($footer['h'])) { $height
= $footer
['h']; }
11994 else { $height
= $this
->_gethtmlheight($Fhtml
); }
11997 else if (!is_array($footer) && $footer) {
11999 if ($this->setAutoBottomMargin
) { $height
= $this
->_gethtmlheight($Fhtml
); }
12001 else { $Fhtml
= ''; }
12003 if ($OE != 'E') { $OE
= 'O'; }
12007 $this->HTMLFooterE
['html'] = $Fhtml;
12008 $this->HTMLFooterE
['h'] = $height;
12010 else { $this
->HTMLFooterE
= ''; }
12015 $this->HTMLFooter
['html'] = $Fhtml;
12016 $this->HTMLFooter
['h'] = $height;
12018 else { $this
->HTMLFooter
= ''; }
12020 if (!$this->mirrorMargins
&& $OE == 'E') { return; }
12021 if ($Fhtml=='') { return false; }
12023 $this->footerDetails
['even'] = array(); // override and clear any other header/footer
12026 $this->footerDetails
['odd'] = array(); // override and clear any other header/footer
12029 if ($this->setAutoBottomMargin
=='pad') {
12030 $this->bMargin
= $this->margin_footer +
$height +
$this->orig_bMargin
;
12031 $this->PageBreakTrigger
=$this->h
-$this->bMargin
;
12032 if (isset($this->saveHTMLHeader
[$this->page
][$OE]['mb'])) { $this
->saveHTMLHeader
[$this
->page
][$OE
]['mb'] = $this
->bMargin
; }
12034 else if ($this->setAutoBottomMargin
=='stretch') {
12035 $this->bMargin
= max($this->orig_bMargin
, $this->margin_footer +
$height +
$this->autoMarginPadding
);
12036 $this->PageBreakTrigger
=$this->h
-$this->bMargin
;
12037 if (isset($this->saveHTMLHeader
[$this->page
][$OE]['mb'])) { $this
->saveHTMLHeader
[$this
->page
][$OE
]['mb'] = $this
->bMargin
; }
12042 function _getHtmlHeight($html) {
12043 $save_state = $this->state
;
12044 if($this->state
==0) {
12045 $this->AddPage($this->CurOrientation
);
12049 $this->pageoutput
[$this->page
] = array();
12050 $save_x = $this->x
;
12051 $save_y = $this->y
;
12052 $this->x
= $this->lMargin
;
12053 $this->y
= $this->margin_header
;
12054 $html = str_replace('{PAGENO}',$this->pagenumPrefix
.$this->docPageNum($this->page
).$this->pagenumSuffix
,$html);
12055 $html = str_replace($this->aliasNbPgGp
,$this->nbpgPrefix
.$this->docPageNumTotal($this->page
).$this->nbpgSuffix
,$html );
12056 $html = str_replace($this->aliasNbPg
,$this->page
,$html );
12057 $html = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$html );
12058 $this->HTMLheaderPageLinks
= array();
12059 $this->HTMLheaderPageAnnots
= array();
12060 $this->HTMLheaderPageForms
= array();
12061 $savepb = $this->pageBackgrounds
;
12062 $this->writingHTMLheader
= true;
12063 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
12064 $this->writingHTMLheader
= false;
12065 $h = ($this->y
- $this->margin_header
);
12067 $this->pageoutput
[$this->page
] = array();
12068 $this->headerbuffer
= '';
12069 $this->pageBackgrounds
= $savepb;
12070 $this->x
= $save_x;
12071 $this->y
= $save_y;
12072 $this->state
= $save_state;
12073 if($save_state==0) {
12074 unset($this->pages
[1]);
12081 // Called internally from Header
12082 function writeHTMLHeaders() {
12084 if ($this->mirrorMargins
&& ($this->page
)%
2==0) { $OE
= 'E'; } // EVEN
12085 else { $OE
= 'O'; }
12087 $this->saveHTMLHeader
[$this->page
][$OE]['html'] = $this->HTMLHeaderE
['html'] ;
12090 $this->saveHTMLHeader
[$this->page
][$OE]['html'] = $this->HTMLHeader
['html'] ;
12092 if ($this->forcePortraitHeaders
&& $this->CurOrientation
=='L' && $this->CurOrientation
!=$this->DefOrientation
) {
12093 $this->saveHTMLHeader
[$this->page
][$OE]['rotate'] = true;
12094 $this->saveHTMLHeader
[$this->page
][$OE]['ml'] = $this->tMargin
;
12095 $this->saveHTMLHeader
[$this->page
][$OE]['mr'] = $this->bMargin
;
12096 $this->saveHTMLHeader
[$this->page
][$OE]['mh'] = $this->margin_header
;
12097 $this->saveHTMLHeader
[$this->page
][$OE]['mf'] = $this->margin_footer
;
12098 $this->saveHTMLHeader
[$this->page
][$OE]['pw'] = $this->h
;
12099 $this->saveHTMLHeader
[$this->page
][$OE]['ph'] = $this->w
;
12102 $this->saveHTMLHeader
[$this->page
][$OE]['ml'] = $this->lMargin
;
12103 $this->saveHTMLHeader
[$this->page
][$OE]['mr'] = $this->rMargin
;
12104 $this->saveHTMLHeader
[$this->page
][$OE]['mh'] = $this->margin_header
;
12105 $this->saveHTMLHeader
[$this->page
][$OE]['mf'] = $this->margin_footer
;
12106 $this->saveHTMLHeader
[$this->page
][$OE]['pw'] = $this->w
;
12107 $this->saveHTMLHeader
[$this->page
][$OE]['ph'] = $this->h
;
12111 function writeHTMLFooters() {
12113 if ($this->mirrorMargins
&& ($this->page
)%
2==0) { $OE
= 'E'; } // EVEN
12114 else { $OE
= 'O'; }
12116 $this->saveHTMLFooter
[$this->page
][$OE]['html'] = $this->HTMLFooterE
['html'] ;
12119 $this->saveHTMLFooter
[$this->page
][$OE]['html'] = $this->HTMLFooter
['html'] ;
12121 if ($this->forcePortraitHeaders
&& $this->CurOrientation
=='L' && $this->CurOrientation
!=$this->DefOrientation
) {
12122 $this->saveHTMLFooter
[$this->page
][$OE]['rotate'] = true;
12123 $this->saveHTMLFooter
[$this->page
][$OE]['ml'] = $this->tMargin
;
12124 $this->saveHTMLFooter
[$this->page
][$OE]['mr'] = $this->bMargin
;
12125 $this->saveHTMLFooter
[$this->page
][$OE]['mt'] = $this->rMargin
;
12126 $this->saveHTMLFooter
[$this->page
][$OE]['mb'] = $this->lMargin
;
12127 $this->saveHTMLFooter
[$this->page
][$OE]['mh'] = $this->margin_header
;
12128 $this->saveHTMLFooter
[$this->page
][$OE]['mf'] = $this->margin_footer
;
12129 $this->saveHTMLFooter
[$this->page
][$OE]['pw'] = $this->h
;
12130 $this->saveHTMLFooter
[$this->page
][$OE]['ph'] = $this->w
;
12133 $this->saveHTMLFooter
[$this->page
][$OE]['ml'] = $this->lMargin
;
12134 $this->saveHTMLFooter
[$this->page
][$OE]['mr'] = $this->rMargin
;
12135 $this->saveHTMLFooter
[$this->page
][$OE]['mt'] = $this->tMargin
;
12136 $this->saveHTMLFooter
[$this->page
][$OE]['mb'] = $this->bMargin
;
12137 $this->saveHTMLFooter
[$this->page
][$OE]['mh'] = $this->margin_header
;
12138 $this->saveHTMLFooter
[$this->page
][$OE]['mf'] = $this->margin_footer
;
12139 $this->saveHTMLFooter
[$this->page
][$OE]['pw'] = $this->w
;
12140 $this->saveHTMLFooter
[$this->page
][$OE]['ph'] = $this->h
;
12143 /*-- END HTMLHEADERS-FOOTERS --*/
12145 function DefHeaderByName($name,$arr) {
12146 if (!$name) { $name
= '_default'; }
12147 $this->pageheaders
[$name] = $arr;
12150 function DefFooterByName($name,$arr) {
12151 if (!$name) { $name
= '_default'; }
12152 $this->pagefooters
[$name] = $arr;
12155 function SetHeaderByName($name,$side='O',$write=false) {
12156 if (!$name) { $name
= '_default'; }
12157 if ($side=='E') { $this
->headerDetails
['even'] = $this
->pageheaders
[$name
]; }
12158 else { $this
->headerDetails
['odd'] = $this
->pageheaders
[$name
]; }
12159 if ($write) { $this
->Header(); }
12162 function SetFooterByName($name,$side='O') {
12163 if (!$name) { $name
= '_default'; }
12164 if ($side=='E') { $this
->footerDetails
['even'] = $this
->pagefooters
[$name
]; }
12165 else { $this
->footerDetails
['odd'] = $this
->pagefooters
[$name
]; }
12168 /*-- HTMLHEADERS-FOOTERS --*/
12169 function DefHTMLHeaderByName($name,$html) {
12170 if (!$name) { $name
= '_default'; }
12172 $this->pageHTMLheaders
[$name]['html'] = $html;
12173 $this->pageHTMLheaders
[$name]['h'] = $this->_gethtmlheight($html);
12176 function DefHTMLFooterByName($name,$html) {
12177 if (!$name) { $name
= '_default'; }
12179 $this->pageHTMLfooters
[$name]['html'] = $html;
12180 $this->pageHTMLfooters
[$name]['h'] = $this->_gethtmlheight($html);
12183 function SetHTMLHeaderByName($name,$side='O',$write=false) {
12184 if (!$name) { $name
= '_default'; }
12185 $this->SetHTMLHeader($this->pageHTMLheaders
[$name],$side,$write);
12188 function SetHTMLFooterByName($name,$side='O') {
12189 if (!$name) { $name
= '_default'; }
12190 $this->SetHTMLFooter($this->pageHTMLfooters
[$name],$side,$write);
12192 /*-- END HTMLHEADERS-FOOTERS --*/
12195 function SetHeader($Harray=array(),$side='',$write=false) {
12196 if (is_string($Harray)) {
12197 if (strlen($Harray)==0) {
12198 if ($side=='O') { $this
->headerDetails
['odd'] = array(); }
12199 else if ($side=='E') { $this
->headerDetails
['even'] = array(); }
12200 else { $this
->headerDetails
= array(); }
12202 else if (strpos($Harray,'|') || strpos($Harray,'|')===0) {
12203 $hdet = explode('|',$Harray);
12204 $this->headerDetails
= array (
12206 'L' => array ('content' => $hdet[0], 'font-size' => $this->defaultheaderfontsize
, 'font-style' => $this->defaultheaderfontstyle
),
12207 'C' => array ('content' => $hdet[1], 'font-size' => $this->defaultheaderfontsize
, 'font-style' => $this->defaultheaderfontstyle
),
12208 'R' => array ('content' => $hdet[2], 'font-size' => $this->defaultheaderfontsize
, 'font-style' => $this->defaultheaderfontstyle
),
12209 'line' => $this->defaultheaderline
,
12212 'R' => array ('content' => $hdet[0], 'font-size' => $this->defaultheaderfontsize
, 'font-style' => $this->defaultheaderfontstyle
),
12213 'C' => array ('content' => $hdet[1], 'font-size' => $this->defaultheaderfontsize
, 'font-style' => $this->defaultheaderfontstyle
),
12214 'L' => array ('content' => $hdet[2], 'font-size' => $this->defaultheaderfontsize
, 'font-style' => $this->defaultheaderfontstyle
),
12215 'line' => $this->defaultheaderline
,
12220 $this->headerDetails
= array (
12222 'R' => array ('content' => $Harray, 'font-size' => $this->defaultheaderfontsize
, 'font-style' => $this->defaultheaderfontstyle
),
12223 'line' => $this->defaultheaderline
,
12226 'L' => array ('content' => $Harray, 'font-size' => $this->defaultheaderfontsize
, 'font-style' => $this->defaultheaderfontstyle
),
12227 'line' => $this->defaultheaderline
,
12232 else if (is_array($Harray)) {
12233 if ($side=='O') { $this
->headerDetails
['odd'] = $Harray
; }
12234 else if ($side=='E') { $this
->headerDetails
['even'] = $Harray
; }
12235 else { $this
->headerDetails
= $Harray
; }
12237 /*-- HTMLHEADERS-FOOTERS --*/
12238 // Overwrite any HTML Header previously set
12239 if ($side=='E') { $this
->SetHTMLHeader('','E'); }
12240 else if ($side=='O') { $this
->SetHTMLHeader(''); }
12242 $this->SetHTMLHeader('');
12243 $this->SetHTMLHeader('','E');
12245 /*-- END HTMLHEADERS-FOOTERS --*/
12248 $save_y = $this->y
;
12250 $this->SetY($save_y) ;
12257 function SetFooter($Farray=array(),$side='') {
12258 if (is_string($Farray)) {
12259 if (strlen($Farray)==0) {
12260 if ($side=='O') { $this
->footerDetails
['odd'] = array(); }
12261 else if ($side=='E') { $this
->footerDetails
['even'] = array(); }
12262 else { $this
->footerDetails
= array(); }
12264 else if (strpos($Farray,'|') || strpos($Farray,'|')===0) {
12265 $fdet = explode('|',$Farray);
12266 $this->footerDetails
= array (
12268 'L' => array ('content' => $fdet[0], 'font-size' => $this->defaultfooterfontsize
, 'font-style' => $this->defaultfooterfontstyle
),
12269 'C' => array ('content' => $fdet[1], 'font-size' => $this->defaultfooterfontsize
, 'font-style' => $this->defaultfooterfontstyle
),
12270 'R' => array ('content' => $fdet[2], 'font-size' => $this->defaultfooterfontsize
, 'font-style' => $this->defaultfooterfontstyle
),
12271 'line' => $this->defaultfooterline
,
12274 'R' => array ('content' => $fdet[0], 'font-size' => $this->defaultfooterfontsize
, 'font-style' => $this->defaultfooterfontstyle
),
12275 'C' => array ('content' => $fdet[1], 'font-size' => $this->defaultfooterfontsize
, 'font-style' => $this->defaultfooterfontstyle
),
12276 'L' => array ('content' => $fdet[2], 'font-size' => $this->defaultfooterfontsize
, 'font-style' => $this->defaultfooterfontstyle
),
12277 'line' => $this->defaultfooterline
,
12282 $this->footerDetails
= array (
12284 'R' => array ('content' => $Farray, 'font-size' => $this->defaultfooterfontsize
, 'font-style' => $this->defaultfooterfontstyle
),
12285 'line' => $this->defaultfooterline
,
12288 'L' => array ('content' => $Farray, 'font-size' => $this->defaultfooterfontsize
, 'font-style' => $this->defaultfooterfontstyle
),
12289 'line' => $this->defaultfooterline
,
12294 else if (is_array($Farray)) {
12295 if ($side=='O') { $this
->footerDetails
['odd'] = $Farray
; }
12296 else if ($side=='E') { $this
->footerDetails
['even'] = $Farray
; }
12297 else { $this
->footerDetails
= $Farray
; }
12299 /*-- HTMLHEADERS-FOOTERS --*/
12300 // Overwrite any HTML Footer previously set
12301 if ($side=='E') { $this
->SetHTMLFooter('','E'); }
12302 else if ($side=='O') { $this
->SetHTMLFooter(''); }
12304 $this->SetHTMLFooter('');
12305 $this->SetHTMLFooter('','E');
12307 /*-- END HTMLHEADERS-FOOTERS --*/
12310 /*-- WATERMARK --*/
12311 function setUnvalidatedText($txt='', $alpha=-1) {
12312 if ($alpha>=0) $this->watermarkTextAlpha
= $alpha;
12313 $this->watermarkText
= $txt;
12315 function SetWatermarkText($txt='', $alpha=-1) {
12316 if ($alpha>=0) $this->watermarkTextAlpha
= $alpha;
12317 $this->watermarkText
= $txt;
12320 function SetWatermarkImage($src, $alpha=-1, $size='D', $pos='F') {
12321 if ($alpha>=0) $this->watermarkImageAlpha
= $alpha;
12322 $this->watermarkImage
= $src;
12323 $this->watermark_size
= $size;
12324 $this->watermark_pos
= $pos;
12326 /*-- END WATERMARK --*/
12330 function Footer() {
12332 // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
12333 if ($this->show_marks
== 'CROP' || $this->show_marks
== 'CROPCROSS') {
12335 $this->SetLineWidth(0.1); // = 0.1 mm
12336 $this->SetDColor($this->ConvertColor(0));
12337 $l = $this->cropMarkLength
;
12338 $m = $this->cropMarkMargin
; // Distance of crop mark from margin
12339 $b = $this->nonPrintMargin
; // Non-printable border at edge of paper sheet
12341 $bx = $this->page_box
['outer_width_LR'] - $m;
12342 $ax = max($ax1, $bx-$l);
12343 $cx1 = $this->w
- $b;
12344 $dx = $this->w
- $this->page_box
['outer_width_LR'] +
$m;
12345 $cx = min($cx1, $dx+
$l);
12347 $by = $this->page_box
['outer_width_TB'] - $m;
12348 $ay = max($ay1, $by-$l);
12349 $cy1 = $this->h
- $b;
12350 $dy = $this->h
- $this->page_box
['outer_width_TB'] +
$m;
12351 $cy = min($cy1, $dy+
$l);
12353 $this->Line($ax, $this->page_box
['outer_width_TB'], $bx, $this->page_box
['outer_width_TB']);
12354 $this->Line($cx, $this->page_box
['outer_width_TB'], $dx, $this->page_box
['outer_width_TB']);
12355 $this->Line($ax, $this->h
- $this->page_box
['outer_width_TB'], $bx, $this->h
- $this->page_box
['outer_width_TB']);
12356 $this->Line($cx, $this->h
- $this->page_box
['outer_width_TB'], $dx, $this->h
- $this->page_box
['outer_width_TB']);
12357 $this->Line($this->page_box
['outer_width_LR'], $ay, $this->page_box
['outer_width_LR'], $by);
12358 $this->Line($this->page_box
['outer_width_LR'], $cy, $this->page_box
['outer_width_LR'], $dy);
12359 $this->Line($this->w
- $this->page_box
['outer_width_LR'], $ay, $this->w
- $this->page_box
['outer_width_LR'], $by);
12360 $this->Line($this->w
- $this->page_box
['outer_width_LR'], $cy, $this->w
- $this->page_box
['outer_width_LR'], $dy);
12362 if ($this->printers_info
) {
12363 $hd = date('Y-m-d H:i').' Page '.$this->page
.' of {nb}';
12364 $this->SetTColor($this->ConvertColor(0));
12365 $this->SetFont('arial','',7.5,true,true);
12366 $this->x
= $this->page_box
['outer_width_LR'] +
1.5;
12368 $this->Cell($headerpgwidth ,$this->FontSize
,$hd,0,0,'L',0,'',0,0,0,'M');
12369 $this->SetFont($this->default_font
,'',$this->original_default_font_size
);
12373 if ($this->show_marks
== 'CROSS' || $this->show_marks
== 'CROPCROSS') {
12374 $this->SetLineWidth(0.1); // = 0.1 mm
12375 $this->SetDColor($this->ConvertColor(0));
12376 $l = 14 /2; // longer length of the cross line (half)
12377 $w = 6 /2; // shorter width of the cross line (half)
12378 $r = 1.2; // radius of circle
12379 $m = $this->crossMarkMargin
; // Distance of cross mark from margin
12380 $x1 = $this->page_box
['outer_width_LR'] - $m;
12381 $x2 = $this->w
- $this->page_box
['outer_width_LR'] +
$m;
12382 $y1 = $this->page_box
['outer_width_TB'] - $m;
12383 $y2 = $this->h
- $this->page_box
['outer_width_TB'] +
$m;
12385 $this->Circle($x1, $this->h
/2, $r, 'S') ;
12386 $this->Line($x1-$w, $this->h
/2, $x1+
$w, $this->h
/2);
12387 $this->Line($x1, $this->h
/2-$l, $x1, $this->h
/2+
$l);
12389 $this->Circle($x2, $this->h
/2, $r, 'S') ;
12390 $this->Line($x2-$w, $this->h
/2, $x2+
$w, $this->h
/2);
12391 $this->Line($x2, $this->h
/2-$l, $x2, $this->h
/2+
$l);
12393 $this->Circle($this->w
/2, $y1, $r, 'S') ;
12394 $this->Line($this->w
/2, $y1-$w, $this->w
/2, $y1+
$w);
12395 $this->Line($this->w
/2-$l, $y1, $this->w
/2+
$l, $y1);
12397 $this->Circle($this->w
/2, $y2, $r, 'S') ;
12398 $this->Line($this->w
/2, $y2-$w, $this->w
/2, $y2+
$w);
12399 $this->Line($this->w
/2-$l, $y2, $this->w
/2+
$l, $y2);
12403 // If @page set non-HTML headers/footers named, they were not read until later in the HTML code - so now set them
12404 if ($this->page
==1) {
12405 if ($this->firstPageBoxHeader
) {
12406 $this->headerDetails
['odd'] = $this->pageheaders
[$this->firstPageBoxHeader
];
12409 if ($this->firstPageBoxFooter
) {
12410 $this->footerDetails
['odd'] = $this->pagefooters
[$this->firstPageBoxFooter
];
12412 $this->firstPageBoxHeader
='';
12413 $this->firstPageBoxFooter
='';
12415 /*-- END CSS-PAGE --*/
12419 /*-- HTMLHEADERS-FOOTERS --*/
12420 if (($this->mirrorMargins
&& ($this->page%
2==0) && $this->HTMLFooterE
) || ($this->mirrorMargins
&& ($this->page%
2==1) && $this->HTMLFooter
) || (!$this->mirrorMargins
&& $this->HTMLFooter
)) {
12421 $this->writeHTMLFooters();
12422 /*-- WATERMARK --*/
12423 if (($this->watermarkText
) && ($this->showWatermarkText
)) {
12424 $this->watermark( $this->watermarkText
, 45, 120, $this->watermarkTextAlpha
); // Watermark text
12426 if (($this->watermarkImage
) && ($this->showWatermarkImage
)) {
12427 $this->watermarkImg( $this->watermarkImage
, $this->watermarkImageAlpha
); // Watermark image
12429 /*-- END WATERMARK --*/
12432 /*-- END HTMLHEADERS-FOOTERS --*/
12434 $this->processingHeader
=true;
12435 $this->ResetMargins(); // necessary after columns
12436 $this->pgwidth
= $this->w
- $this->lMargin
- $this->rMargin
;
12437 /*-- WATERMARK --*/
12438 if (($this->watermarkText
) && ($this->showWatermarkText
)) {
12439 $this->watermark( $this->watermarkText
, 45, 120, $this->watermarkTextAlpha
); // Watermark text
12441 if (($this->watermarkImage
) && ($this->showWatermarkImage
)) {
12442 $this->watermarkImg( $this->watermarkImage
, $this->watermarkImageAlpha
); // Watermark image
12444 /*-- END WATERMARK --*/
12445 $h = $this->footerDetails
;
12448 if ($this->forcePortraitHeaders
&& $this->CurOrientation
=='L' && $this->CurOrientation
!=$this->DefOrientation
) {
12449 $this->_out(sprintf('q 0 -1 1 0 0 %.3F cm ',($this->h
*_MPDFK
)));
12450 $headerpgwidth = $this->h
- $this->orig_lMargin
- $this->orig_rMargin
;
12451 if (($this->mirrorMargins
) && (($this->page
)%
2==0)) { // EVEN
12452 $headerlmargin = $this->orig_rMargin
;
12455 $headerlmargin = $this->orig_lMargin
;
12460 $headerpgwidth = $this->pgwidth
;
12461 $headerlmargin = $this->lMargin
;
12463 $this->SetY(-$this->margin_footer
);
12465 $this->SetTColor($this->ConvertColor(0));
12466 $this->SUP
= false;
12467 $this->SUB
= false;
12468 $this->bullet
= false;
12470 // only show pagenumber if numbering on
12471 $pgno = $this->docPageNum($this->page
, true);
12473 if (($this->mirrorMargins
) && (($this->page
)%
2==0)) { // EVEN
12476 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS = DEFAULT
12479 $maxfontheight = 0;
12480 foreach(array('L','C','R') AS $pos) {
12481 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
12482 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz
= $h
[$side
][$pos
]['font-size']; }
12483 else { $hfsz
= $this
->default_font_size
; }
12484 $maxfontheight = max($maxfontheight,$hfsz);
12487 // LEFT-CENTER-RIGHT
12488 foreach(array('L','C','R') AS $pos) {
12489 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
12490 $hd = str_replace('{PAGENO}',$pgno,$h[$side][$pos]['content']);
12491 $hd = str_replace($this->aliasNbPgGp
,$this->nbpgPrefix
.$this->aliasNbPgGp
.$this->nbpgSuffix
,$hd);
12492 $hd = preg_replace('/\{DATE\s+(.*?)\}/e',"date('\\1')",$hd);
12493 if (isset($h[$side][$pos]['font-family']) && $h[$side][$pos]['font-family']) { $hff
= $h
[$side
][$pos
]['font-family']; }
12494 else { $hff
= $this
->original_default_font
; }
12495 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz
= $h
[$side
][$pos
]['font-size']; }
12496 else { $hfsz
= $this
->original_default_font_size
; }
12497 $maxfontheight = max($maxfontheight,$hfsz);
12498 if (isset($h[$side][$pos]['font-style']) && $h[$side][$pos]['font-style']) { $hfst
= $h
[$side
][$pos
]['font-style']; }
12499 else { $hfst
= ''; }
12500 if (isset($h[$side][$pos]['color']) && $h[$side][$pos]['color']) {
12501 $hfcol = $h[$side][$pos]['color'];
12502 $cor = $this->ConvertColor($hfcol);
12503 if ($cor) { $this
->SetTColor($cor
); }
12505 else { $hfcol
= ''; }
12506 $this->SetFont($hff,$hfst,$hfsz,true,true);
12507 $this->x
= $headerlmargin ;
12508 $this->y
= $this->h
- $this->margin_footer
- ($maxfontheight/_MPDFK
);
12509 $hd = $this->purify_utf8_text($hd);
12510 if ($this->text_input_as_HTML
) {
12511 $hd = $this->all_entities_to_utf8($hd);
12513 // CONVERT CODEPAGE
12514 if ($this->usingCoreFont
) { $hd
= mb_convert_encoding($hd
,$this
->mb_enc
,'UTF-8'); }
12515 // DIRECTIONALITY RTL
12516 $this->magic_reverse_dir($hd, true, $this->directionality
); // *RTL*
12517 // Font-specific ligature substitution for Indic fonts
12518 if (isset($this->CurrentFont
['indic']) && $this->CurrentFont
['indic']) $this->ConvertIndic($hd); // *INDIC*
12520 if ($this->directionality
== 'rtl') {
12521 if ($pos == 'L') { $align
= 'R'; }
12522 else if ($pos == 'R') { $align
= 'L'; }
12525 if ($pos!='L' && (strpos($hd,$this->aliasNbPg
)!==false || strpos($hd,$this->aliasNbPgGp
)!==false)) {
12526 if (strpos($hd,$this->aliasNbPgGp
)!==false) { $type
= 'nbpggp'; } else { $type
= 'nbpg'; }
12527 $this->_out('{mpdfheader'.$type.' '.$pos.' ff='.$hff.' fs='.$hfst.' fz='.$hfsz.'}');
12528 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK
,$hd,0,0,$align,0,'',0,0,0,'M');
12532 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK
,$hd,0,0,$align,0,'',0,0,0,'M');
12534 if ($hfcol) { $this
->SetTColor($this
->ConvertColor(0)); }
12537 // Return Font to normal
12538 $this->SetFont($this->default_font
,'',$this->original_default_font_size
);
12542 if (isset($h[$side]['line']) && $h[$side]['line']) {
12543 $this->SetLineWidth(0.1);
12544 $this->SetDColor($this->ConvertColor(0));
12545 $this->Line($headerlmargin , $this->y
-($maxfontheight*($this->footer_line_spacing
)/_MPDFK
), $headerlmargin +
$headerpgwidth, $this->y
-($maxfontheight*($this->footer_line_spacing
)/_MPDFK
));
12547 if ($this->forcePortraitHeaders
&& $this->CurOrientation
=='L' && $this->CurOrientation
!=$this->DefOrientation
) {
12551 $this->processingHeader
=false;
12555 ///////////////////
12557 ///////////////////
12560 function hardHyphenate($word, $maxWidth) {
12561 // Don't hyphenate web addresses
12562 if (preg_match('/^(http:|www\.)/',$word)) { return array(false,'','',''); }
12566 $softhyphens = array();
12569 if ($this->usingCoreFont
) {
12570 $wl = strlen($word);
12573 $wl = mb_strlen($word,'UTF-8');
12575 while($offset < $wl) {
12576 if (!$this->usingCoreFont
) {
12577 $p = mb_strpos($word, "-", $offset, 'UTF-8');
12579 else if ($this->FontFamily
!='csymbol' && $this->FontFamily
!='czapfdingbats') {
12580 $p = strpos($word, "-", $offset);
12582 if ($p !== false) { $poss
[] = $p
- count($poss
); }
12587 foreach($poss AS $i) {
12588 if ($this->usingCoreFont
) {
12589 $a = substr($word,0,$i);
12590 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12592 $post = substr($word,$i,strlen($word));
12593 $prelength = strlen($pre);
12596 $a = mb_substr($word,0,$i,'UTF-8');
12597 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12599 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8');
12600 $prelength = mb_strlen($pre, 'UTF-8');
12604 return array($success,$pre,$post,$prelength);
12608 /*-- HYPHENATION --*/
12609 ///////////////////
12610 ///////////////////
12612 ///////////////////
12614 function softHyphenate($word, $maxWidth) {
12615 // Don't hyphenate web addresses
12616 if (preg_match('/^(http:|www\.)/',$word)) { return array(false,'','',''); }
12620 $softhyphens = array();
12623 if ($this->usingCoreFont
) {
12624 $wl = strlen($word);
12627 $wl = mb_strlen($word,'UTF-8');
12629 while($offset < $wl) {
12630 // Soft Hyphens chr(173)
12631 if (!$this->usingCoreFont
) {
12632 $p = mb_strpos($word, "\xc2\xad", $offset, 'UTF-8');
12634 else if ($this->FontFamily
!='csymbol' && $this->FontFamily
!='czapfdingbats') {
12635 $p = strpos($word, chr(173), $offset);
12637 if ($p !== false) { $poss
[] = $p
- count($poss
); }
12642 foreach($poss AS $i) {
12643 if ($this->usingCoreFont
) {
12644 $a = substr($word,0,$i);
12645 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12647 $post = substr($word,$i,strlen($word));
12648 $prelength = strlen($pre);
12651 $a = mb_substr($word,0,$i,'UTF-8');
12652 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12654 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8');
12655 $prelength = mb_strlen($pre, 'UTF-8');
12659 return array($success,$pre,$post,$prelength);
12662 ///////////////////
12663 // Word hyphenation
12664 function hyphenateWord($word, $maxWidth) {
12665 // Do everything inside this function in utf-8
12666 // Don't hyphenate web addresses
12667 if (preg_match('/^(http:|www\.)/',$word)) { return array(false,'','',''); }
12671 if (!$this->loadedSHYdictionary
) {
12672 if (file_exists(_MPDF_PATH
.'patterns/dictionary.txt')) {
12673 $this->SHYdictionary
= file(_MPDF_PATH
.'patterns/dictionary.txt',FILE_SKIP_EMPTY_LINES
);
12674 foreach($this->SHYdictionary
as $entry) {
12675 $entry = trim($entry);
12679 $wl = mb_strlen($entry ,'UTF-8');
12680 while($offset < $wl) {
12681 $p = mb_strpos($entry, '/', $offset, 'UTF-8');
12682 if ($p !== false) { $poss
[] = $p
- count($poss
); }
12686 if (count($poss)) { $this
->SHYdictionaryWords
[str_replace('/', '', mb_strtolower($entry
))] = $poss
; }
12689 $this->loadedSHYdictionary
= true;
12692 if (!in_array($this->SHYlang
,$this->SHYlanguages
)) { return array(false,'','',''); }
12693 // If no pattern loaded or not the best one
12694 if (count($this->SHYpatterns
) < 1 || ($this->loadedSHYpatterns
&& $this->loadedSHYpatterns
!= $this->SHYlang
)) {
12695 include(_MPDF_PATH
."patterns/" . $this->SHYlang
. ".php");
12696 $patterns = explode(' ', $patterns);
12697 $new_patterns = array();
12698 for($i = 0; $i < count($patterns); $i++
) {
12699 $value = $patterns[$i];
12700 $new_patterns[preg_replace('/[0-9]/', '', $value)] = $value;
12702 $this->SHYpatterns
= $new_patterns;
12703 $this->loadedSHYpatterns
= $this->SHYlang
;
12706 if ($this->usingCoreFont
) { $word
= mb_convert_encoding($word
,'UTF-8',$this
->mb_enc
); }
12710 $startpunctuation = "\xc2\xab\xc2\xbf\xe2\x80\x98\xe2\x80\x9b\xe2\x80\x9c\xe2\x80\x9f";
12711 $endpunctuation = "\xe2\x80\x9e\xe2\x80\x9d\xe2\x80\x9a\xe2\x80\x99\xc2\xbb";
12716 if (preg_match('/^(["\''.$startpunctuation .'])+(.{'.$this->SHYcharmin.',})$/u',$word,$m)) {
12720 if (preg_match('/^(.{'.$this->SHYcharmin.',})([\'\.,;:!?"'.$endpunctuation .']+)$/u',$word,$m)) {
12724 if(mb_strlen($word,'UTF-8') < $this->SHYcharmin
) {
12725 return array(false,'','','');
12729 if(isset($this->SHYdictionaryWords
[mb_strtolower($word)])) {
12730 foreach($this->SHYdictionaryWords
[mb_strtolower($word)] AS $i) {
12731 $a = $prepre . mb_substr($word,0,$i,'UTF-8');
12732 if ($this->usingCoreFont
) { $testa
= mb_convert_encoding($a
,$this
->mb_enc
,'UTF-8'); }
12733 else { $testa
= $a
; }
12734 if ($this->GetStringWidth($testa.'-') > $maxWidth) { break ; }
12736 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8') . $postpost;
12742 $text_word = '_' . $word . '_';
12743 $word_length = mb_strlen($text_word,'UTF-8');
12745 $single_character = preg_split('//u', $text_word);
12747 $text_word = mb_strtolower($text_word,'UTF-8');
12748 $hyphenated_word = array();
12749 $numb3rs = array('0' => true, '1' => true, '2' => true, '3' => true, '4' => true, '5' => true, '6' => true, '7' => true, '8' => true, '9' => true);
12750 for($position = 0; $position <= ($word_length - $this->SHYcharmin
); $position++
) {
12751 $maxwins = min(($word_length - $position), $this->SHYcharmax
);
12752 for($win = $this->SHYcharmin
; $win <= $maxwins; $win++
) {
12753 if(isset($this->SHYpatterns
[mb_substr($text_word, $position, $win,'UTF-8')])) {
12754 $pattern = $this->SHYpatterns
[mb_substr($text_word, $position, $win,'UTF-8')];
12756 $pattern_length = mb_strlen($pattern,'UTF-8');
12757 for($i = 0; $i < $pattern_length; $i++
) {
12758 $char = $pattern[$i];
12759 if(isset($numb3rs[$char])) {
12760 $zero = ($i == 0) ? $position - 1 : $position +
$i - $digits;
12761 if(!isset($hyphenated_word[$zero]) || $hyphenated_word[$zero] != $char) $hyphenated_word[$zero] = $char;
12769 for($i = $this->SHYleftmin
; $i <= (mb_strlen($word,'UTF-8') - $this->SHYrightmin
); $i++
) {
12770 if(isset($hyphenated_word[$i]) && $hyphenated_word[$i] %
2 != 0) {
12771 $a = $prepre . mb_substr($word,0,$i,'UTF-8');
12772 if ($this->usingCoreFont
) { $testa
= mb_convert_encoding($a
,$this
->mb_enc
,'UTF-8'); }
12773 else { $testa
= $a
; }
12774 if ($this->GetStringWidth($testa.'-') > $maxWidth +
0.0001) { break ; }
12776 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8') . $postpost;
12781 if ($this->usingCoreFont
) {
12782 $pre = mb_convert_encoding($pre,$this->mb_enc
,'UTF-8');
12783 $post = mb_convert_encoding($post,$this->mb_enc
,'UTF-8');
12784 $prelength = strlen($pre);
12787 $prelength = mb_strlen($pre);
12789 return array($success,$pre,$post,$prelength);
12792 /*-- END HYPHENATION --*/
12796 ///////////////////
12797 /// HTML parser ///
12798 ///////////////////
12799 function WriteHTML($html,$sub=0,$init=true,$close=true) {
12800 // $sub ADDED - 0 = default; 1=headerCSS only; 2=HTML body (parts) only; 3 - HTML parses only
12801 // 4 - writes HTML headers
12802 // $close Leaves buffers etc. in current state, so that it can continue a block etc.
12803 // $init - Clears and sets buffers to Top level block etc.
12805 if (empty($html)) { $html
= ''; }
12806 if ($this->progressBar
) { $this
->UpdateProgressBar(1,0,'Parsing CSS & Headers'); } // *PROGRESS-BAR*
12809 $this->headerbuffer
='';
12810 $this->textbuffer
= array();
12811 $this->fixedPosBlockSave
= array();
12813 if ($sub == 1) { $html
= '<style> '.$html
.' </style>'; } // stylesheet only
12815 if ($this->allow_charset_conversion
) {
12817 $this->ReadCharset($html);
12819 if ($this->charset_in
&& $sub!=4) { // mPDF 5.4.14
12820 $success = iconv($this->charset_in
,'UTF-8//TRANSLIT',$html);
12821 if ($success) { $html
= $success
; }
12824 $html = $this->purify_utf8($html,false);
12827 $this->lastblocklevelchange
= 0;
12828 $this->blk
= array();
12829 $this->initialiseBlock($this->blk
[0]);
12830 $this->blk
[0]['width'] =& $this->pgwidth
;
12831 $this->blk
[0]['inner_width'] =& $this->pgwidth
;
12832 $this->blk
[0]['blockContext'] = $this->blockContext
;
12835 $zproperties = array();
12837 $this->ReadMetaTags($html);
12840 if (preg_match('/<base[^>]*href=["\']([^"\'>]*)["\']/i', $html, $m)) {
12841 $this->SetBasePath($m[1]);
12843 // NB default stylesheet now in mPDF.css - read on initialising class
12844 $html = $this->cssmgr
->ReadCSS($html);
12846 if ($this->useLang
&& !$this->usingCoreFont
&& preg_match('/<html [^>]*lang=[\'\"](.*?)[\'\"]/ism',$html,$m)) {
12847 $html_lang = $m[1];
12850 if (preg_match('/<html [^>]*dir=[\'\"]\s*rtl\s*[\'\"]/ism',$html)) {
12851 $zproperties['DIRECTION'] = 'rtl';
12854 // allow in-line CSS for body tag to be parsed // Get <body> tag inline CSS
12855 if (preg_match('/<body([^>]*)>(.*?)<\/body>/ism',$html,$m) || preg_match('/<body([^>]*)>(.*)$/ism',$html,$m)) {
12857 // Changed to allow style="background: url('bg.jpg')"
12858 if (preg_match('/style=[\"](.*?)[\"]/ism',$m[1],$mm) || preg_match('/style=[\'](.*?)[\']/ism',$m[1],$mm)) {
12859 $zproperties = $this->cssmgr
->readInlineCSS($mm[1]);
12861 if (preg_match('/dir=[\'\"]\s*rtl\s*[\'\"]/ism',$m[1])) {
12862 $zproperties['DIRECTION'] = 'rtl';
12864 if (isset($html_lang) && $html_lang) { $zproperties
['LANG'] = $html_lang
; }
12865 if ($this->useLang
&& !$this->onlyCoreFonts
&& preg_match('/lang=[\'\"](.*?)[\'\"]/ism',$m[1],$mm)) {
12866 $zproperties['LANG'] = $mm[1];
12871 $properties = $this->cssmgr
->MergeCSS('BLOCK','BODY','');
12872 if ($zproperties) { $properties
= $this
->cssmgr
->array_merge_recursive_unique($properties
,$zproperties
); }
12874 if (isset($properties['DIRECTION']) && $properties['DIRECTION']) {
12875 $this->cssmgr
->CSS
['BODY']['DIRECTION'] = $properties['DIRECTION'];
12877 if (!isset($this->cssmgr
->CSS
['BODY']['DIRECTION'])) {
12878 $this->cssmgr
->CSS
['BODY']['DIRECTION'] = $this->directionality
;
12880 else { $this
->SetDirectionality($this
->cssmgr
->CSS
['BODY']['DIRECTION']); }
12882 $this->setCSS($properties,'','BODY');
12883 $this->blk
[0]['InlineProperties'] = $this->saveInlineProperties();
12885 if ($sub == 1) { return ''; }
12886 if (!isset($this->cssmgr
->CSS
['BODY'])) { $this
->cssmgr
->CSS
['BODY'] = array(); }
12888 /*-- BACKGROUNDS --*/
12889 if (isset($properties['BACKGROUND-GRADIENT'])) {
12890 $this->bodyBackgroundGradient
= $properties['BACKGROUND-GRADIENT'];
12893 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE']) {
12894 $ret = $this->SetBackground($properties, $this->pgwidth
);
12895 if ($ret) { $this
->bodyBackgroundImage
= $ret
; }
12897 /*-- END BACKGROUNDS --*/
12900 // If page-box is set
12901 if ($this->state
==0 && isset($this->cssmgr
->CSS
['@PAGE']) && $this->cssmgr
->CSS
['@PAGE'] ) {
12902 $this->page_box
['current'] = '';
12903 $this->page_box
['using'] = true;
12904 list($pborientation,$pbmgl,$pbmgr,$pbmgt,$pbmgb,$pbmgh,$pbmgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS('', false, 'O');
12905 $this->DefOrientation
= $this->CurOrientation
= $pborientation;
12906 $this->orig_lMargin
= $this->DeflMargin
= $pbmgl;
12907 $this->orig_rMargin
= $this->DefrMargin
= $pbmgr;
12908 $this->orig_tMargin
= $this->tMargin
= $pbmgt;
12909 $this->orig_bMargin
= $this->bMargin
= $pbmgb;
12910 $this->orig_hMargin
= $this->margin_header
= $pbmgh;
12911 $this->orig_fMargin
= $this->margin_footer
= $pbmgf;
12912 list($pborientation,$pbmgl,$pbmgr,$pbmgt,$pbmgb,$pbmgh,$pbmgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS('', true, 'O'); // first page
12913 $this->show_marks
= $marks;
12914 if ($hname && !preg_match('/^html_(.*)$/i',$hname)) $this->firstPageBoxHeader
= $hname;
12915 if ($fname && !preg_match('/^html_(.*)$/i',$fname)) $this->firstPageBoxFooter
= $fname;
12917 /*-- END CSS-PAGE --*/
12919 $parseonly = false;
12920 $this->bufferoutput
= false;
12923 // Close any open block tags
12924 for ($b= $this->blklvl
;$b>0;$b--) { $this
->CloseTag($this
->blk
[$b
]['tag']); }
12925 // Output any text left in buffer
12926 if (count($this->textbuffer
)) { $this
->printbuffer($this
->textbuffer
); }
12927 $this->textbuffer
=array();
12929 else if ($sub == 4) {
12930 // Close any open block tags
12931 for ($b= $this->blklvl
;$b>0;$b--) { $this
->CloseTag($this
->blk
[$b
]['tag']); }
12932 // Output any text left in buffer
12933 if (count($this->textbuffer
)) { $this
->printbuffer($this
->textbuffer
); }
12934 $this->bufferoutput
= true;
12935 $this->textbuffer
=array();
12936 $this->headerbuffer
='';
12937 $properties = $this->cssmgr
->MergeCSS('BLOCK','BODY','');
12938 $this->setCSS($properties,'','BODY');
12941 mb_internal_encoding('UTF-8');
12943 $html = $this->AdjustHTML($html, $this->tabSpaces
); //Try to make HTML look more like XHTML
12945 if ($this->autoFontGroups
) { $html
= $this
->AutoFont($html
); }
12947 /*-- HTMLHEADERS-FOOTERS --*/
12948 preg_match_all('/<htmlpageheader([^>]*)>(.*?)<\/htmlpageheader>/si',$html,$h);
12949 for($i=0;$i<count($h[1]);$i++
) {
12950 if (preg_match('/name=[\'|\"](.*?)[\'|\"]/',$h[1][$i],$n)) {
12951 $this->pageHTMLheaders
[$n[1]]['html'] = $h[2][$i];
12952 $this->pageHTMLheaders
[$n[1]]['h'] = $this->_gethtmlheight($h[2][$i]);
12955 preg_match_all('/<htmlpagefooter([^>]*)>(.*?)<\/htmlpagefooter>/si',$html,$f);
12956 for($i=0;$i<count($f[1]);$i++
) {
12957 if (preg_match('/name=[\'|\"](.*?)[\'|\"]/',$f[1][$i],$n)) {
12958 $this->pageHTMLfooters
[$n[1]]['html'] = $f[2][$i];
12959 $this->pageHTMLfooters
[$n[1]]['h'] = $this->_gethtmlheight($f[2][$i]);
12962 /*-- END HTMLHEADERS-FOOTERS --*/
12963 $html = preg_replace('/<htmlpageheader.*?<\/htmlpageheader>/si','',$html);
12964 $html = preg_replace('/<htmlpagefooter.*?<\/htmlpagefooter>/si','',$html);
12966 if($this->state
==0 && $sub!=1 && $sub!=3 && $sub!=4) {
12967 $this->AddPage($this->CurOrientation
);
12971 /*-- HTMLHEADERS-FOOTERS --*/
12973 if (isset($hname) && preg_match('/^html_(.*)$/i',$hname,$n)) $this->SetHTMLHeader($this->pageHTMLheaders
[$n[1]],'O',true);
12974 if (isset($fname) && preg_match('/^html_(.*)$/i',$fname,$n)) $this->SetHTMLFooter($this->pageHTMLfooters
[$n[1]],'O');
12976 /*-- END HTMLHEADERS-FOOTERS --*/
12978 $html=str_replace('<?','< ',$html); //Fix '<?XML' bug from HTML code generated by MS Word
12980 $this->checkSIP
= false;
12981 $this->checkSMP
= false;
12982 $this->checkCJK
= false;
12983 if ($this->onlyCoreFonts
) { $html
= $this
->SubstituteChars($html
); }
12985 if (preg_match("/([".$this->pregRTLchars
."])/u", $html)) { $this
->biDirectional
= true; } // *RTL*
12986 if (preg_match("/([\x{20000}-\x{2FFFF}])/u", $html)) { $this
->checkSIP
= true; }
12987 if (preg_match("/([\x{10000}-\x{1FFFF}])/u", $html)) { $this
->checkSMP
= true; }
12988 /*-- CJK-FONTS --*/
12989 if (preg_match("/([".$this->pregCJKchars
."])/u", $html)) { $this
->checkCJK
= true; }
12990 /*-- END CJK-FONTS --*/
12993 // Don't allow non-breaking spaces that are converted to substituted chars or will break anyway and mess up table width calc.
12994 $html = str_replace('<tta>160</tta>',chr(32),$html);
12995 $html = str_replace('</tta><tta>','|',$html);
12996 $html = str_replace('</tts><tts>','|',$html);
12997 $html = str_replace('</ttz><ttz>','|',$html);
12999 //Add new supported tags in the DisableTags function
13000 $html=strip_tags($html,$this->enabledtags
); //remove all unsupported tags, but the ones inside the 'enabledtags' string
13002 //Explode the string in order to parse the HTML code
13003 $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE
);
13004 // ? more accurate regexp that allows e.g. <a name="Silly <name>">
13005 // if changing - also change in fn.SubstituteChars()
13006 // $a = preg_split ('/<((?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+)>/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
13008 if ($this->mb_enc
) {
13009 mb_internal_encoding($this->mb_enc
);
13012 if ($this->progressBar
) { $this
->UpdateProgressBar(1,0); } // *PROGRESS-BAR*
13013 $this->subPos
= -1;
13015 for($i=0;$i<$cnt; $i++
) {
13019 if ($this->blk
[$this->blklvl
]['hide']) { continue; }
13020 if ($this->inlineDisplayOff
) { continue; }
13021 if ($this->inMeter
) { continue; } // mPDF 5.5.09
13023 if ($this->inFixedPosBlock
) { $this
->fixedPosBlock
.= $e
; continue; } // *CSS-POSITION*
13024 if (strlen($e) == 0) { continue; }
13026 $e = strcode2utf($e);
13027 $e = $this->lesser_entity_decode($e);
13029 if ($this->usingCoreFont
) {
13030 // If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
13031 if ($this->useSubstitutions
&& !$this->onlyCoreFonts
&& $this->subPos
<$i && !$this->specialcontent
) {
13032 $cnt +
= $this->SubstituteCharsNonCore($a, $i, $e);
13034 // CONVERT ENCODING
13035 $e = mb_convert_encoding($e,$this->mb_enc
,'UTF-8');
13037 if ($this->toupper
) { $e
= mb_strtoupper($e
,$this
->mb_enc
); }
13038 if ($this->tolower
) { $e
= mb_strtolower($e
,$this
->mb_enc
); }
13039 if ($this->capitalize
) { $e
= mb_convert_case($e
, MB_CASE_TITLE
, "UTF-8"); }
13042 if ($this->checkSIP
&& $this->CurrentFont
['sipext'] && $this->subPos
<$i && !$this->specialcontent
) {
13043 $cnt +
= $this->SubstituteCharsSIP($a, $i, $e);
13046 if ($this->useSubstitutions
&& !$this->onlyCoreFonts
&& $this->CurrentFont
['type']!='Type0' && $this->subPos
<$i && !$this->specialcontent
) {
13047 // mPDF 5.6.62 removes U+200E/U+200F LTR and RTL mark and U+200C/U+200D Zero-width Joiner and Non-joiner
13048 $e = preg_replace("/[\xe2\x80\x8c\xe2\x80\x8d\xe2\x80\x8e\xe2\x80\x8f]/u",'',$e);
13049 $cnt +
= $this->SubstituteCharsMB($a, $i, $e);
13051 if ($this->biDirectional
) { // *RTL*
13052 $e = preg_replace("/([".$this->pregRTLchars
."]+)/ue", '$this->ArabJoin(stripslashes(\'\\1\'))', $e); // *RTL*
13054 // Font-specific ligature substitution for Indic fonts
13055 if (isset($this->CurrentFont
['indic']) && $this->CurrentFont
['indic']) $this->ConvertIndic($e); // *INDIC*
13057 // mPDF 5.6.62 removes U+200E/U+200F LTR and RTL mark and U+200C/U+200D Zero-width Joiner and Non-joiner
13058 $e = preg_replace("/[\xe2\x80\x8c\xe2\x80\x8d\xe2\x80\x8e\xe2\x80\x8f]/u",'',$e);
13060 if ($this->toupper
) { $e
= mb_strtoupper($e
,$this
->mb_enc
); }
13061 if ($this->tolower
) { $e
= mb_strtolower($e
,$this
->mb_enc
); }
13062 if ($this->capitalize
) { $e
= mb_convert_case($e
, MB_CASE_TITLE
, "UTF-8"); }
13064 if (($this->tts
) || ($this->ttz
) || ($this->tta
)) {
13065 $es = explode('|',$e);
13067 foreach($es AS $val) {
13071 //Adjust lineheight
13074 if ($this->specialcontent
) {
13076 //SELECT tag (form element)
13077 if ($this->specialcontent
== "type=select") {
13079 $stringwidth = $this->GetStringWidth($e);
13080 if (!isset($this->selectoption
['MAXWIDTH']) || $stringwidth > $this->selectoption
['MAXWIDTH']) { $this
->selectoption
['MAXWIDTH'] = $stringwidth
; }
13081 if (!isset($this->selectoption
['SELECTED']) || $this->selectoption
['SELECTED'] == '') { $this
->selectoption
['SELECTED'] = $e
; }
13082 // mPDD 1.4 Active Forms
13083 if (isset($this->selectoption
['ACTIVE']) && $this->selectoption
['ACTIVE']) {
13084 $this->selectoption
['ITEMS'][]=array('exportValue'=>$this->selectoption
['currentVAL'], 'content'=>$e, 'selected'=>$this->selectoption
['currentSEL']);
13089 $objattr = unserialize($this->specialcontent
);
13090 $objattr['text'] = $e;
13091 $te = "\xbb\xa4\xactype=textarea,objattr=".serialize($objattr)."\xbb\xa4\xac";
13092 if ($this->tdbegin
) {
13093 $this->_saveCellTextBuffer($te, $this->HREF
);
13096 $this->_saveTextBuffer($te, $this->HREF
);
13099 /*-- END FORMS --*/
13103 else if ($this->tableLevel
) {
13105 if ($this->tdbegin
) {
13106 if (($this->ignorefollowingspaces
) && !$this->ispre
) { $e
= ltrim($e
); }
13107 if ($e || $e==='0') {
13108 if (($this->blockjustfinished
|| $this->listjustfinished
) && $this->cell
[$this->row
][$this->col
]['s']>0) {
13109 $this->_saveCellTextBuffer("\n");
13110 if (!isset($this->cell
[$this->row
][$this->col
]['maxs'])) {
13111 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
13113 elseif($this->cell
[$this->row
][$this->col
]['maxs'] < $this->cell
[$this->row
][$this->col
]['s']) {
13114 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
13116 $this->cell
[$this->row
][$this->col
]['s'] = 0;// reset
13118 $this->blockjustfinished
=false;
13119 $this->listjustfinished
=false;
13121 $this->_saveCellTextBuffer($e, $this->HREF
);
13123 if (!isset($this->cell
[$this->row
][$this->col
]['R']) || !$this->cell
[$this->row
][$this->col
]['R']) {
13124 if (isset($this->cell
[$this->row
][$this->col
]['s'])) {
13125 $this->cell
[$this->row
][$this->col
]['s'] +
= $this->GetStringWidth($e, false);
13127 else { $this
->cell
[$this
->row
][$this
->col
]['s'] = $this
->GetStringWidth($e
, false); }
13128 if (!empty($this->spanborddet
)) {
13129 $this->cell
[$this->row
][$this->col
]['s'] +
= $this->spanborddet
['L']['w'] +
$this->spanborddet
['R']['w'];
13133 if ($this->checkCJK
&& preg_match("/([".$this->pregCJKchars
."])/u", $e)) { $this
->tableCJK
= true; } // *CJK-FONTS*
13135 // mPDF 5.6.13 Decimal mark alignment
13136 if (substr($this->cell
[$this->row
][$this->col
]['a'],0,1) == 'D') {
13137 $dp = $this->decimal_align
[substr($this->cell
[$this->row
][$this->col
]['a'],0,2)];
13138 $s = preg_split('/'.preg_quote($dp,'/').'/', $e, 2); // ? needs to be /u if not core
13139 $s0 = $this->GetStringWidth($s[0], false);
13140 if ($s[1]) { $s1
= $this
->GetStringWidth(($s
[1].$dp
), false); }
13142 if (!isset($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['decimal_align'][$this->col
]['maxs0'])) {
13143 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['decimal_align'][$this->col
]['maxs0'] = $s0;
13146 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['decimal_align'][$this->col
]['maxs0'] = max($s0, $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['decimal_align'][$this->col
]['maxs0']);
13148 if (!isset($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['decimal_align'][$this->col
]['maxs1'])) {
13149 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['decimal_align'][$this->col
]['maxs1'] = $s1;
13152 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['decimal_align'][$this->col
]['maxs1'] = max($s1, $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['decimal_align'][$this->col
]['maxs1']);
13156 if ($this->tableLevel
==1 && $this->useGraphs
) {
13157 $this->graphs
[$this->currentGraphId
]['data'][$this->row
][$this->col
] = $e;
13159 $this->nestedtablejustfinished
= false;
13160 $this->linebreakjustfinished
=false;
13163 /*-- END TABLES --*/
13167 if ($this->ignorefollowingspaces
and !$this->ispre
) { $e
= ltrim($e
); }
13168 if ($e || $e==='0') $this->_saveTextBuffer($e, $this->HREF
);
13176 /*-- PROGRESS-BAR --*/
13177 if ($this->progressBar
) { // 10% increments
13178 if (intval($i*10/$cnt) != $pbc) { $pbc
= intval($i
*10/$cnt
); $this
->UpdateProgressBar(1,$pbc
*10,$tag
); }
13180 /*-- END PROGRESS-BAR --*/
13183 // Check for tags where HTML specifies optional end tags,
13184 // and/or does not allow nesting e.g. P inside P, or
13185 $endtag = trim(strtoupper(substr($e,1))); // mPDF 5.4.20
13186 if($this->blk
[$this->blklvl
]['hide']) {
13187 if (in_array($endtag, $this->outerblocktags
) || in_array($endtag, $this->innerblocktags
)) {
13188 unset($this->blk
[$this->blklvl
]);
13194 /*-- CSS-POSITION --*/
13195 if ($this->inFixedPosBlock
) {
13196 if (in_array($endtag, $this->outerblocktags
) || in_array($endtag, $this->innerblocktags
)) { $this
->fixedPosBlockDepth
--; }
13197 if ($this->fixedPosBlockDepth
== 0) {
13198 $this->fixedPosBlockSave
[] = array($this->fixedPosBlock
, $this->fixedPosBlockBBox
, $this->page
);
13199 $this->fixedPosBlock
= '';
13200 $this->inFixedPosBlock
= false;
13203 $this->fixedPosBlock
.= '<'.$e.'>';
13206 /*-- END CSS-POSITION --*/
13207 if ($this->allow_html_optional_endtags
&& !$parseonly) {
13208 if (($endtag == 'DIV' || $endtag =='FORM' || $endtag =='CENTER') && $this->lastoptionaltag
== 'P') { $this
->CloseTag($this
->lastoptionaltag
); }
13209 if ($this->lastoptionaltag
== 'LI' && $endtag == 'OL') { $this
->CloseTag($this
->lastoptionaltag
); }
13210 if ($this->lastoptionaltag
== 'LI' && $endtag == 'UL') { $this
->CloseTag($this
->lastoptionaltag
); }
13211 if ($this->lastoptionaltag
== 'DD' && $endtag == 'DL') { $this
->CloseTag($this
->lastoptionaltag
); }
13212 if ($this->lastoptionaltag
== 'DT' && $endtag == 'DL') { $this
->CloseTag($this
->lastoptionaltag
); }
13213 if ($this->lastoptionaltag
== 'OPTION' && $endtag == 'SELECT') { $this
->CloseTag($this
->lastoptionaltag
); }
13215 if ($endtag == 'TABLE') {
13216 if ($this->lastoptionaltag
== 'THEAD' || $this->lastoptionaltag
== 'TBODY' || $this->lastoptionaltag
== 'TFOOT') {
13217 $this->CloseTag($this->lastoptionaltag
);
13219 if ($this->lastoptionaltag
== 'TR') { $this
->CloseTag('TR'); }
13220 if ($this->lastoptionaltag
== 'TD' || $this->lastoptionaltag
== 'TH') { $this
->CloseTag($this
->lastoptionaltag
); $this
->CloseTag('TR'); }
13222 if ($endtag == 'THEAD' || $endtag == 'TBODY' || $endtag == 'TFOOT') {
13223 if ($this->lastoptionaltag
== 'TR') { $this
->CloseTag('TR'); }
13224 if ($this->lastoptionaltag
== 'TD' || $this->lastoptionaltag
== 'TH') { $this
->CloseTag($this
->lastoptionaltag
); $this
->CloseTag('TR'); }
13226 if ($endtag == 'TR') {
13227 if ($this->lastoptionaltag
== 'TD' || $this->lastoptionaltag
== 'TH') { $this
->CloseTag($this
->lastoptionaltag
); }
13229 /*-- END TABLES --*/
13231 $this->CloseTag($endtag);
13234 else { // OPENING TAG
13235 if($this->blk
[$this->blklvl
]['hide']) {
13236 if (strpos($e,' ')) { $te
= strtoupper(substr($e
,0,strpos($e
,' '))); }
13237 else { $te
= strtoupper($e
); }
13238 if (in_array($te, $this->outerblocktags
) || in_array($te, $this->innerblocktags
)) {
13240 $this->blk
[$this->blklvl
]['hide']=true;
13245 /*-- CSS-POSITION --*/
13246 if ($this->inFixedPosBlock
) {
13247 if (strpos($e,' ')) { $te
= strtoupper(substr($e
,0,strpos($e
,' '))); }
13248 else { $te
= strtoupper($e
); }
13249 $this->fixedPosBlock
.= '<'.$e.'>';
13250 if (in_array($te, $this->outerblocktags
) || in_array($te, $this->innerblocktags
)) { $this
->fixedPosBlockDepth++
; }
13253 /*-- END CSS-POSITION --*/
13254 $regexp = '|=\'(.*?)\'|s'; // eliminate single quotes, if any
13255 $e = preg_replace($regexp,"=\"\$1\"",$e);
13256 // changes anykey=anyvalue to anykey="anyvalue" (only do this inside [some] tags)
13257 if (substr($e,0,10)!='pageheader' && substr($e,0,10)!='pagefooter' && substr($e,0,12)!='tocpagebreak') { // mPDF 5.6.69
13258 $regexp = '| (\\w+?)=([^\\s>"]+)|si';
13259 $e = preg_replace($regexp," \$1=\"\$2\"",$e);
13262 $e = preg_replace('/ (\\S+?)\s*=\s*"/i', " \\1=\"", $e);
13264 //Fix path values, if needed
13265 $orig_srcpath = '';
13266 if ((stristr($e,"href=") !== false) or (stristr($e,"src=") !== false) ) {
13267 $regexp = '/ (href|src)\s*=\s*"(.*?)"/i';
13268 preg_match($regexp,$e,$auxiliararray);
13269 if (isset($auxiliararray[2])) { $path
= $auxiliararray
[2]; }
13270 else { $path
= ''; }
13271 if (trim($path) != '' && !(stristr($e,"src=") !== false && substr($path,0,4)=='var:')) {
13272 $orig_srcpath = $path;
13273 $this->GetFullPath($path);
13274 $regexp = '/ (href|src)="(.*?)"/i';
13275 $e = preg_replace($regexp,' \\1="'.$path.'"',$e);
13277 }//END of Fix path values
13280 //Extract attributes
13282 $contents1=array(); // mPDF 5.5.17
13283 $contents2=array();
13284 // Changed to allow style="background: url('bg.jpg')"
13285 // mPDF 5.5.17 Changed to improve performance; maximum length of \S (attribute) = 16
13286 // mPDF 5.6.30 Increase allowed attribute name to 32 - cutting off "toc-even-header-name" etc.
13287 preg_match_all('/\\S{1,32}=["][^"]*["]/',$e,$contents1);
13288 preg_match_all('/\\S{1,32}=[\'][^\']*[\']/i',$e,$contents2);
13290 $contents = array_merge($contents1, $contents2);
13291 preg_match('/\\S+/',$e,$a2);
13292 $tag=strtoupper($a2[0]);
13294 if ($orig_srcpath) { $attr
['ORIG_SRC'] = $orig_srcpath
; }
13295 if (!empty($contents)) {
13296 foreach($contents[0] as $v) {
13297 // Changed to allow style="background: url('bg.jpg')"
13298 if(preg_match('/^([^=]*)=["]?([^"]*)["]?$/',$v,$a3) || preg_match('/^([^=]*)=[\']?([^\']*)[\']?$/',$v,$a3)) {
13299 if (strtoupper($a3[1])=='ID' || strtoupper($a3[1])=='CLASS') { // 4.2.013 Omits STYLE
13300 $attr[strtoupper($a3[1])]=trim(strtoupper($a3[2]));
13302 // includes header-style-right etc. used for <pageheader>
13303 else if (preg_match('/^(HEADER|FOOTER)-STYLE/i',$a3[1])) {
13304 $attr[strtoupper($a3[1])]=trim(strtoupper($a3[2]));
13307 $attr[strtoupper($a3[1])]=trim($a3[2]);
13312 $this->OpenTag($tag,$attr);
13313 /*-- CSS-POSITION --*/
13314 if ($this->inFixedPosBlock
) {
13315 $this->fixedPosBlockBBox
= array($tag,$attr, $this->x
, $this->y
);
13316 $this->fixedPosBlock
= '';
13317 $this->fixedPosBlockDepth
= 1;
13319 /*-- END CSS-POSITION --*/
13321 if (preg_match('/\/$/',$e)) { $this
->closeTag($tag
); }
13326 } //end of foreach($a as $i=>$e)
13330 // Close any open block tags
13331 for ($b= $this->blklvl
;$b>0;$b--) { $this
->CloseTag($this
->blk
[$b
]['tag']); }
13333 // Output any text left in buffer
13334 if (count($this->textbuffer
) && !$parseonly) { $this
->printbuffer($this
->textbuffer
); }
13335 if (!$parseonly) $this->textbuffer
=array();
13337 /*-- CSS-FLOAT --*/
13338 // If ended with a float, need to move to end page
13339 $currpos = $this->page
*1000 +
$this->y
;
13340 if (isset($this->blk
[$this->blklvl
]['float_endpos']) && $this->blk
[$this->blklvl
]['float_endpos'] > $currpos) {
13341 $old_page = $this->page
;
13342 $new_page = intval($this->blk
[$this->blklvl
]['float_endpos'] /1000);
13343 if ($old_page != $new_page) {
13344 $s = $this->PrintPageBackgrounds();
13345 // Writes after the marker so not overwritten later by page background etc.
13346 $this->pages
[$this->page
] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages
[$this->page
]);
13347 $this->pageBackgrounds
= array();
13348 $this->page
= $new_page;
13349 $this->ResetMargins();
13351 $this->pageoutput
[$this->page
] = array();
13353 $this->y
= (($this->blk
[$this->blklvl
]['float_endpos'] *1000) %
1000000)/1000; // mod changes operands to integers before processing
13355 /*-- END CSS-FLOAT --*/
13357 /*-- CSS-IMAGE-FLOAT --*/
13358 $this->printfloatbuffer();
13359 /*-- END CSS-IMAGE-FLOAT --*/
13361 //Create Internal Links, if needed
13362 if (!empty($this->internallink
) ) {
13363 foreach($this->internallink
as $k=>$v) {
13364 if (strpos($k,"#") !== false ) { continue; } //ignore
13366 $pagenum = $v['PAGE'];
13368 while (array_key_exists($sharp.$k,$this->internallink
)) {
13369 $internallink = $this->internallink
[$sharp.$k];
13370 $this->SetLink($internallink,$ypos,$pagenum);
13376 $this->linemaxfontsize
= '';
13377 $this->lineheight_correction
= $this->default_lineheight_correction
;
13379 $this->bufferoutput
= false;
13381 /*-- CSS-POSITION --*/
13382 if (count($this->fixedPosBlockSave
) && $sub != 4) {
13383 foreach($this->fixedPosBlockSave
AS $fpbs) {
13384 $old_page = $this->page
;
13385 $this->page
= $fpbs[2];
13386 $this->WriteFixedPosHTML($fpbs[0], 0, 0, 100, 100,'auto', $fpbs[1]); // 0,0,10,10 are overwritten by bbox
13387 $this->page
= $old_page;
13390 /*-- END CSS-POSITION --*/
13395 /*-- CSS-POSITION --*/
13397 function WriteFixedPosHTML($html='',$x, $y, $w, $h, $overflow='visible', $bounding=array()) {
13398 // $overflow can be 'hidden', 'visible' or 'auto' - 'auto' causes autofit to size
13399 // Annotations disabled - enabled in mPDF 5.0
13401 // Will always go on current page (or start Page 1 if required)
13402 // Probably INCOMPATIBLE WITH keep with table, columns etc.
13403 // Called externally or interally via <div style="position: [fixed|absolute]">
13404 // When used internally, $x $y $w $h and $overflow are all overridden by $bounding
13406 $overflow = strtolower($overflow);
13407 if($this->state
==0) {
13408 $this->AddPage($this->CurOrientation
);
13410 $save_y = $this->y
;
13411 $save_x = $this->x
;
13412 $this->fullImageHeight
= $this->h
;
13413 $save_cols = false;
13415 if ($this->ColActive
) {
13417 $save_nbcol = $this->NbCol
; // other values of gap and vAlign will not change by setting Columns off
13418 $this->SetColumns(0);
13420 /*-- END COLUMNS --*/
13421 $save_annots = $this->title2annots
; // *ANNOTATIONS*
13422 $this->writingHTMLheader
= true; // a FIX to stop pagebreaks etc.
13423 $this->writingHTMLfooter
= true;
13424 $this->InFooter
= true; // suppresses autopagebreaks
13425 $save_bgs = $this->pageBackgrounds
;
13426 $checkinnerhtml = preg_replace('/\s/','',$html);
13428 if ($w > $this->w
) { $x
= 0; $w
= $this
->w
; }
13429 if ($h > $this->h
) { $y
= 0; $h
= $this
->h
; }
13430 if ($x > $this->w
) { $x
= $this
->w
- $w
; }
13431 if ($y > $this->h
) { $y
= $this
->h
- $h
; }
13433 if (!empty($bounding)) {
13434 // $cont_ containing block = full physical page (position: absolute) or page inside margins (position: fixed)
13435 // $bbox_ Bounding box is the <div> which is positioned absolutely/fixed
13436 // top/left/right/bottom/width/height/background*/border*/padding*/margin* are taken from bounding
13437 // font*[family/size/style/weight]/line-height/text*[align/decoration/transform/indent]/color are transferred to $inner
13438 // as an enclosing <div> (after having checked ID/CLASS)
13439 // $x, $y, $w, $h are inside of $bbox_ = containing box for $inner_
13440 // $inner_ InnerHTML is the contents of that block to be output
13441 $tag = $bounding[0];
13442 $attr = $bounding[1];
13443 $orig_x0 = $bounding[2];
13444 $orig_y0 = $bounding[3];
13446 // As in WriteHTML() initialising
13448 $this->lastblocklevelchange
= 0;
13449 $this->blk
= array();
13450 $this->initialiseBlock($this->blk
[0]);
13452 $this->blk
[0]['width'] =& $this->pgwidth
;
13453 $this->blk
[0]['inner_width'] =& $this->pgwidth
;
13455 $this->blk
[0]['blockContext'] = $this->blockContext
;
13457 $properties = $this->cssmgr
->MergeCSS('BLOCK','BODY','');
13458 $this->setCSS($properties,'','BODY');
13460 $this->initialiseBlock($this->blk
[1]);
13461 $this->blk
[1]['tag'] = $tag;
13462 $this->blk
[1]['attr'] = $attr;
13464 $p = $this->cssmgr
->MergeCSS('BLOCK',$tag,$attr);
13465 if (isset($p['ROTATE']) && ($p['ROTATE']==90 || $p['ROTATE']==-90)) { $rotate
= $p
['ROTATE']; }
13466 else { $rotate
= 0; }
13467 if (isset($p['OVERFLOW'])) { $overflow
= strtolower($p
['OVERFLOW']); }
13468 if (strtolower($p['POSITION']) == 'fixed') {
13469 $cont_w = $this->pgwidth
; // $this->blk[0]['inner_width'];
13470 $cont_h = $this->h
- $this->tMargin
- $this->bMargin
;
13471 $cont_x = $this->lMargin
;
13472 $cont_y = $this->tMargin
;
13475 $cont_w = $this->w
; // ABSOLUTE;
13476 $cont_h = $this->h
;
13481 // Pass on in-line properties to the innerhtml
13483 if (isset($p['TEXT-ALIGN'])) { $css
.= 'text-align: '.strtolower($p
['TEXT-ALIGN']).'; '; }
13484 if (isset($p['TEXT-TRANSFORM'])) { $css
.= 'text-transform: '.strtolower($p
['TEXT-TRANSFORM']).'; '; }
13485 if (isset($p['TEXT-INDENT'])) { $css
.= 'text-indent: '.strtolower($p
['TEXT-INDENT']).'; '; }
13486 if (isset($p['TEXT-DECORATION'])) { $css
.= 'text-decoration: '.strtolower($p
['TEXT-DECORATION']).'; '; }
13487 if (isset($p['FONT-FAMILY'])) { $css
.= 'font-family: '.strtolower($p
['FONT-FAMILY']).'; '; }
13488 if (isset($p['FONT-STYLE'])) { $css
.= 'font-style: '.strtolower($p
['FONT-STYLE']).'; '; }
13489 if (isset($p['FONT-WEIGHT'])) { $css
.= 'font-weight: '.strtolower($p
['FONT-WEIGHT']).'; '; }
13490 if (isset($p['FONT-SIZE'])) { $css
.= 'font-size: '.strtolower($p
['FONT-SIZE']).'; '; }
13491 if (isset($p['LINE-HEIGHT'])) { $css
.= 'line-height: '.strtolower($p
['LINE-HEIGHT']).'; '; }
13492 if (isset($p['TEXT-SHADOW'])) { $css
.= 'text-shadow: '.strtolower($p
['TEXT-SHADOW']).'; '; }
13493 if (isset($p['LETTER-SPACING'])) { $css
.= 'letter-spacing: '.strtolower($p
['LETTER-SPACING']).'; '; }
13494 if (isset($p['FONT-VARIANT'])) { $css
.= 'font-variant: '.strtolower($p
['FONT-VARIANT']).'; '; }
13495 if (isset($p['COLOR'])) { $css
.= 'color: '.strtolower($p
['COLOR']).'; '; }
13496 if (isset($p['Z-INDEX'])) { $css
.= 'z-index: '.$p
['Z-INDEX'].'; '; } // mPDF 5.6.01
13498 $html = '<div style="'.$css.'">'.$html.'</div>';
13500 // Copy over (only) the properties to set for border and background
13502 $pb['MARGIN-TOP'] = $p['MARGIN-TOP'];
13503 $pb['MARGIN-RIGHT'] = $p['MARGIN-RIGHT'];
13504 $pb['MARGIN-BOTTOM'] = $p['MARGIN-BOTTOM'];
13505 $pb['MARGIN-LEFT'] = $p['MARGIN-LEFT'];
13506 $pb['PADDING-TOP'] = $p['PADDING-TOP'];
13507 $pb['PADDING-RIGHT'] = $p['PADDING-RIGHT'];
13508 $pb['PADDING-BOTTOM'] = $p['PADDING-BOTTOM'];
13509 $pb['PADDING-LEFT'] = $p['PADDING-LEFT'];
13510 $pb['BORDER-TOP'] = $p['BORDER-TOP'];
13511 $pb['BORDER-RIGHT'] = $p['BORDER-RIGHT'];
13512 $pb['BORDER-BOTTOM'] = $p['BORDER-BOTTOM'];
13513 $pb['BORDER-LEFT'] = $p['BORDER-LEFT'];
13514 $pb['BORDER-TOP-LEFT-RADIUS-H'] = $p['BORDER-TOP-LEFT-RADIUS-H'];
13515 $pb['BORDER-TOP-LEFT-RADIUS-V'] = $p['BORDER-TOP-LEFT-RADIUS-V'];
13516 $pb['BORDER-TOP-RIGHT-RADIUS-H'] = $p['BORDER-TOP-RIGHT-RADIUS-H'];
13517 $pb['BORDER-TOP-RIGHT-RADIUS-V'] = $p['BORDER-TOP-RIGHT-RADIUS-V'];
13518 $pb['BORDER-BOTTOM-LEFT-RADIUS-H'] = $p['BORDER-BOTTOM-LEFT-RADIUS-H'];
13519 $pb['BORDER-BOTTOM-LEFT-RADIUS-V'] = $p['BORDER-BOTTOM-LEFT-RADIUS-V'];
13520 $pb['BORDER-BOTTOM-RIGHT-RADIUS-H'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-H'];
13521 $pb['BORDER-BOTTOM-RIGHT-RADIUS-V'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-V'];
13522 if (isset($p['BACKGROUND-COLOR'])) { $pb
['BACKGROUND-COLOR'] = $p
['BACKGROUND-COLOR']; }
13523 if (isset($p['BOX-SHADOW'])) { $pb
['BOX-SHADOW'] = $p
['BOX-SHADOW']; }
13524 /*-- BACKGROUNDS --*/
13525 if (isset($p['BACKGROUND-IMAGE'])) { $pb
['BACKGROUND-IMAGE'] = $p
['BACKGROUND-IMAGE']; }
13526 if (isset($p['BACKGROUND-IMAGE-RESIZE'])) { $pb
['BACKGROUND-IMAGE-RESIZE'] = $p
['BACKGROUND-IMAGE-RESIZE']; }
13527 if (isset($p['BACKGROUND-IMAGE-OPACITY'])) { $pb
['BACKGROUND-IMAGE-OPACITY'] = $p
['BACKGROUND-IMAGE-OPACITY']; }
13528 if (isset($p['BACKGROUND-REPEAT'])) { $pb
['BACKGROUND-REPEAT'] = $p
['BACKGROUND-REPEAT']; }
13529 if (isset($p['BACKGROUND-POSITION'])) { $pb
['BACKGROUND-POSITION'] = $p
['BACKGROUND-POSITION']; }
13530 if (isset($p['BACKGROUND-GRADIENT'])) { $pb
['BACKGROUND-GRADIENT'] = $p
['BACKGROUND-GRADIENT']; }
13531 if (isset($p['BACKGROUND-SIZE'])) { $pb
['BACKGROUND-SIZE'] = $p
['BACKGROUND-SIZE']; } // mPDF 5.6.12
13532 if (isset($p['BACKGROUND-ORIGIN'])) { $pb
['BACKGROUND-ORIGIN'] = $p
['BACKGROUND-ORIGIN']; } // mPDF 5.6.12
13533 if (isset($p['BACKGROUND-CLIP'])) { $pb
['BACKGROUND-CLIP'] = $p
['BACKGROUND-CLIP']; } // mPDF 5.6.12
13535 /*-- END BACKGROUNDS --*/
13537 $this->setCSS($pb,'BLOCK',$tag);
13539 //================================================================
13540 $bbox_br = $this->blk
[1]['border_right']['w'];
13541 $bbox_bl = $this->blk
[1]['border_left']['w'];
13542 $bbox_bt = $this->blk
[1]['border_top']['w'];
13543 $bbox_bb = $this->blk
[1]['border_bottom']['w'];
13544 $bbox_pr = $this->blk
[1]['padding_right'];
13545 $bbox_pl = $this->blk
[1]['padding_left'];
13546 $bbox_pt = $this->blk
[1]['padding_top'];
13547 $bbox_pb = $this->blk
[1]['padding_bottom'];
13548 $bbox_mr = $this->blk
[1]['margin_right'];
13549 if (strtolower($p['MARGIN-RIGHT'])=='auto') { $bbox_mr
= 'auto'; }
13550 $bbox_ml = $this->blk
[1]['margin_left'];
13551 if (strtolower($p['MARGIN-LEFT'])=='auto') { $bbox_ml
= 'auto'; }
13552 $bbox_mt = $this->blk
[1]['margin_top'];
13553 if (strtolower($p['MARGIN-TOP'])=='auto') { $bbox_mt
= 'auto'; }
13554 $bbox_mb = $this->blk
[1]['margin_bottom'];
13555 if (strtolower($p['MARGIN-BOTTOM'])=='auto') { $bbox_mb
= 'auto'; }
13556 if (isset($p['LEFT']) && strtolower($p['LEFT'])!='auto') { $bbox_left
= $this
->ConvertSize($p
['LEFT'], $cont_w
, $this
->FontSize
,false); }
13557 else { $bbox_left
= 'auto'; }
13558 if (isset($p['TOP']) && strtolower($p['TOP'])!='auto') { $bbox_top
= $this
->ConvertSize($p
['TOP'], $cont_h
, $this
->FontSize
,false); }
13559 else { $bbox_top
= 'auto'; }
13560 if (isset($p['RIGHT']) && strtolower($p['RIGHT'])!='auto') { $bbox_right
= $this
->ConvertSize($p
['RIGHT'], $cont_w
, $this
->FontSize
,false); }
13561 else { $bbox_right
= 'auto'; }
13562 if (isset($p['BOTTOM']) && strtolower($p['BOTTOM'])!='auto') { $bbox_bottom
= $this
->ConvertSize($p
['BOTTOM'], $cont_h
, $this
->FontSize
,false); }
13563 else { $bbox_bottom
= 'auto'; }
13564 if (isset($p['WIDTH']) && strtolower($p['WIDTH'])!='auto') { $inner_w
= $this
->ConvertSize($p
['WIDTH'], $cont_w
, $this
->FontSize
,false); }
13565 else { $inner_w
= 'auto'; }
13566 if (isset($p['HEIGHT']) && strtolower($p['HEIGHT'])!='auto') { $inner_h
= $this
->ConvertSize($p
['HEIGHT'], $cont_h
, $this
->FontSize
,false); }
13567 else { $inner_h
= 'auto'; }
13569 // If bottom or right pos are set and not left / top - save this to adjust rotated block later
13571 if ($bbox_left === 'auto' && $bbox_right !== 'auto') { $rot_rpos
= $bbox_right
; }
13572 else { $rot_rpos
= false; }
13573 if ($bbox_top === 'auto' && $bbox_bottom !== 'auto') { $rot_bpos
= $bbox_bottom
; }
13574 else { $rot_bpos
= false; }
13577 //================================================================
13578 if ($checkinnerhtml=='' && $inner_h==='auto') { $inner_h
= 0.0001; }
13579 if ($checkinnerhtml=='' && $inner_w==='auto') { $inner_w
= 2*$this
->GetCharWidth('W',false); }
13580 //================================================================
13581 // Algorithm from CSS2.1 See http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height
13583 // Special case (not CSS) if all not specified, centre vertically on page
13584 if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom==='auto' && $bbox_mt==='auto' && $bbox_mb==='auto') {
13585 $bbox_top_orig = $bbox_top;
13586 if ($bbox_mt==='auto') { $bbox_mt
= 0; }
13587 if ($bbox_mb==='auto') { $bbox_mb
= 0; }
13588 $bbox_top = $orig_y0 - $bbox_mt - $cont_y;
13589 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13592 else if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom==='auto') {
13593 $bbox_top_orig = $bbox_top = $orig_y0 - $cont_y;
13594 if ($bbox_mt==='auto') { $bbox_mt
= 0; }
13595 if ($bbox_mb==='auto') { $bbox_mb
= 0; }
13596 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13598 else if ($bbox_top!=='auto' && $inner_h!=='auto' && $bbox_bottom!=='auto') {
13599 if ($bbox_mt==='auto' && $bbox_mb==='auto') {
13600 $x = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
13601 $bbox_mt = $bbox_mb = ($x/2);
13603 else if ($bbox_mt==='auto') {
13604 $bbox_mt = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13606 else if ($bbox_mb==='auto') {
13607 $bbox_mb = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
13610 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13614 if ($bbox_mt==='auto') { $bbox_mt
= 0; }
13615 if ($bbox_mb==='auto') { $bbox_mb
= 0; }
13616 if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom!=='auto') {
13617 // solve for $bbox_top when content_h known - $inner_h=='auto' && $bbox_top =='auto'
13619 else if ($bbox_top==='auto' && $bbox_bottom==='auto' && $inner_h!=='auto') {
13620 $bbox_top = $orig_y0 - $bbox_mt - $cont_y;
13621 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13623 else if ($inner_h==='auto' && $bbox_bottom==='auto' && $bbox_top!=='auto') {
13624 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13626 else if ($bbox_top==='auto' && $inner_h!=='auto' && $bbox_bottom!=='auto') {
13627 $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
13629 else if ($inner_h==='auto' && $bbox_top!=='auto' && $bbox_bottom!=='auto') {
13630 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
13632 else if ($bbox_bottom==='auto' && $bbox_top!=='auto' && $inner_h!=='auto') {
13633 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13637 // THEN DO SAME FOR WIDTH
13638 // http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
13639 if ($bbox_left==='auto' && $inner_w==='auto' && $bbox_right==='auto') {
13640 if ($bbox_ml==='auto') { $bbox_ml
= 0; }
13641 if ($bbox_mr==='auto') { $bbox_mr
= 0; }
13642 // IF containing element RTL, should set $bbox_right
13643 $bbox_left = $orig_x0 - $bbox_ml - $cont_x;
13644 // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
13646 else if ($bbox_left!=='auto' && $inner_w!=='auto' && $bbox_right!=='auto') {
13647 if ($bbox_ml==='auto' && $bbox_mr==='auto') {
13648 $x = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
13649 $bbox_ml = $bbox_mr = ($x/2);
13651 else if ($bbox_ml==='auto') {
13652 $bbox_ml = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
13654 else if ($bbox_mr==='auto') {
13655 $bbox_mr = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
13658 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13662 if ($bbox_ml==='auto') { $bbox_ml
= 0; }
13663 if ($bbox_mr==='auto') { $bbox_mr
= 0; }
13664 if ($bbox_left==='auto' && $inner_w==='auto' && $bbox_right!=='auto') {
13665 // solve for $bbox_left when content_w known - $inner_w=='auto' && $bbox_left =='auto'
13667 else if ($bbox_left==='auto' && $bbox_right==='auto' && $inner_w!=='auto') {
13668 // IF containing element RTL, should set $bbox_right
13669 $bbox_left = $orig_x0 - $bbox_ml - $cont_x;
13670 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13672 else if ($inner_w==='auto' && $bbox_right==='auto' && $bbox_left!=='auto') {
13673 // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
13675 else if ($bbox_left==='auto' && $inner_w!=='auto' && $bbox_right!=='auto') {
13676 $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
13678 else if ($inner_w==='auto' && $bbox_left!=='auto' && $bbox_right!=='auto') {
13679 $inner_w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
13681 else if ($bbox_right==='auto' && $bbox_left!=='auto' && $inner_w!=='auto') {
13682 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13686 //================================================================
13687 //================================================================
13688 /*-- BACKGROUNDS --*/
13689 if (isset($pb['BACKGROUND-IMAGE']) && $pb['BACKGROUND-IMAGE']) {
13690 $ret = $this->SetBackground($pb, $this->blk
[1]['inner_width']);
13691 if ($ret) { $this
->blk
[1]['background-image'] = $ret
; }
13693 /*-- END BACKGROUNDS --*/
13695 //================================================================
13696 $y = $cont_y +
$bbox_top +
$bbox_mt +
$bbox_bt +
$bbox_pt;
13697 $h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13698 $x = $cont_x +
$bbox_left +
$bbox_ml +
$bbox_bl +
$bbox_pl;
13699 $w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
13700 // Set (temporary) values for x y w h to do first paint, if values are auto
13701 if ($inner_h==='auto' && $bbox_top==='auto') {
13702 $y = $cont_y +
$bbox_mt +
$bbox_bt +
$bbox_pt;
13703 $h = $cont_h - ($bbox_bottom +
$bbox_mt +
$bbox_mb +
$bbox_bt +
$bbox_bb +
$bbox_pt +
$bbox_pb);
13705 else if ($inner_h==='auto' && $bbox_bottom==='auto') {
13706 $y = $cont_y +
$bbox_top +
$bbox_mt +
$bbox_bt +
$bbox_pt;
13707 $h = $cont_h - ($bbox_top +
$bbox_mt +
$bbox_mb +
$bbox_bt +
$bbox_bb +
$bbox_pt +
$bbox_pb);
13709 if ($inner_w==='auto' && $bbox_left==='auto') {
13710 $x = $cont_x +
$bbox_ml +
$bbox_bl +
$bbox_pl;
13711 $w = $cont_w - ($bbox_right +
$bbox_ml +
$bbox_mr +
$bbox_bl +
$bbox_br +
$bbox_pl +
$bbox_pr);
13713 else if ($inner_w==='auto' && $bbox_right==='auto') {
13714 $x = $cont_x +
$bbox_left +
$bbox_ml +
$bbox_bl +
$bbox_pl;
13715 $w = $cont_w - ($bbox_left +
$bbox_ml +
$bbox_mr +
$bbox_bl +
$bbox_br +
$bbox_pl +
$bbox_pr);
13717 $bbox_y = $cont_y +
$bbox_top +
$bbox_mt;
13718 $bbox_x = $cont_x +
$bbox_left +
$bbox_ml;
13719 $saved_block1 = $this->blk
[1];
13722 //================================================================
13723 if ($inner_w==='auto') { // do a first write
13725 $this->rMargin
=$this->w
- $w - $x;
13726 // SET POSITION & FONT VALUES
13727 $this->pgwidth
= $this->w
- $this->lMargin
- $this->rMargin
;
13728 $this->pageoutput
[$this->page
]=array();
13731 $this->HTMLheaderPageLinks
= array();
13732 $this->HTMLheaderPageAnnots
= array();
13733 $this->HTMLheaderPageForms
= array();
13734 $this->pageBackgrounds
= array();
13735 $this->maxPosR
= 0;
13736 $this->maxPosL
= $this->w
; // For RTL
13737 $this->WriteHTML($html , 4);
13738 $inner_w = $this->maxPosR
- $this->lMargin
;
13739 if ($bbox_right==='auto') {
13740 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13742 else if ($bbox_left==='auto') {
13743 $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
13744 $bbox_x = $cont_x +
$bbox_left +
$bbox_ml ;
13745 $inner_x = $bbox_x +
$bbox_bl +
$bbox_pl;
13749 $bbox_y = $cont_y +
$bbox_top +
$bbox_mt;
13750 $bbox_x = $cont_x +
$bbox_left +
$bbox_ml;
13753 if ($inner_h==='auto') { // do a first write
13755 $this->rMargin
=$this->w
- $w - $x;
13756 // SET POSITION & FONT VALUES
13757 $this->pgwidth
= $this->w
- $this->lMargin
- $this->rMargin
;
13758 $this->pageoutput
[$this->page
]=array();
13761 $this->HTMLheaderPageLinks
= array();
13762 $this->HTMLheaderPageAnnots
= array();
13763 $this->HTMLheaderPageForms
= array();
13764 $this->pageBackgrounds
= array();
13765 $this->WriteHTML($html , 4);
13766 $inner_h = $this->y
- $y;
13767 if ($overflow!='hidden' && $overflow!='visible') { // constrained
13768 if (($this->y +
$bbox_pb +
$bbox_bb) > ($cont_y +
$cont_h)) {
13769 $adj = ($this->y +
$bbox_pb +
$bbox_bb) - ($cont_y +
$cont_h);
13773 if ($bbox_bottom==='auto' && $bbox_top_orig==='auto') {
13774 $bbox_bottom = $bbox_top = ($cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb)/2;
13775 if ($overflow!='hidden' && $overflow!='visible') { // constrained
13776 if ($bbox_top < 0) {
13778 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13781 $bbox_y = $cont_y +
$bbox_top +
$bbox_mt;
13782 $inner_y = $bbox_y +
$bbox_bt +
$bbox_pt;
13786 else if ($bbox_bottom==='auto') {
13787 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb;
13789 else if ($bbox_top==='auto') {
13790 $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13791 if ($overflow!='hidden' && $overflow!='visible') { // constrained
13792 if ($bbox_top < 0) {
13794 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13797 $bbox_y = $cont_y +
$bbox_top +
$bbox_mt;
13798 $inner_y = $bbox_y +
$bbox_bt +
$bbox_pt;
13802 $bbox_y = $cont_y +
$bbox_top +
$bbox_mt;
13803 $bbox_x = $cont_x +
$bbox_left +
$bbox_ml;
13810 $this->rMargin
=$this->w
- $w - $x;
13811 // SET POSITION & FONT VALUES
13812 $this->pgwidth
= $this->w
- $this->lMargin
- $this->rMargin
;
13813 $this->pageoutput
[$this->page
]=array();
13816 $this->HTMLheaderPageLinks
= array();
13817 $this->HTMLheaderPageAnnots
= array();
13818 $this->HTMLheaderPageForms
= array();
13819 $this->pageBackgrounds
= array();
13820 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
13821 $actual_h = $this->y
- $y;
13824 $ratio = $actual_h / $use_w;
13826 if ($overflow!='hidden' && $overflow!='visible') {
13828 if (($ratio / $target ) > 1) {
13829 $nl = CEIL($actual_h / $this->lineheight
);
13831 $est_w = sqrt(($l * $this->lineheight
) / $target) * 0.8;
13832 $use_w +
= ($est_w - $use_w) - ($w/100);
13834 $bpcstart = ($ratio / $target);
13836 while(($ratio / $target ) > 1) {
13838 if ($this->progressBar
) { $this
->UpdateProgressBar(4,intval(100/($ratio
/$target
)),('Auto-sizing fixed-position block: '.$bpcctr++
)); } // *PROGRESS-BAR*
13843 if (($ratio / $target) > 1.5 || ($ratio / $target) < 0.6) {
13844 $use_w +
= ($w/$this->incrementFPR1
);
13846 else if (($ratio / $target) > 1.2 || ($ratio / $target) < 0.85) {
13847 $use_w +
= ($w/$this->incrementFPR2
);
13849 else if (($ratio / $target) > 1.1 || ($ratio / $target) < 0.91) {
13850 $use_w +
= ($w/$this->incrementFPR3
);
13853 $use_w +
= ($w/$this->incrementFPR4
);
13856 $use_h = $use_w * $target ;
13857 $this->rMargin
=$this->w
- $use_w - $x;
13858 $this->pgwidth
= $this->w
- $this->lMargin
- $this->rMargin
;
13859 $this->HTMLheaderPageLinks
= array();
13860 $this->HTMLheaderPageAnnots
= array();
13861 $this->HTMLheaderPageForms
= array();
13862 $this->pageBackgrounds
= array();
13863 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
13864 $actual_h = $this->y
- $y;
13865 $ratio = $actual_h / $use_w;
13867 if ($this->progressBar
) { $this
->UpdateProgressBar(4,'100',' '); } // *PROGRESS-BAR*
13869 $shrink_f = $w/$use_w;
13871 //================================================================
13873 $this->pages
[$this->page
] .= '___BEFORE_BORDERS___';
13874 $block_s = $this->PrintPageBackgrounds(); // Save to print later inside clipping path
13875 $this->pageBackgrounds
= array();
13877 //================================================================
13880 $prerotw = $bbox_bl +
$bbox_pl +
$inner_w +
$bbox_pr +
$bbox_br;
13881 $preroth = $bbox_bt +
$bbox_pt +
$inner_h +
$bbox_pb +
$bbox_bb;
13882 $rot_start = " q\n";
13883 if ($rotate == 90) {
13884 if ($rot_rpos !== false) { $adjw
= $prerotw
; } // width before rotation
13885 else { $adjw
= $preroth
; } // height before rotation
13886 if ($rot_bpos !== false) { $adjh
= -$prerotw + $preroth
; }
13887 else { $adjh
= 0; }
13890 if ($rot_rpos !== false) { $adjw
= $prerotw
- $preroth
; }
13891 else { $adjw
= 0; }
13892 if ($rot_bpos !== false) { $adjh
= $preroth
; } // height before rotation
13893 else { $adjh
= $prerotw
; } // width before rotation
13895 $rot_start .= $this->transformTranslate($adjw, $adjh, true)."\n";
13896 $rot_start .= $this->transformRotate($rotate, $bbox_x, $bbox_y, true)."\n";
13904 //================================================================
13905 if (!empty($bounding)) {
13906 // WHEN HEIGHT // BOTTOM EDGE IS KNOWN and $this->y is set to the bottom
13907 // Re-instate saved $this->blk[1]
13908 $this->blk
[1] = $saved_block1;
13910 // These are only needed when painting border/background
13911 $this->blk
[1]['width'] = $bbox_w = $cont_w - $bbox_left - $bbox_ml - $bbox_mr - $bbox_right;
13912 $this->blk
[1]['x0'] = $bbox_x;
13913 $this->blk
[1]['y0'] = $bbox_y;
13914 $this->blk
[1]['startpage'] = $this->page
;
13915 $this->blk
[1]['y1'] = $bbox_y +
$bbox_bt +
$bbox_pt +
$inner_h +
$bbox_pb +
$bbox_bb ;
13916 $this->_out($rot_start); // mPDF 5.0
13917 $this->PaintDivBB('',0,1); // Prints borders and sets backgrounds in $this->pageBackgrounds
13918 $this->_out($rot_end);
13921 $s = $this->PrintPageBackgrounds();
13922 $s = $rot_start.$s.$rot_end;
13923 $this->pages
[$this->page
] = preg_replace('/___BEFORE_BORDERS___/', "\n".$s."\n", $this->pages
[$this->page
]);
13924 $this->pageBackgrounds
= array();
13926 $this->_out($rot_start);
13929 if ($overflow=='hidden') {
13930 //Bounding rectangle to clip
13931 $clip_y1 = $this->y
;
13932 if (!empty($bounding) && ($this->y +
$bbox_pb +
$bbox_bb) > ($bbox_y +
$bbox_bt +
$bbox_pt +
$inner_h +
$bbox_pb +
$bbox_bb )) {
13933 $clip_y1 = ($bbox_y +
$bbox_bt +
$bbox_pt +
$inner_h +
$bbox_pb +
$bbox_bb ) - ($bbox_pb +
$bbox_bb);
13935 //$op = 'W* n'; // Clipping
13936 $op = 'W n'; // Clipping alternative mode
13938 $ch = $clip_y1 - $y;
13939 $this->_out(sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK
,($this->h
-$y)*_MPDFK
,$w*_MPDFK
,-$ch*_MPDFK
,$op));
13940 if (!empty($block_s)) {
13941 $tmp = "q\n".sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK
,($this->h
-$y)*_MPDFK
,$w*_MPDFK
,-$ch*_MPDFK
,$op);
13942 $tmp .= "\n".$block_s."\nQ";
13948 if (!empty($block_s)) {
13949 if ($shrink_f != 1) { // i.e. autofit has resized the box
13950 $tmp = "q\n".$this->transformScale(($shrink_f*100),($shrink_f*100), $x, $y, true);
13951 $tmp .= "\n".$block_s."\nQ";
13954 $this->_out($block_s);
13959 if ($shrink_f != 1) { // i.e. autofit has resized the box
13960 $this->StartTransform();
13961 $this->transformScale(($shrink_f*100),($shrink_f*100), $x, $y);
13964 $this->_out($this->headerbuffer
);
13966 if ($shrink_f != 1) { // i.e. autofit has resized the box
13967 $this->StopTransform();
13970 if ($overflow=='hidden') {
13975 $this->_out($rot_end);
13979 foreach($this->HTMLheaderPageLinks
AS $lk) {
13981 $tmp = $lk[2]; // Switch h - w
13985 $lx1 = (($lk[0]/_MPDFK
));
13986 $ly1 = (($this->h
-($lk[1]/_MPDFK
)));
13987 if ($rotate == 90) {
13988 $adjx = -($lx1-$bbox_x) +
($preroth - ($ly1-$bbox_y));
13989 $adjy = -($ly1-$bbox_y) +
($lx1-$bbox_x);
13992 else if ($rotate == -90) {
13993 $adjx = -($lx1-$bbox_x) +
($ly1-$bbox_y);
13994 $adjy = -($ly1-$bbox_y) - ($lx1-$bbox_x) +
$prerotw;
13997 if ($rot_rpos !== false) { $adjx +
= $prerotw
- $preroth
; }
13998 if ($rot_bpos !== false) { $adjy +
= $preroth
- $prerotw
; }
14002 $lk[0] = $lx1*_MPDFK
;
14003 $lk[1] = ($this->h
-$ly1)*_MPDFK
;
14005 if ($shrink_f != 1) { // i.e. autofit has resized the box
14006 $lx1 = (($lk[0]/_MPDFK
)-$x);
14007 $lx2 = $x +
($lx1 * $shrink_f);
14008 $lk[0] = $lx2*_MPDFK
;
14009 $ly1 = (($this->h
-($lk[1]/_MPDFK
))-$y);
14010 $ly2 = $y +
($ly1 * $shrink_f);
14011 $lk[1] = ($this->h
-$ly2)*_MPDFK
;
14012 $lk[2] *= $shrink_f; // width
14013 $lk[3] *= $shrink_f; // height
14015 $this->PageLinks
[$this->page
][]=$lk;
14018 foreach($this->HTMLheaderPageForms
AS $n=>$f) {
14019 if ($shrink_f != 1) { // i.e. autofit has resized the box
14020 $f['x'] = $x +
(($f['x'] -$x) * $shrink_f);
14021 $f['y'] = $y +
(($f['y'] -$y) * $shrink_f);
14022 $f['w'] *= $shrink_f;
14023 $f['h'] *= $shrink_f;
14024 $f['style']['fontsize'] *= $shrink_f;
14026 $this->form
->forms
[$f['n']] = $f;
14028 // Page Annotations
14029 foreach($this->HTMLheaderPageAnnots
AS $lk) {
14031 if ($rotate == 90) {
14032 $adjx = -($lk['x']-$bbox_x) +
($preroth - ($lk['y']-$bbox_y));
14033 $adjy = -($lk['y']-$bbox_y) +
($lk['x']-$bbox_x);
14035 else if ($rotate == -90) {
14036 $adjx = -($lk['x']-$bbox_x) +
($lk['y']-$bbox_y);
14037 $adjy = -($lk['y']-$bbox_y) - ($lk['x']-$bbox_x) +
$prerotw;
14039 if ($rot_rpos !== false) { $adjx +
= $prerotw
- $preroth
; }
14040 if ($rot_bpos !== false) { $adjy +
= $preroth
- $prerotw
; }
14044 if ($shrink_f != 1) { // i.e. autofit has resized the box
14045 $lk['x'] = $x +
(($lk['x']-$x) * $shrink_f);
14046 $lk['y'] = $y +
(($lk['y']-$y) * $shrink_f);
14048 $this->PageAnnots
[$this->page
][]=$lk;
14052 $this->headerbuffer
= '';
14053 $this->HTMLheaderPageLinks
= array();
14054 $this->HTMLheaderPageAnnots
= array();
14055 $this->HTMLheaderPageForms
= array();
14056 $this->pageBackgrounds
= $save_bgs;
14057 $this->writingHTMLheader
= false;
14059 $this->writingHTMLfooter
= false;
14060 $this->fullImageHeight
= false;
14061 $this->ResetMargins();
14062 $this->pgwidth
= $this->w
- $this->lMargin
- $this->rMargin
;
14063 $this->SetXY($save_x,$save_y) ;
14064 $this->title2annots
= $save_annots; // *ANNOTATIONS*
14065 $this->InFooter
= false; // turns back on autopagebreaks
14066 $this->pageoutput
[$this->page
]=array();
14067 $this->pageoutput
[$this->page
]['Font']='';
14070 $this->SetColumns($save_nbcol,$this->colvAlign
,$this->ColGap
);
14072 /*-- END COLUMNS --*/
14074 /*-- END CSS-POSITION --*/
14078 function initialiseBlock(&$blk) {
14079 $blk['margin_top'] = 0;
14080 $blk['margin_left'] = 0;
14081 $blk['margin_bottom'] = 0;
14082 $blk['margin_right'] = 0;
14083 $blk['padding_top'] = 0;
14084 $blk['padding_left'] = 0;
14085 $blk['padding_bottom'] = 0;
14086 $blk['padding_right'] = 0;
14087 $blk['border_top']['w'] = 0;
14088 $blk['border_left']['w'] = 0;
14089 $blk['border_bottom']['w'] = 0;
14090 $blk['border_right']['w'] = 0;
14091 $blk['hide'] = false;
14092 $blk['outer_left_margin'] = 0;
14093 $blk['outer_right_margin'] = 0;
14094 $blk['cascadeCSS'] = array();
14095 $blk['block-align'] = false;
14096 $blk['bgcolor'] = false;
14097 $blk['page_break_after_avoid'] = false;
14098 $blk['keep_block_together'] = false;
14099 $blk['float'] = false;
14100 $blk['line_height'] = '';
14101 $blk['margin_collapse'] = false;
14105 function border_details($bd) {
14106 $prop = preg_split('/\s+/',trim($bd));
14108 if (isset($this->blk
[$this->blklvl
]['inner_width'])) { $refw
= $this
->blk
[$this
->blklvl
]['inner_width']; }
14109 else if (isset($this->blk
[$this->blklvl
-1]['inner_width'])) { $refw
= $this
->blk
[$this
->blklvl
-1]['inner_width']; }
14110 else { $refw
= $this
->w
; }
14111 if ( count($prop) == 1 ) {
14112 $bsize = $this->ConvertSize($prop[0],$refw,$this->FontSize
,false);
14114 return array('s' => 1, 'w' => $bsize, 'c' => $this->ConvertColor(0), 'style'=>'solid');
14116 else {
return array('w' => 0, 's' => 0); }
14119 else if (count($prop) == 2 ) {
14121 if (in_array($prop[1],$this->borderstyles
) || $prop[1] == 'none' || $prop[1] == 'hidden' ) { $prop
[2] = ''; }
14123 else if (in_array($prop[0],$this->borderstyles
) || $prop[0] == 'none' || $prop[0] == 'hidden' ) { $prop
[0] = ''; $prop
[1] = $prop
[0]; $prop
[2] = $prop
[1]; }
14125 else { $prop
[1] = ''; $prop
[2] = $prop
[1]; }
14127 else if ( count($prop) == 3 ) {
14128 // Change #000000 1px solid to 1px solid #000000 (proper)
14129 if (substr($prop[0],0,1) == '#') { $tmp
= $prop
[0]; $prop
[0] = $prop
[1]; $prop
[1] = $prop
[2]; $prop
[2] = $tmp
; }
14130 // Change solid #000000 1px to 1px solid #000000 (proper)
14131 else if (substr($prop[0],1,1) == '#') { $tmp
= $prop
[1]; $prop
[0] = $prop
[2]; $prop
[1] = $prop
[0]; $prop
[2] = $tmp
; }
14132 // Change solid 1px #000000 to 1px solid #000000 (proper)
14133 else if (in_array($prop[0],$this->borderstyles
) || $prop[0] == 'none' || $prop[0] == 'hidden' ) {
14134 $tmp = $prop[0]; $prop[0] = $prop[1]; $prop[1] = $tmp;
14137 else {
return array(); }
14139 $bsize = $this->ConvertSize($prop[0],$refw,$this->FontSize
,false);
14141 $coul = $this->ConvertColor($prop[2]); // returns array
14143 $prop[1] = strtolower($prop[1]);
14144 if (in_array($prop[1],$this->borderstyles
) && $bsize > 0) { $on
= 1; }
14145 else if ($prop[1] == 'hidden') { $on
= 1; $bsize
= 0; $coul
= ''; }
14146 else if ($prop[1] == 'none') { $on
= 0; $bsize
= 0; $coul
= ''; }
14147 else { $on
= 0; $bsize
= 0; $coul
= ''; $prop
[1] = ''; }
14148 return array('s' => $on, 'w' => $bsize, 'c' => $coul, 'style'=> $prop[1] );
14153 /*-- END HTML-CSS --*/
14156 // Return either a number (factor) - based on current set fontsize (if % or em) - or exact lineheight (with 'mm' after it)
14157 function fixLineheight($v) {
14159 if (preg_match('/^[0-9\.,]*$/',$v) && $v >= 0) { return ($v +
0); }
14160 else if (strtoupper($v) == 'NORMAL') {
14161 return $this->normalLineheight
;
14164 $tlh = $this->ConvertSize($v,$this->FontSize
,$this->FontSize
,true);
14165 if ($tlh) { return ($tlh
.'mm'); }
14167 return $this->normalLineheight
;
14171 /*-- BORDER-RADIUS --*/
14172 function _borderPadding($a, $b, &$px, &$py) {
14173 // $px and py are padding long axis (x) and short axis (y)
14174 $added = 0; // extra padding
14178 // Check if Falls within ellipse of border radius
14179 if ( ( (($x+
$added)*($x+
$added))/($a*$a) +
(($y+
$added)*($y+
$added))/($b*$b) ) <=1 ) { return false; }
14183 $newx = $b / sqrt((($b*$b)/($a*$a)) +
( tan($t) * tan($t) ) );
14184 $newy = $a / sqrt((($a*$a)/($b*$b)) +
( (1/tan($t)) * (1/tan($t)) ) );
14185 $px = max($px, $a - $newx +
$added);
14186 $py = max($py, $b - $newy +
$added);
14188 /*-- END BORDER-RADIUS --*/
14196 function SetPagedMediaCSS($name='', $first, $oddEven) {
14197 if ($oddEven == 'E') {
14198 if ($this->directionality
=='rtl') { $side
= 'R'; }
14199 else { $side
= 'L'; }
14202 if ($this->directionality
=='rtl') { $side
= 'L'; }
14203 else { $side
= 'R'; }
14205 $name = strtoupper($name);
14207 $p['SIZE'] = 'AUTO';
14209 // Uses mPDF original margins as default
14210 $p['MARGIN-RIGHT'] = strval($this->orig_rMargin
).'mm';
14211 $p['MARGIN-LEFT'] = strval($this->orig_lMargin
).'mm';
14212 $p['MARGIN-TOP'] = strval($this->orig_tMargin
).'mm';
14213 $p['MARGIN-BOTTOM'] = strval($this->orig_bMargin
).'mm';
14214 $p['MARGIN-HEADER'] = strval($this->orig_hMargin
).'mm';
14215 $p['MARGIN-FOOTER'] = strval($this->orig_fMargin
).'mm';
14217 // Basic page + selector
14218 if (isset($this->cssmgr
->CSS
['@PAGE'])) { $zp
= $this
->cssmgr
->CSS
['@PAGE']; }
14219 else { $zp
= array(); }
14220 if (is_array($zp) && !empty($zp)) { $p
= array_merge($p
,$zp
); }
14222 if (isset($p['EVEN-HEADER-NAME']) && $oddEven=='E') {
14223 $p['HEADER'] = $p['EVEN-HEADER-NAME']; unset($p['EVEN-HEADER-NAME']);
14225 if (isset($p['ODD-HEADER-NAME']) && $oddEven!='E') {
14226 $p['HEADER'] = $p['ODD-HEADER-NAME']; unset($p['ODD-HEADER-NAME']);
14228 if (isset($p['EVEN-FOOTER-NAME']) && $oddEven=='E') {
14229 $p['FOOTER'] = $p['EVEN-FOOTER-NAME']; unset($p['EVEN-FOOTER-NAME']);
14231 if (isset($p['ODD-FOOTER-NAME']) && $oddEven!='E') {
14232 $p['FOOTER'] = $p['ODD-FOOTER-NAME']; unset($p['ODD-FOOTER-NAME']);
14235 // If right/Odd page
14236 if (isset($this->cssmgr
->CSS
['@PAGE>>PSEUDO>>RIGHT']) && $side=='R') {
14237 $zp = $this->cssmgr
->CSS
['@PAGE>>PSEUDO>>RIGHT'];
14239 else { $zp
= array(); }
14240 if (isset($zp['SIZE'])) { unset($zp
['SIZE']); }
14241 if (isset($zp['SHEET-SIZE'])) { unset($zp
['SHEET-SIZE']); }
14242 // Disallow margin-left or -right on :LEFT or :RIGHT
14243 if (isset($zp['MARGIN-LEFT'])) { unset($zp
['MARGIN-LEFT']); }
14244 if (isset($zp['MARGIN-RIGHT'])) { unset($zp
['MARGIN-RIGHT']); }
14245 if (is_array($zp) && !empty($zp)) { $p
= array_merge($p
,$zp
); }
14247 // If left/Even page
14248 if (isset($this->cssmgr
->CSS
['@PAGE>>PSEUDO>>LEFT']) && $side=='L') {
14249 $zp = $this->cssmgr
->CSS
['@PAGE>>PSEUDO>>LEFT'];
14251 else { $zp
= array(); }
14252 if (isset($zp['SIZE'])) { unset($zp
['SIZE']); }
14253 if (isset($zp['SHEET-SIZE'])) { unset($zp
['SHEET-SIZE']); }
14254 // Disallow margin-left or -right on :LEFT or :RIGHT
14255 if (isset($zp['MARGIN-LEFT'])) { unset($zp
['MARGIN-LEFT']); }
14256 if (isset($zp['MARGIN-RIGHT'])) { unset($zp
['MARGIN-RIGHT']); }
14257 if (is_array($zp) && !empty($zp)) { $p
= array_merge($p
,$zp
); }
14260 if (isset($this->cssmgr
->CSS
['@PAGE>>PSEUDO>>FIRST']) && $first) { $zp
= $this
->cssmgr
->CSS
['@PAGE>>PSEUDO>>FIRST']; }
14261 else { $zp
= array(); }
14262 if (isset($zp['SIZE'])) { unset($zp
['SIZE']); }
14263 if (isset($zp['SHEET-SIZE'])) { unset($zp
['SHEET-SIZE']); }
14264 if (is_array($zp) && !empty($zp)) { $p
= array_merge($p
,$zp
); }
14268 if (isset($this->cssmgr
->CSS
['@PAGE>>NAMED>>'.$name])) { $zp
= $this
->cssmgr
->CSS
['@PAGE>>NAMED>>'.$name
]; }
14269 else { $zp
= array(); }
14270 if (is_array($zp) && !empty($zp)) { $p
= array_merge($p
,$zp
); }
14272 if (isset($p['EVEN-HEADER-NAME']) && $oddEven=='E') {
14273 $p['HEADER'] = $p['EVEN-HEADER-NAME']; unset($p['EVEN-HEADER-NAME']);
14275 if (isset($p['ODD-HEADER-NAME']) && $oddEven!='E') {
14276 $p['HEADER'] = $p['ODD-HEADER-NAME']; unset($p['ODD-HEADER-NAME']);
14278 if (isset($p['EVEN-FOOTER-NAME']) && $oddEven=='E') {
14279 $p['FOOTER'] = $p['EVEN-FOOTER-NAME']; unset($p['EVEN-FOOTER-NAME']);
14281 if (isset($p['ODD-FOOTER-NAME']) && $oddEven!='E') {
14282 $p['FOOTER'] = $p['ODD-FOOTER-NAME']; unset($p['ODD-FOOTER-NAME']);
14285 // If named right/Odd page
14286 if (isset($this->cssmgr
->CSS
['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>RIGHT']) && $side=='R') { $zp
= $this
->cssmgr
->CSS
['@PAGE>>NAMED>>'.$name
.'>>PSEUDO>>RIGHT']; }
14287 else { $zp
= array(); }
14288 if (isset($zp['SIZE'])) { unset($zp
['SIZE']); }
14289 if (isset($zp['SHEET-SIZE'])) { unset($zp
['SHEET-SIZE']); }
14290 // Disallow margin-left or -right on :LEFT or :RIGHT
14291 if (isset($zp['MARGIN-LEFT'])) { unset($zp
['MARGIN-LEFT']); }
14292 if (isset($zp['MARGIN-RIGHT'])) { unset($zp
['MARGIN-RIGHT']); }
14293 if (is_array($zp) && !empty($zp)) { $p
= array_merge($p
,$zp
); }
14295 // If named left/Even page
14296 if (isset($this->cssmgr
->CSS
['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>LEFT']) && $side=='L') { $zp
= $this
->cssmgr
->CSS
['@PAGE>>NAMED>>'.$name
.'>>PSEUDO>>LEFT']; }
14297 else { $zp
= array(); }
14298 if (isset($zp['SIZE'])) { unset($zp
['SIZE']); }
14299 if (isset($zp['SHEET-SIZE'])) { unset($zp
['SHEET-SIZE']); }
14300 // Disallow margin-left or -right on :LEFT or :RIGHT
14301 if (isset($zp['MARGIN-LEFT'])) { unset($zp
['MARGIN-LEFT']); }
14302 if (isset($zp['MARGIN-RIGHT'])) { unset($zp
['MARGIN-RIGHT']); }
14303 if (is_array($zp) && !empty($zp)) { $p
= array_merge($p
,$zp
); }
14305 // If named first page
14306 if (isset($this->cssmgr
->CSS
['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>FIRST']) && $first) { $zp
= $this
->cssmgr
->CSS
['@PAGE>>NAMED>>'.$name
.'>>PSEUDO>>FIRST']; }
14307 else { $zp
= array(); }
14308 if (isset($zp['SIZE'])) { unset($zp
['SIZE']); }
14309 if (isset($zp['SHEET-SIZE'])) { unset($zp
['SHEET-SIZE']); }
14310 if (is_array($zp) && !empty($zp)) { $p
= array_merge($p
,$zp
); }
14313 $orientation = $mgl = $mgr = $mgt = $mgb = $mgh = $mgf = '';
14314 $header = $footer = '';
14315 $resetpagenum = $pagenumstyle = $suppress = '';
14322 if (isset($p['SHEET-SIZE']) && is_array($p['SHEET-SIZE'])) {
14323 $newformat = $p['SHEET-SIZE'];
14324 if ($newformat[0] > $newformat[1]) { // landscape
14325 $newformat = array_reverse($newformat);
14326 $p['ORIENTATION'] = 'L';
14328 else { $p
['ORIENTATION'] = 'P'; }
14329 $this->_setPageSize($newformat, $p['ORIENTATION']);
14332 if (isset($p['SIZE']) && is_array($p['SIZE']) && !$newformat) {
14333 if ($p['SIZE']['W'] > $p['SIZE']['H']) { $p
['ORIENTATION'] = 'L'; }
14334 else { $p
['ORIENTATION'] = 'P'; }
14336 if (is_array($p['SIZE'])) {
14337 if ($p['SIZE']['W'] > $this->fw
) { $p
['SIZE']['W'] = $this
->fw
; } // mPD 4.2 use fw not fPt
14338 if ($p['SIZE']['H'] > $this->fh
) { $p
['SIZE']['H'] = $this
->fh
; }
14339 if (($p['ORIENTATION']==$this->DefOrientation
&& !$newformat) || ($newformat && $p['ORIENTATION']=='P')) {
14340 $outer_width_LR = ($this->fw
- $p['SIZE']['W'])/2;
14341 $outer_width_TB = ($this->fh
- $p['SIZE']['H'])/2;
14344 $outer_width_LR = ($this->fh
- $p['SIZE']['W'])/2;
14345 $outer_width_TB = ($this->fw
- $p['SIZE']['H'])/2;
14347 $pgw = $p['SIZE']['W'];
14348 $pgh = $p['SIZE']['H'];
14350 else { // AUTO LANDSCAPE PORTRAIT
14351 $outer_width_LR = 0;
14352 $outer_width_TB = 0;
14354 if (strtoupper($p['SIZE']) == 'AUTO') { $p
['ORIENTATION']=$this
->DefOrientation
; }
14355 else if (strtoupper($p['SIZE']) == 'LANDSCAPE') { $p
['ORIENTATION']='L'; }
14356 else { $p
['ORIENTATION']='P'; }
14358 if (($p['ORIENTATION']==$this->DefOrientation
&& !$newformat) || ($newformat && $p['ORIENTATION']=='P')) {
14368 if (isset($p['HEADER']) && $p['HEADER']) { $header
= $p
['HEADER']; }
14369 if (isset($p['FOOTER']) && $p['FOOTER']) { $footer
= $p
['FOOTER']; }
14370 if (isset($p['RESETPAGENUM']) && $p['RESETPAGENUM']) { $resetpagenum
= $p
['RESETPAGENUM']; }
14371 if (isset($p['PAGENUMSTYLE']) && $p['PAGENUMSTYLE']) { $pagenumstyle
= $p
['PAGENUMSTYLE']; }
14372 if (isset($p['SUPPRESS']) && $p['SUPPRESS']) { $suppress
= $p
['SUPPRESS']; }
14374 if (preg_match('/cross/i', $p['MARKS']) && preg_match('/crop/i', $p['MARKS'])) { $marks
= 'CROPCROSS'; }
14375 else if (strtoupper($p['MARKS']) == 'CROP') { $marks
= 'CROP'; }
14376 else if (strtoupper($p['MARKS']) == 'CROSS') { $marks
= 'CROSS'; }
14379 if (isset($p['BACKGROUND-COLOR']) && $p['BACKGROUND-COLOR']) { $bg
['BACKGROUND-COLOR'] = $p
['BACKGROUND-COLOR']; }
14380 /*-- BACKGROUNDS --*/
14381 if (isset($p['BACKGROUND-GRADIENT']) && $p['BACKGROUND-GRADIENT']) { $bg
['BACKGROUND-GRADIENT'] = $p
['BACKGROUND-GRADIENT']; }
14382 if (isset($p['BACKGROUND-IMAGE']) && $p['BACKGROUND-IMAGE']) { $bg
['BACKGROUND-IMAGE'] = $p
['BACKGROUND-IMAGE']; }
14383 if (isset($p['BACKGROUND-REPEAT']) && $p['BACKGROUND-REPEAT']) { $bg
['BACKGROUND-REPEAT'] = $p
['BACKGROUND-REPEAT']; }
14384 if (isset($p['BACKGROUND-POSITION']) && $p['BACKGROUND-POSITION']) { $bg
['BACKGROUND-POSITION'] = $p
['BACKGROUND-POSITION']; }
14385 if (isset($p['BACKGROUND-IMAGE-RESIZE']) && $p['BACKGROUND-IMAGE-RESIZE']) { $bg
['BACKGROUND-IMAGE-RESIZE'] = $p
['BACKGROUND-IMAGE-RESIZE']; }
14386 if (isset($p['BACKGROUND-IMAGE-OPACITY'])) { $bg
['BACKGROUND-IMAGE-OPACITY'] = $p
['BACKGROUND-IMAGE-OPACITY']; }
14387 /*-- END BACKGROUNDS --*/
14389 if (isset($p['MARGIN-LEFT'])) { $mgl
= $this
->ConvertSize($p
['MARGIN-LEFT'],$pgw
) + $outer_width_LR
; }
14390 if (isset($p['MARGIN-RIGHT'])) { $mgr
= $this
->ConvertSize($p
['MARGIN-RIGHT'],$pgw
) + $outer_width_LR
; }
14391 if (isset($p['MARGIN-BOTTOM'])) { $mgb
= $this
->ConvertSize($p
['MARGIN-BOTTOM'],$pgh
) + $outer_width_TB
; }
14392 if (isset($p['MARGIN-TOP'])) { $mgt
= $this
->ConvertSize($p
['MARGIN-TOP'],$pgh
) + $outer_width_TB
; }
14393 if (isset($p['MARGIN-HEADER'])) { $mgh
= $this
->ConvertSize($p
['MARGIN-HEADER'],$pgh
) + $outer_width_TB
; }
14394 if (isset($p['MARGIN-FOOTER'])) { $mgf
= $this
->ConvertSize($p
['MARGIN-FOOTER'],$pgh
) + $outer_width_TB
; }
14396 if (isset($p['ORIENTATION']) && $p['ORIENTATION']) { $orientation
= $p
['ORIENTATION']; }
14397 $this->page_box
['outer_width_LR'] = $outer_width_LR; // Used in MARKS:crop etc.
14398 $this->page_box
['outer_width_TB'] = $outer_width_TB;
14400 return array($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$header,$footer,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat);
14402 /*-- END CSS-PAGE --*/
14406 /*-- CSS-FLOAT --*/
14407 // Added mPDF 3.0 Float DIV - CLEAR
14408 function ClearFloats($clear, $blklvl=0) {
14409 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($blklvl,true);
14410 $end = $currpos = ($this->page
*1000 +
$this->y
);
14411 if ($clear == 'BOTH' && ($l_exists || $r_exists)) {
14412 $this->pageoutput
[$this->page
] = array();
14413 $end = max($l_max, $r_max, $currpos);
14415 else if ($clear == 'RIGHT' && $r_exists) {
14416 $this->pageoutput
[$this->page
] = array();
14417 $end = max($r_max, $currpos);
14419 else if ($clear == 'LEFT' && $l_exists ) {
14420 $this->pageoutput
[$this->page
] = array();
14421 $end = max($l_max, $currpos);
14424 $old_page = $this->page
;
14425 $new_page = intval($end/1000);
14426 if ($old_page != $new_page) {
14427 $s = $this->PrintPageBackgrounds();
14428 // Writes after the marker so not overwritten later by page background etc.
14429 $this->pages
[$this->page
] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages
[$this->page
]);
14430 $this->pageBackgrounds
= array();
14431 $this->page
= $new_page;
14433 $this->ResetMargins();
14434 $this->pageoutput
[$this->page
] = array();
14435 $this->y
= (($end*1000) %
1000000)/1000; // mod changes operands to integers before processing
14439 // Added mPDF 3.0 Float DIV
14440 function GetFloatDivInfo($blklvl=0,$clear=false) {
14441 // If blklvl specified, only returns floats at that level - for ClearFloats
14448 if (count($this->floatDivs
)) {
14449 $currpos = ($this->page
*1000 +
$this->y
);
14450 foreach($this->floatDivs
AS $f) {
14451 if (($clear && $f['blockContext'] == $this->blk
[$blklvl]['blockContext']) || (!$clear && $currpos >= $f['startpos'] && $currpos < ($f['endpos']-0.001) && $f['blklvl'] > $blklvl && $f['blockContext'] == $this->blk
[$blklvl]['blockContext'])) {
14452 if ($f['side']=='L') {
14454 $l_max = max($l_max, $f['endpos']);
14455 $l_width = max($l_width , $f['w']);
14457 if ($f['side']=='R') {
14459 $r_max = max($r_max, $f['endpos']);
14460 $r_width = max($r_width , $f['w']);
14465 return array($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width);
14467 /*-- END CSS-FLOAT --*/
14472 function OpenTag($tag,$attr)
14475 // What this gets: < $tag $attr['WIDTH']="90px" > does not get content here </closeTag here>
14476 // Correct tags where HTML specifies optional end tags,
14477 // and/or does not allow nesting e.g. P inside P, or
14478 if ($this->allow_html_optional_endtags
) {
14479 if (($tag == 'P' || $tag == 'DIV' || $tag == 'H1' || $tag == 'H2' || $tag == 'H3' || $tag == 'H4' || $tag == 'H5' || $tag == 'H6' || $tag == 'UL' || $tag == 'OL' || $tag == 'TABLE' || $tag=='PRE' || $tag=='FORM' || $tag=='ADDRESS' || $tag=='BLOCKQUOTE' || $tag=='CENTER' || $tag=='DL' || $tag == 'HR' ) && $this->lastoptionaltag
== 'P') { $this
->CloseTag($this
->lastoptionaltag
); }
14480 if ($tag == 'DD' && $this->lastoptionaltag
== 'DD') { $this
->CloseTag($this
->lastoptionaltag
); }
14481 if ($tag == 'DD' && $this->lastoptionaltag
== 'DT') { $this
->CloseTag($this
->lastoptionaltag
); }
14482 if ($tag == 'DT' && $this->lastoptionaltag
== 'DD') { $this
->CloseTag($this
->lastoptionaltag
); }
14483 if ($tag == 'DT' && $this->lastoptionaltag
== 'DT') { $this
->CloseTag($this
->lastoptionaltag
); }
14484 if ($tag == 'LI' && $this->lastoptionaltag
== 'LI') { $this
->CloseTag($this
->lastoptionaltag
); }
14485 if (($tag == 'TD' || $tag == 'TH') && $this->lastoptionaltag
== 'TD') { $this
->CloseTag($this
->lastoptionaltag
); } // *TABLES*
14486 if (($tag == 'TD' || $tag == 'TH') && $this->lastoptionaltag
== 'TH') { $this
->CloseTag($this
->lastoptionaltag
); } // *TABLES*
14487 if ($tag == 'TR' && $this->lastoptionaltag
== 'TR') { $this
->CloseTag($this
->lastoptionaltag
); } // *TABLES*
14488 if ($tag == 'TR' && $this->lastoptionaltag
== 'TD') { $this
->CloseTag($this
->lastoptionaltag
); $this
->CloseTag('TR'); $this
->CloseTag('THEAD'); } // *TABLES*
14489 if ($tag == 'TR' && $this->lastoptionaltag
== 'TH') { $this
->CloseTag($this
->lastoptionaltag
); $this
->CloseTag('TR'); $this
->CloseTag('THEAD'); } // *TABLES*
14490 if ($tag == 'OPTION' && $this->lastoptionaltag
== 'OPTION') { $this
->CloseTag($this
->lastoptionaltag
); }
14493 $align = array('left'=>'L','center'=>'C','right'=>'R','top'=>'T','text-top'=>'TT','middle'=>'M','baseline'=>'BS','bottom'=>'B','text-bottom'=>'TB','justify'=>'J');
14495 $this->ignorefollowingspaces
=false;
14501 $objattr = array();
14502 $objattr['type'] = 'dottab';
14503 $dots=str_repeat('.', 3)." "; // minimum number of dots
14504 $objattr['width'] = $this->GetStringWidth($dots);
14505 $objattr['margin_top'] = 0;
14506 $objattr['margin_bottom'] = 0;
14507 $objattr['margin_left'] = 0;
14508 $objattr['margin_right'] = 0;
14509 $objattr['height'] = 0;
14510 $objattr['colorarray'] = $this->colorarray
;
14511 $objattr['border_top']['w'] = 0;
14512 $objattr['border_bottom']['w'] = 0;
14513 $objattr['border_left']['w'] = 0;
14514 $objattr['border_right']['w'] = 0;
14517 $properties = $this->cssmgr
->MergeCSS('INLINE',$tag,$attr); // mPDF 5.6.33
14518 if (isset($properties['OUTDENT'])) { // mPDF 5.6.33
14519 $objattr['outdent'] = $this->ConvertSize($properties['OUTDENT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
14521 else if (isset($attr['OUTDENT'])) {
14522 $objattr['outdent'] = $this->ConvertSize($attr['OUTDENT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
14524 else { $objattr
['outdent'] = 0; }
14526 $objattr['fontfamily'] = $this->FontFamily
;
14527 $objattr['fontsize'] = $this->FontSizePt
;
14529 $e = "\xbb\xa4\xactype=dottab,objattr=".serialize($objattr)."\xbb\xa4\xac";
14531 // Output it to buffers
14532 if ($this->tableLevel
) {
14533 if (!isset($this->cell
[$this->row
][$this->col
]['maxs'])) {
14534 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
14536 elseif($this->cell
[$this->row
][$this->col
]['maxs'] < $this->cell
[$this->row
][$this->col
]['s']) {
14537 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
14539 $this->cell
[$this->row
][$this->col
]['s'] = 0 ;// reset
14540 $this->_saveCellTextBuffer($e);
14543 /*-- END TABLES --*/
14544 $this->_saveTextBuffer($e);
14550 $this->ignorefollowingspaces
= true;
14551 if ($attr['NAME']) { $pname
= $attr
['NAME']; }
14552 else { $pname
= '_default'; }
14554 if ($tag=='PAGEHEADER') { $p
= &$this
->pageheaders
[$pname
]; }
14555 else { $p
= &$this
->pagefooters
[$pname
]; }
14560 $p['L']['font-style'] = '';
14561 $p['C']['font-style'] = '';
14562 $p['R']['font-style'] = '';
14564 if (isset($attr['CONTENT-LEFT'])) {
14565 $p['L']['content'] = $attr['CONTENT-LEFT'];
14567 if (isset($attr['CONTENT-CENTER'])) {
14568 $p['C']['content'] = $attr['CONTENT-CENTER'];
14570 if (isset($attr['CONTENT-RIGHT'])) {
14571 $p['R']['content'] = $attr['CONTENT-RIGHT'];
14574 if (isset($attr['HEADER-STYLE']) || isset($attr['FOOTER-STYLE'])) { // font-family,size,weight,style,color
14575 if ($tag=='PAGEHEADER') { $properties
= $this
->cssmgr
->readInlineCSS($attr
['HEADER-STYLE']); }
14576 else { $properties
= $this
->cssmgr
->readInlineCSS($attr
['FOOTER-STYLE']); }
14577 if (isset($properties['FONT-FAMILY'])) {
14578 $p['L']['font-family'] = $properties['FONT-FAMILY'];
14579 $p['C']['font-family'] = $properties['FONT-FAMILY'];
14580 $p['R']['font-family'] = $properties['FONT-FAMILY'];
14582 if (isset($properties['FONT-SIZE'])) {
14583 $p['L']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK
;
14584 $p['C']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK
;
14585 $p['R']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK
;
14587 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') {
14588 $p['L']['font-style'] = 'B';
14589 $p['C']['font-style'] = 'B';
14590 $p['R']['font-style'] = 'B';
14592 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') {
14593 $p['L']['font-style'] .= 'I';
14594 $p['C']['font-style'] .= 'I';
14595 $p['R']['font-style'] .= 'I';
14597 if (isset($properties['COLOR'])) {
14598 $p['L']['color'] = $properties['COLOR'];
14599 $p['C']['color'] = $properties['COLOR'];
14600 $p['R']['color'] = $properties['COLOR'];
14603 if (isset($attr['HEADER-STYLE-LEFT']) || isset($attr['FOOTER-STYLE-LEFT'])) {
14604 if ($tag=='PAGEHEADER') { $properties
= $this
->cssmgr
->readInlineCSS($attr
['HEADER-STYLE-LEFT']); }
14605 else { $properties
= $this
->cssmgr
->readInlineCSS($attr
['FOOTER-STYLE-LEFT']); }
14606 if (isset($properties['FONT-FAMILY'])) { $p
['L']['font-family'] = $properties
['FONT-FAMILY']; }
14607 if (isset($properties['FONT-SIZE'])) { $p
['L']['font-size'] = $this
->ConvertSize($properties
['FONT-SIZE']) * _MPDFK
; }
14608 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p
['L']['font-style'] ='B'; }
14609 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p
['L']['font-style'] .='I'; }
14610 if (isset($properties['COLOR'])) { $p
['L']['color'] = $properties
['COLOR']; }
14612 if (isset($attr['HEADER-STYLE-CENTER']) || isset($attr['FOOTER-STYLE-CENTER'])) {
14613 if ($tag=='PAGEHEADER') { $properties
= $this
->cssmgr
->readInlineCSS($attr
['HEADER-STYLE-CENTER']); }
14614 else { $properties
= $this
->cssmgr
->readInlineCSS($attr
['FOOTER-STYLE-CENTER']); }
14615 if (isset($properties['FONT-FAMILY'])) { $p
['C']['font-family'] = $properties
['FONT-FAMILY']; }
14616 if (isset($properties['FONT-SIZE'])) { $p
['C']['font-size'] = $this
->ConvertSize($properties
['FONT-SIZE']) * _MPDFK
; }
14617 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p
['C']['font-style'] = 'B'; }
14618 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p
['C']['font-style'] .= 'I'; }
14619 if (isset($properties['COLOR'])) { $p
['C']['color'] = $properties
['COLOR']; }
14621 if (isset($attr['HEADER-STYLE-RIGHT']) || isset($attr['FOOTER-STYLE-RIGHT'])) {
14622 if ($tag=='PAGEHEADER') { $properties
= $this
->cssmgr
->readInlineCSS($attr
['HEADER-STYLE-RIGHT']); }
14623 else { $properties
= $this
->cssmgr
->readInlineCSS($attr
['FOOTER-STYLE-RIGHT']); }
14624 if (isset($properties['FONT-FAMILY'])) { $p
['R']['font-family'] = $properties
['FONT-FAMILY']; }
14625 if (isset($properties['FONT-SIZE'])) { $p
['R']['font-size'] = $this
->ConvertSize($properties
['FONT-SIZE']) * _MPDFK
; }
14626 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p
['R']['font-style'] = 'B'; }
14627 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p
['R']['font-style'] .= 'I'; }
14628 if (isset($properties['COLOR'])) { $p
['R']['color'] = $properties
['COLOR']; }
14630 if (isset($attr['LINE']) && $attr['LINE']) { // 0|1|on|off
14631 if ($attr['LINE']=='1' || strtoupper($attr['LINE'])=='ON') { $lineset
=1; }
14632 else { $lineset
=0; }
14633 $p['line'] = $lineset;
14638 /*-- HTMLHEADERS-FOOTERS --*/
14639 case 'SETHTMLPAGEHEADER':
14640 case 'SETHTMLPAGEFOOTER':
14641 $this->ignorefollowingspaces
= true;
14642 if (isset($attr['NAME']) && $attr['NAME']) { $pname
= $attr
['NAME']; }
14643 else { $pname
= '_default'; }
14644 if (isset($attr['PAGE']) && $attr['PAGE']) { // O|odd|even|E|ALL|[blank]
14645 if (strtoupper($attr['PAGE'])=='O' || strtoupper($attr['PAGE'])=='ODD') { $side
='odd'; }
14646 else if (strtoupper($attr['PAGE'])=='E' || strtoupper($attr['PAGE'])=='EVEN') { $side
='even'; }
14647 else if (strtoupper($attr['PAGE'])=='ALL') { $side
='both'; }
14648 else { $side
='odd'; }
14650 else { $side
='odd'; }
14651 if (isset($attr['VALUE']) && $attr['VALUE']) { // -1|1|on|off
14652 if ($attr['VALUE']=='1' || strtoupper($attr['VALUE'])=='ON') { $set
=1; }
14653 else if ($attr['VALUE']=='-1' || strtoupper($attr['VALUE'])=='OFF') { $set
=0; }
14657 if (isset($attr['SHOW-THIS-PAGE']) && $attr['SHOW-THIS-PAGE'] && $tag=='SETHTMLPAGEHEADER') { $write
= 1; }
14658 else { $write
= 0; }
14659 if ($side=='odd' || $side=='both') {
14660 if ($set && $tag=='SETHTMLPAGEHEADER') { $this
->SetHTMLHeader($this
->pageHTMLheaders
[$pname
],'O',$write
); }
14661 else if ($set && $tag=='SETHTMLPAGEFOOTER') { $this
->SetHTMLFooter($this
->pageHTMLfooters
[$pname
],'O'); }
14662 else if ($tag=='SETHTMLPAGEHEADER') { $this
->SetHTMLHeader('','O'); }
14663 else { $this
->SetHTMLFooter('','O'); }
14665 if ($side=='even' || $side=='both') {
14666 if ($set && $tag=='SETHTMLPAGEHEADER') { $this
->SetHTMLHeader($this
->pageHTMLheaders
[$pname
],'E',$write
); }
14667 else if ($set && $tag=='SETHTMLPAGEFOOTER') { $this
->SetHTMLFooter($this
->pageHTMLfooters
[$pname
],'E'); }
14668 else if ($tag=='SETHTMLPAGEHEADER') { $this
->SetHTMLHeader('','E'); }
14669 else { $this
->SetHTMLFooter('','E'); }
14672 /*-- END HTMLHEADERS-FOOTERS --*/
14674 case 'SETPAGEHEADER':
14675 case 'SETPAGEFOOTER':
14676 $this->ignorefollowingspaces
= true;
14677 if (isset($attr['NAME']) && $attr['NAME']) { $pname
= $attr
['NAME']; }
14678 else { $pname
= '_default'; }
14679 if (isset($attr['PAGE']) && $attr['PAGE']) { // O|odd|even|E|ALL|[blank]
14680 if (strtoupper($attr['PAGE'])=='O' || strtoupper($attr['PAGE'])=='ODD') { $side
='odd'; }
14681 else if (strtoupper($attr['PAGE'])=='E' || strtoupper($attr['PAGE'])=='EVEN') { $side
='even'; }
14682 else if (strtoupper($attr['PAGE'])=='ALL') { $side
='both'; }
14683 else { $side
='odd'; }
14685 else { $side
='odd'; }
14686 if (isset($attr['VALUE']) && $attr['VALUE']) { // -1|1|on|off
14687 if ($attr['VALUE']=='1' || strtoupper($attr['VALUE'])=='ON') { $set
=1; }
14688 else if ($attr['VALUE']=='-1' || strtoupper($attr['VALUE'])=='OFF') { $set
=0; }
14692 if ($side=='odd' || $side=='both') {
14693 if ($set && $tag=='SETPAGEHEADER') { $this
->headerDetails
['odd'] = $this
->pageheaders
[$pname
]; }
14694 else if ($set && $tag=='SETPAGEFOOTER') { $this
->footerDetails
['odd'] = $this
->pagefooters
[$pname
]; }
14695 else if ($tag=='SETPAGEHEADER') { $this
->headerDetails
['odd'] = array(); }
14696 else { $this
->footerDetails
['odd'] = array(); }
14697 if (!$this->mirrorMargins
|| ($this->page
)%
2!=0) { // ODD
14698 if ($tag=='SETPAGEHEADER') { $this
->_setAutoHeaderHeight($this
->headerDetails
['odd'],$this
->HTMLHeader
); }
14699 if ($tag=='SETPAGEFOOTER') { $this
->_setAutoFooterHeight($this
->footerDetails
['odd'],$this
->HTMLFooter
); }
14702 if ($side=='even' || $side=='both') {
14703 if ($set && $tag=='SETPAGEHEADER') { $this
->headerDetails
['even'] = $this
->pageheaders
[$pname
]; }
14704 else if ($set && $tag=='SETPAGEFOOTER') { $this
->footerDetails
['even'] = $this
->pagefooters
[$pname
]; }
14705 else if ($tag=='SETPAGEHEADER') { $this
->headerDetails
['even'] = array(); }
14706 else { $this
->footerDetails
['even'] = array(); }
14707 if ($this->mirrorMargins
&& ($this->page
)%
2==0) { // EVEN
14708 if ($tag=='SETPAGEHEADER') { $this
->_setAutoHeaderHeight($this
->headerDetails
['even'],$this
->HTMLHeaderE
); }
14709 if ($tag=='SETPAGEFOOTER') { $this
->_setAutoFooterHeight($this
->footerDetails
['even'],$this
->HTMLFooterE
); }
14712 if (isset($attr['SHOW-THIS-PAGE']) && $attr['SHOW-THIS-PAGE'] && $tag=='SETPAGEHEADER') {
14719 case 'TOC': //added custom-tag - set Marker for insertion later of ToC
14720 if (!class_exists('tocontents', false)) { include(_MPDF_PATH
.'classes/tocontents.php'); }
14721 if (empty($this->tocontents
)) { $this
->tocontents
= new tocontents($this
); }
14722 $this->tocontents
->openTagTOC($attr);
14727 case 'TOCPAGEBREAK': // custom-tag - set Marker for insertion later of ToC AND adds PAGEBREAK
14728 if (!class_exists('tocontents', false)) { include(_MPDF_PATH
.'classes/tocontents.php'); }
14729 if (empty($this->tocontents
)) { $this
->tocontents
= new tocontents($this
); }
14730 list($isbreak,$toc_id) = $this->tocontents
->openTagTOCPAGEBREAK($attr);
14731 if ($isbreak) break;
14732 // No break - continues as PAGEBREAK...
14736 case 'PAGE_BREAK': //custom-tag
14737 case 'PAGEBREAK': //custom-tag
14738 case 'NEWPAGE': //custom-tag
14739 case 'FORMFEED': //custom-tag
14741 $save_blklvl = $this->blklvl
;
14742 $save_blk = $this->blk
;
14743 $save_silp = $this->saveInlineProperties();
14744 $save_spanlvl = $this->spanlvl
;
14745 $save_ilp = $this->InlineProperties
;
14747 // Close any open block tags
14748 for ($b= $this->blklvl
;$b>0;$b--) { $this
->CloseTag($this
->blk
[$b
]['tag']); }
14749 if(!empty($this->textbuffer
)) { //Output previously buffered content
14750 $this->printbuffer($this->textbuffer
);
14751 $this->textbuffer
=array();
14753 $this->ignorefollowingspaces
= true;
14754 $save_cols = false;
14756 if ($this->ColActive
) {
14758 $save_nbcol = $this->NbCol
; // other values of gap and vAlign will not change by setting Columns off
14759 $this->SetColumns(0);
14761 /*-- END COLUMNS --*/
14764 if (isset($attr['SHEET-SIZE']) && $tag != 'FORMFEED' && !$this->restoreBlockPageBreaks
) {
14765 // Convert to same types as accepted in initial mPDF() A4, A4-L, or array(w,h)
14766 $prop = preg_split('/\s+/',trim($attr['SHEET-SIZE']));
14767 if (count($prop) == 2 ) {
14768 $newformat = array($this->ConvertSize($prop[0]), $this->ConvertSize($prop[1]));
14770 else { $newformat
= $attr
['SHEET-SIZE']; }
14772 else { $newformat
= ''; }
14774 $mgr = $mgl = $mgt = $mgb = $mgh = $mgf = '';
14775 if (isset($attr['MARGIN-RIGHT'])) { $mgr
= $this
->ConvertSize($attr
['MARGIN-RIGHT'],$this
->w
,$this
->FontSize
,false); }
14776 if (isset($attr['MARGIN-LEFT'])) { $mgl
= $this
->ConvertSize($attr
['MARGIN-LEFT'],$this
->w
,$this
->FontSize
,false); }
14777 if (isset($attr['MARGIN-TOP'])) { $mgt
= $this
->ConvertSize($attr
['MARGIN-TOP'],$this
->w
,$this
->FontSize
,false); }
14778 if (isset($attr['MARGIN-BOTTOM'])) { $mgb
= $this
->ConvertSize($attr
['MARGIN-BOTTOM'],$this
->w
,$this
->FontSize
,false); }
14779 if (isset($attr['MARGIN-HEADER'])) { $mgh
= $this
->ConvertSize($attr
['MARGIN-HEADER'],$this
->w
,$this
->FontSize
,false); }
14780 if (isset($attr['MARGIN-FOOTER'])) { $mgf
= $this
->ConvertSize($attr
['MARGIN-FOOTER'],$this
->w
,$this
->FontSize
,false); }
14781 $ohname = $ehname = $ofname = $efname = '';
14782 if (isset($attr['ODD-HEADER-NAME'])) { $ohname
= $attr
['ODD-HEADER-NAME']; }
14783 if (isset($attr['EVEN-HEADER-NAME'])) { $ehname
= $attr
['EVEN-HEADER-NAME']; }
14784 if (isset($attr['ODD-FOOTER-NAME'])) { $ofname
= $attr
['ODD-FOOTER-NAME']; }
14785 if (isset($attr['EVEN-FOOTER-NAME'])) { $efname
= $attr
['EVEN-FOOTER-NAME']; }
14786 $ohvalue = $ehvalue = $ofvalue = $efvalue = 0;
14787 if (isset($attr['ODD-HEADER-VALUE']) && ($attr['ODD-HEADER-VALUE']=='1' || strtoupper($attr['ODD-HEADER-VALUE'])=='ON')) { $ohvalue
= 1; }
14788 else if (isset($attr['ODD-HEADER-VALUE']) && ($attr['ODD-HEADER-VALUE']=='-1' || strtoupper($attr['ODD-HEADER-VALUE'])=='OFF')) { $ohvalue
= -1; }
14789 if (isset($attr['EVEN-HEADER-VALUE']) && ($attr['EVEN-HEADER-VALUE']=='1' || strtoupper($attr['EVEN-HEADER-VALUE'])=='ON')) { $ehvalue
= 1; }
14790 else if (isset($attr['EVEN-HEADER-VALUE']) && ($attr['EVEN-HEADER-VALUE']=='-1' || strtoupper($attr['EVEN-HEADER-VALUE'])=='OFF')) { $ehvalue
= -1; }
14791 if (isset($attr['ODD-FOOTER-VALUE']) && ($attr['ODD-FOOTER-VALUE']=='1' || strtoupper($attr['ODD-FOOTER-VALUE'])=='ON')) { $ofvalue
= 1; }
14792 else if (isset($attr['ODD-FOOTER-VALUE']) && ($attr['ODD-FOOTER-VALUE']=='-1' || strtoupper($attr['ODD-FOOTER-VALUE'])=='OFF')) { $ofvalue
= -1; }
14793 if (isset($attr['EVEN-FOOTER-VALUE']) && ($attr['EVEN-FOOTER-VALUE']=='1' || strtoupper($attr['EVEN-FOOTER-VALUE'])=='ON')) { $efvalue
= 1; }
14794 else if (isset($attr['EVEN-FOOTER-VALUE']) && ($attr['EVEN-FOOTER-VALUE']=='-1' || strtoupper($attr['EVEN-FOOTER-VALUE'])=='OFF')) { $efvalue
= -1; }
14796 if (isset($attr['ORIENTATION']) && (strtoupper($attr['ORIENTATION'])=='L' || strtoupper($attr['ORIENTATION'])=='LANDSCAPE')) { $orient
= 'L'; }
14797 else if (isset($attr['ORIENTATION']) && (strtoupper($attr['ORIENTATION'])=='P' || strtoupper($attr['ORIENTATION'])=='PORTRAIT')) { $orient
= 'P'; }
14798 else { $orient
= $this
->CurOrientation
; }
14800 if (isset($attr['PAGE-SELECTOR']) && $attr['PAGE-SELECTOR']) { $pagesel
= $attr
['PAGE-SELECTOR']; }
14801 else { $pagesel
= ''; }
14803 $resetpagenum = '';
14804 $pagenumstyle = '';
14806 if (isset($attr['RESETPAGENUM'])) { $resetpagenum
= $attr
['RESETPAGENUM']; }
14807 if (isset($attr['PAGENUMSTYLE'])) { $pagenumstyle
= $attr
['PAGENUMSTYLE']; }
14808 if (isset($attr['SUPPRESS'])) { $suppress
= $attr
['SUPPRESS']; }
14810 if ($tag == 'TOCPAGEBREAK') { $type
= 'NEXT-ODD'; }
14811 else if(isset($attr['TYPE'])) { $type
= strtoupper($attr
['TYPE']); }
14812 else { $type
= ''; }
14814 if ($type == 'E' || $type == 'EVEN') { $this
->AddPage($orient
,'E', $resetpagenum
, $pagenumstyle
, $suppress
,$mgl
,$mgr
,$mgt
,$mgb
,$mgh
,$mgf
,$ohname
,$ehname
,$ofname
,$efname
,$ohvalue
,$ehvalue
,$ofvalue
,$efvalue
,$pagesel
,$newformat
); }
14815 else if ($type == 'O' || $type == 'ODD') { $this
->AddPage($orient
,'O', $resetpagenum
, $pagenumstyle
, $suppress
,$mgl
,$mgr
,$mgt
,$mgb
,$mgh
,$mgf
,$ohname
,$ehname
,$ofname
,$efname
,$ohvalue
,$ehvalue
,$ofvalue
,$efvalue
,$pagesel
,$newformat
); }
14816 else if ($type == 'NEXT-ODD') { $this
->AddPage($orient
,'NEXT-ODD', $resetpagenum
, $pagenumstyle
, $suppress
,$mgl
,$mgr
,$mgt
,$mgb
,$mgh
,$mgf
,$ohname
,$ehname
,$ofname
,$efname
,$ohvalue
,$ehvalue
,$ofvalue
,$efvalue
,$pagesel
,$newformat
); }
14817 else if ($type == 'NEXT-EVEN') { $this
->AddPage($orient
,'NEXT-EVEN', $resetpagenum
, $pagenumstyle
, $suppress
,$mgl
,$mgr
,$mgt
,$mgb
,$mgh
,$mgf
,$ohname
,$ehname
,$ofname
,$efname
,$ohvalue
,$ehvalue
,$ofvalue
,$efvalue
,$pagesel
,$newformat
); }
14818 else { $this
->AddPage($orient
,'', $resetpagenum
, $pagenumstyle
, $suppress
,$mgl
,$mgr
,$mgt
,$mgb
,$mgh
,$mgf
,$ohname
,$ehname
,$ofname
,$efname
,$ohvalue
,$ehvalue
,$ofvalue
,$efvalue
,$pagesel
,$newformat
); }
14821 if ($tag == 'TOCPAGEBREAK') {
14822 if ($toc_id) { $this
->tocontents
->m_TOC
[$toc_id
]['TOCmark'] = $this
->page
; }
14823 else { $this
->tocontents
->TOCmark
= $this
->page
; }
14830 $this->SetColumns($save_nbcol,$this->colvAlign
,$this->ColGap
);
14832 /*-- END COLUMNS --*/
14833 if (($tag == 'FORMFEED' || $this->restoreBlockPagebreaks
) && !$this->tableLevel
&& !$this->listlvl
) {
14834 $this->blk
= $save_blk;
14835 // Re-open block tags
14836 $t = $this->blk
[0]['tag'];
14837 $a = $this->blk
[0]['attr'];
14839 for ($b=0; $b<=$save_blklvl;$b++
) {
14842 $t = $this->blk
[$b+
1]['tag'];
14843 $a = $this->blk
[$b+
1]['attr'];
14844 unset($this->blk
[$b+
1]);
14845 $this->OpenTag($tc,$ac);
14847 $this->spanlvl
= $save_spanlvl;
14848 $this->InlineProperties
= $save_ilp;
14849 $this->restoreInlineProperties($save_silp);
14857 if (isset($attr['CONTENT']) && $attr['CONTENT']) {
14858 $objattr = array();
14859 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES
);
14860 $objattr['type'] = 'toc';
14861 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr
['toclevel'] = $attr
['LEVEL']; } else { $objattr
['toclevel'] = 0; }
14862 if (isset($attr['NAME']) && $attr['NAME']) { $objattr
['toc_id'] = $attr
['NAME']; } else { $objattr
['toc_id'] = 0; }
14863 $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
14864 if($this->tableLevel
) { $this
->cell
[$this
->row
][$this
->col
]['textbuffer'][] = array($e
); } // *TABLES*
14866 $this->textbuffer
[] = array($e);
14874 if (isset($attr['CONTENT']) && $attr['CONTENT']) {
14875 if (isset($attr['XREF']) && $attr['XREF']) {
14876 $this->IndexEntry(htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES
),$attr['XREF']);
14879 $objattr = array();
14880 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES
);
14881 $objattr['type'] = 'indexentry';
14882 $e = "\xbb\xa4\xactype=indexentry,objattr=".serialize($objattr)."\xbb\xa4\xac";
14883 if($this->tableLevel
) { $this
->cell
[$this
->row
][$this
->col
]['textbuffer'][] = array($e
); } // *TABLES*
14885 $this->textbuffer
[] = array($e);
14891 case 'INDEXINSERT':
14892 if (isset($attr['FONT-SIZE'])) { $reffontsize
= $attr
['FONT-SIZE']; } else { $reffontsize
= ''; }
14893 if (isset($attr['LINE-SPACING']) && $attr['LINE-SPACING']) { $linespacing
= $attr
['LINE-SPACING']; } else { $linespacing
= ''; }
14894 if (isset($attr['DIV-FONT-SIZE']) && $attr['DIV-FONT-SIZE']) { $divlettfontsize
= $attr
['DIV-FONT-SIZE']; } else { $divlettfontsize
= ''; }
14895 if (isset($attr['FONT']) && $attr['FONT']) { $reffont
= $attr
['FONT']; } else { $reffont
= ''; }
14896 if (isset($attr['DIV-FONT']) && $attr['DIV-FONT']) { $divlettfont
= $attr
['DIV-FONT']; } else { $divlettfont
= ''; }
14897 if (isset($attr['COLS']) && $attr['COLS']) { $cols
= $attr
['COLS']; } else { $cols
= 1; }
14898 if (isset($attr['OFFSET']) && $attr['OFFSET']) { $offset
= $attr
['OFFSET']; } else { $offset
= 3; }
14899 if (isset($attr['GAP']) && $attr['GAP']) { $gap
= $attr
['GAP']; } else { $gap
= 5; }
14901 if (isset($attr['USEDIVLETTERS']) && (strtoupper($attr['USEDIVLETTERS'])=='OFF' || $attr['USEDIVLETTERS']==-1 || $attr['USEDIVLETTERS']==='0')) { $usedivletters
= 0; }
14902 else { $usedivletters
= 1; }
14904 if (isset($attr['LINKS']) && (strtoupper($attr['LINKS'])=='ON' || $attr['LINKS']==1)) { $links
= true; }
14905 else { $links
= false; }
14906 $this->CreateIndex($cols, $reffontsize, $linespacing, $offset, $usedivletters, $divlettfontsize, $gap, $reffont,$divlettfont, $links);
14908 /*-- END INDEX --*/
14910 /*-- WATERMARK --*/
14912 case 'WATERMARKTEXT':
14913 if (isset($attr['CONTENT']) && $attr['CONTENT']) { $txt
= htmlspecialchars_decode($attr
['CONTENT'],ENT_QUOTES
); } else { $txt
= ''; }
14914 if (isset($attr['ALPHA']) && $attr['ALPHA']>0) { $alpha
= $attr
['ALPHA']; } else { $alpha
= -1; }
14915 $this->SetWatermarkText($txt, $alpha);
14919 case 'WATERMARKIMAGE':
14920 if (isset($attr['SRC'])) { $src
= $attr
['SRC']; } else { $src
= ''; }
14921 if (isset($attr['ALPHA']) && $attr['ALPHA']>0) { $alpha
= $attr
['ALPHA']; } else { $alpha
= -1; }
14922 if (isset($attr['SIZE']) && $attr['SIZE']) {
14923 $size = $attr['SIZE'];
14924 if (strpos($size,',')) { $size
= explode(',',$size
); }
14926 else { $size
= 'D'; }
14927 if (isset($attr['POS']) && $attr['POS']) {
14928 $pos = $attr['POS'];
14929 if (strpos($pos,',')) { $pos
= explode(',',$pos
); }
14931 else { $pos
= 'P'; }
14932 $this->SetWatermarkImage($src, $alpha, $size, $pos);
14934 /*-- END WATERMARK --*/
14936 /*-- BOOKMARKS --*/
14938 if (isset($attr['CONTENT'])) {
14939 $objattr = array();
14940 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES
);
14941 $objattr['type'] = 'bookmark';
14942 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr
['bklevel'] = $attr
['LEVEL']; } else { $objattr
['bklevel'] = 0; }
14943 $e = "\xbb\xa4\xactype=bookmark,objattr=".serialize($objattr)."\xbb\xa4\xac";
14944 if($this->tableLevel
) { $this
->cell
[$this
->row
][$this
->col
]['textbuffer'][] = array($e
); } // *TABLES*
14946 $this->textbuffer
[] = array($e);
14950 /*-- END BOOKMARKS --*/
14952 /*-- ANNOTATIONS --*/
14955 //if (isset($attr['CONTENT']) && !$this->writingHTMLheader && !$this->writingHTMLfooter) { // Stops annotations in FixedPos
14956 if (isset($attr['CONTENT'])) {
14957 $objattr = array();
14958 $objattr['margin_top'] = 0;
14959 $objattr['margin_bottom'] = 0;
14960 $objattr['margin_left'] = 0;
14961 $objattr['margin_right'] = 0;
14962 $objattr['width'] = 0;
14963 $objattr['height'] = 0;
14964 $objattr['border_top']['w'] = 0;
14965 $objattr['border_bottom']['w'] = 0;
14966 $objattr['border_left']['w'] = 0;
14967 $objattr['border_right']['w'] = 0;
14968 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES
);
14969 $objattr['type'] = 'annot';
14970 $objattr['POPUP'] = '';
14973 if (isset($attr['POS-X'])) { $objattr
['POS-X'] = $attr
['POS-X']; } else { $objattr
['POS-X'] = 0; }
14974 if (isset($attr['POS-Y'])) { $objattr
['POS-Y'] = $attr
['POS-Y']; } else { $objattr
['POS-Y'] = 0; }
14975 if (isset($attr['ICON'])) { $objattr
['ICON'] = $attr
['ICON']; } else { $objattr
['ICON'] = 'Note'; }
14976 if (isset($attr['AUTHOR'])) { $objattr
['AUTHOR'] = $attr
['AUTHOR']; }
14977 else if (isset($attr['TITLE'])) { $objattr
['AUTHOR'] = $attr
['TITLE']; } else { $objattr
['AUTHOR'] = ''; }
14978 if (isset($attr['FILE'])) { $objattr
['FILE'] = $attr
['FILE']; } else { $objattr
['FILE'] = ''; }
14979 if (isset($attr['SUBJECT'])) { $objattr
['SUBJECT'] = $attr
['SUBJECT']; } else { $objattr
['SUBJECT'] = ''; }
14980 if (isset($attr['OPACITY']) && $attr['OPACITY']>0 && $attr['OPACITY']<=1) { $objattr
['OPACITY'] = $attr
['OPACITY']; }
14981 else if ($this->annotMargin
) { $objattr
['OPACITY'] = 1; }
14982 else { $objattr
['OPACITY'] = $this
->annotOpacity
; }
14983 if (isset($attr['COLOR'])) {
14984 $cor = $this->ConvertColor($attr['COLOR']);
14985 if ($cor) { $objattr
['COLOR'] = $cor
; }
14986 else { $objattr
['COLOR'] = $this
->ConvertColor('yellow'); }
14988 else { $objattr
['COLOR'] = $this
->ConvertColor('yellow'); }
14990 if (isset($attr['POPUP']) && !empty($attr['POPUP'])) {
14991 $pop = preg_split('/\s+/',trim($attr['POPUP']));
14992 if (count($pop)>1) { $objattr
['POPUP'] = $pop
; }
14993 else { $objattr
['POPUP'] = true; }
14995 $e = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
14996 if($this->tableLevel
) { $this
->cell
[$this
->row
][$this
->col
]['textbuffer'][] = array($e
); } // *TABLES*
14998 $this->textbuffer
[] = array($e);
15001 /*-- END ANNOTATIONS --*/
15005 case 'COLUMNS': //added custom-tag
15006 if (isset($attr['COLUMN-COUNT']) && ($attr['COLUMN-COUNT'] || $attr['COLUMN-COUNT']==='0')) {
15007 // Close any open block tags
15008 for ($b= $this->blklvl
;$b>0;$b--) { $this
->CloseTag($this
->blk
[$b
]['tag']); }
15009 if(!empty($this->textbuffer
)) { //Output previously buffered content
15010 $this->printbuffer($this->textbuffer
);
15011 $this->textbuffer
=array();
15014 if (isset($attr['VALIGN']) && $attr['VALIGN']) {
15015 if ($attr['VALIGN'] == 'J') { $valign
= 'J'; }
15016 else { $valign
= $align
[$attr
['VALIGN']]; }
15018 else { $valign
= ''; }
15019 if (isset($attr['COLUMN-GAP']) && $attr['COLUMN-GAP']) { $this
->SetColumns($attr
['COLUMN-COUNT'],$valign
,$attr
['COLUMN-GAP']); }
15020 else { $this
->SetColumns($attr
['COLUMN-COUNT'],$valign
); }
15022 $this->ignorefollowingspaces
= true;
15025 case 'COLUMN_BREAK': //custom-tag
15026 case 'COLUMNBREAK': //custom-tag
15027 case 'NEWCOLUMN': //custom-tag
15028 $this->ignorefollowingspaces
= true;
15029 $this->NewColumn();
15030 $this->ColumnAdjust
= false; // disables all column height adjustment for the page.
15033 /*-- END COLUMNS --*/
15037 // $this->biDirectional = true;
15043 $this->InlineProperties
[$tag] = $this->saveInlineProperties();
15044 $this->setCSS(array('FONT-FAMILY'=>'czapfdingbats','FONT-WEIGHT'=>'normal','FONT-STYLE'=>'normal'),'INLINE');
15049 $this->InlineProperties
[$tag] = $this->saveInlineProperties();
15050 $this->setCSS(array('FONT-FAMILY'=>'csymbol','FONT-WEIGHT'=>'normal','FONT-STYLE'=>'normal'),'INLINE');
15055 $this->InlineProperties
[$tag] = $this->saveInlineProperties();
15057 if (in_array($this->FontFamily
,$this->mono_fonts
)) {
15058 $this->setCSS(array('FONT-FAMILY'=>'ccourier'),'INLINE');
15060 else if (in_array($this->FontFamily
,$this->serif_fonts
)) {
15061 $this->setCSS(array('FONT-FAMILY'=>'ctimes'),'INLINE');
15064 $this->setCSS(array('FONT-FAMILY'=>'chelvetica'),'INLINE');
15070 // INLINE PHRASES OR STYLES
15093 case 'MARK': // mPDF 5.5.09
15097 /*-- ANNOTATIONS --*/
15098 if ($this->title2annots
&& isset($attr['TITLE'])) {
15099 $objattr = array();
15100 $objattr['margin_top'] = 0;
15101 $objattr['margin_bottom'] = 0;
15102 $objattr['margin_left'] = 0;
15103 $objattr['margin_right'] = 0;
15104 $objattr['width'] = 0;
15105 $objattr['height'] = 0;
15106 $objattr['border_top']['w'] = 0;
15107 $objattr['border_bottom']['w'] = 0;
15108 $objattr['border_left']['w'] = 0;
15109 $objattr['border_right']['w'] = 0;
15111 $objattr['CONTENT'] = $attr['TITLE'];
15112 $objattr['type'] = 'annot';
15113 $objattr['POS-X'] = 0;
15114 $objattr['POS-Y'] = 0;
15115 $objattr['ICON'] = 'Comment';
15116 $objattr['AUTHOR'] = '';
15117 $objattr['SUBJECT'] = '';
15118 $objattr['OPACITY'] = $this->annotOpacity
;
15119 $objattr['COLOR'] = $this->ConvertColor('yellow');
15120 $annot = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
15122 /*-- END ANNOTATIONS --*/
15124 if ($tag == 'SPAN') {
15126 $this->InlineProperties
['SPAN'][$this->spanlvl
] = $this->saveInlineProperties();
15127 if (isset($annot)) { $this
->InlineAnnots
[$tag
][$this
->spanlvl
] = $annot
; } // *ANNOTATIONS*
15130 if (!isset($this->InlineProperties
[$tag])) $this->InlineProperties
[$tag] = $this->saveInlineProperties(); // mPDF 5.4.13
15131 if (isset($annot)) { $this
->InlineAnnots
[$tag
] = $annot
; } // *ANNOTATIONS*
15133 $properties = $this->cssmgr
->MergeCSS('INLINE',$tag,$attr);
15134 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15139 if (isset($attr['NAME']) and $attr['NAME'] != '') {
15141 /*-- BOOKMARKS --*/
15142 if ($this->anchor2Bookmark
) {
15143 $objattr = array();
15144 $objattr['CONTENT'] = htmlspecialchars_decode($attr['NAME'],ENT_QUOTES
);
15145 $objattr['type'] = 'bookmark';
15146 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr
['bklevel'] = $attr
['LEVEL']; } else { $objattr
['bklevel'] = 0; }
15147 $e = "\xbb\xa4\xactype=bookmark,objattr=".serialize($objattr)."\xbb\xa4\xac";
15149 /*-- END BOOKMARKS --*/
15150 if($this->tableLevel
) { // *TABLES*
15151 $this->_saveCellTextBuffer($e, '', $attr['NAME']); // *TABLES*
15154 $this->_saveTextBuffer($e, '', $attr['NAME']); //an internal link (adds a space for recognition)
15157 if (isset($attr['HREF'])) {
15158 $this->InlineProperties
['A'] = $this->saveInlineProperties();
15159 $properties = $this->cssmgr
->MergeCSS('',$tag,$attr);
15160 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15161 $this->HREF
=htmlspecialchars_decode(urldecode($attr['HREF']));
15165 case 'LEGEND': // mPDF 5.4.18
15166 $this->InlineProperties
['LEGEND'] = $this->saveInlineProperties();
15167 $properties = $this->cssmgr
->MergeCSS('',$tag,$attr);
15168 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15173 case 'PROGRESS': // mPDF 5.5.09
15174 case 'METER': // mPDF 5.5.09
15175 $this->inMeter
= true; // mPDF 5.5.09
15177 if (isset($attr['MAX']) && $attr['MAX']) { $max
= $attr
['MAX']; }
15179 if (isset($attr['MIN']) && $attr['MIN'] && $tag=='METER') { $min
= $attr
['MIN']; }
15181 if ($max < $min) { $max
= $min
; }
15183 if (isset($attr['VALUE']) && ($attr['VALUE'] || $attr['VALUE']==='0')) {
15184 $value = $attr['VALUE'];
15185 if ($value < $min) { $value
= $min
; }
15186 else if ($value > $max) { $value
= $max
; }
15188 else { $value
= ''; }
15190 if (isset($attr['LOW']) && $attr['LOW']) { $low
= $attr
['LOW']; }
15191 else { $low
= $min
; }
15192 if ($low < $min) { $low
= $min
; }
15193 else if ($low > $max) { $low
= $max
; }
15194 if (isset($attr['HIGH']) && $attr['HIGH']) { $high
= $attr
['HIGH']; }
15195 else { $high
= $max
; }
15196 if ($high < $low) { $high
= $low
; }
15197 else if ($high > $max) { $high
= $max
; }
15198 if (isset($attr['OPTIMUM']) && $attr['OPTIMUM']) { $optimum
= $attr
['OPTIMUM']; }
15199 else { $optimum
= $min +
(($max
-$min
)/2); }
15200 if ($optimum < $min) { $optimum
= $min
; }
15201 else if ($optimum > $max) { $optimum
= $max
; }
15202 if (isset($attr['TYPE']) && $attr['TYPE']) { $type
= $attr
['TYPE']; }
15203 else { $type
= ''; }
15204 $objattr = array();
15205 $objattr['margin_top'] = 0;
15206 $objattr['margin_bottom'] = 0;
15207 $objattr['margin_left'] = 0;
15208 $objattr['margin_right'] = 0;
15209 $objattr['padding_top'] = 0;
15210 $objattr['padding_bottom'] = 0;
15211 $objattr['padding_left'] = 0;
15212 $objattr['padding_right'] = 0;
15213 $objattr['width'] = 0;
15214 $objattr['height'] = 0;
15215 $objattr['border_top']['w'] = 0;
15216 $objattr['border_bottom']['w'] = 0;
15217 $objattr['border_left']['w'] = 0;
15218 $objattr['border_right']['w'] = 0;
15220 $properties = $this->cssmgr
->MergeCSS('',$tag,$attr);
15221 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
15224 $objattr['visibility'] = 'visible';
15225 if (isset($properties['VISIBILITY'])) {
15226 $v = strtolower($properties['VISIBILITY']);
15227 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility
=='visible') {
15228 $objattr['visibility'] = $v;
15232 if (isset($properties['MARGIN-TOP'])) { $objattr
['margin_top']=$this
->ConvertSize($properties
['MARGIN-TOP'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
15233 if (isset($properties['MARGIN-BOTTOM'])) { $objattr
['margin_bottom'] = $this
->ConvertSize($properties
['MARGIN-BOTTOM'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
15234 if (isset($properties['MARGIN-LEFT'])) { $objattr
['margin_left'] = $this
->ConvertSize($properties
['MARGIN-LEFT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
15235 if (isset($properties['MARGIN-RIGHT'])) { $objattr
['margin_right'] = $this
->ConvertSize($properties
['MARGIN-RIGHT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
15237 if (isset($properties['PADDING-TOP'])) { $objattr
['padding_top']=$this
->ConvertSize($properties
['PADDING-TOP'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
15238 if (isset($properties['PADDING-BOTTOM'])) { $objattr
['padding_bottom'] = $this
->ConvertSize($properties
['PADDING-BOTTOM'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
15239 if (isset($properties['PADDING-LEFT'])) { $objattr
['padding_left'] = $this
->ConvertSize($properties
['PADDING-LEFT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
15240 if (isset($properties['PADDING-RIGHT'])) { $objattr
['padding_right'] = $this
->ConvertSize($properties
['PADDING-RIGHT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
15242 if (isset($properties['BORDER-TOP'])) { $objattr
['border_top'] = $this
->border_details($properties
['BORDER-TOP']); }
15243 if (isset($properties['BORDER-BOTTOM'])) { $objattr
['border_bottom'] = $this
->border_details($properties
['BORDER-BOTTOM']); }
15244 if (isset($properties['BORDER-LEFT'])) { $objattr
['border_left'] = $this
->border_details($properties
['BORDER-LEFT']); }
15245 if (isset($properties['BORDER-RIGHT'])) { $objattr
['border_right'] = $this
->border_details($properties
['BORDER-RIGHT']); }
15247 if (isset($properties['VERTICAL-ALIGN'])) { $objattr
['vertical-align'] = $align
[strtolower($properties
['VERTICAL-ALIGN'])]; }
15250 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
15251 else if(isset($attr['WIDTH'])) $w = $this->ConvertSize($attr['WIDTH'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
15253 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
15254 else if(isset($attr['HEIGHT'])) $h = $this->ConvertSize($attr['HEIGHT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
15256 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr
['opacity'] = $properties
['OPACITY']; }
15258 if (strpos($this->HREF
,".") === false && strpos($this->HREF
,"@") !== 0) {
15259 $href = $this->HREF
;
15260 while(array_key_exists($href,$this->internallink
)) $href="#".$href;
15261 $this->internallink
[$href] = $this->AddLink();
15262 $objattr['link'] = $this->internallink
[$href];
15264 else { $objattr
['link'] = $this
->HREF
; }
15266 $extraheight = $objattr['padding_top'] +
$objattr['padding_bottom'] +
$objattr['margin_top'] +
$objattr['margin_bottom'] +
$objattr['border_top']['w'] +
$objattr['border_bottom']['w'];
15267 $extrawidth = $objattr['padding_left'] +
$objattr['padding_right'] +
$objattr['margin_left'] +
$objattr['margin_right'] +
$objattr['border_left']['w'] +
$objattr['border_right']['w'];
15270 if (!class_exists('meter', false)) {
15271 include(_MPDF_PATH
.'classes/meter.php');
15273 $this->meter
= new meter();
15274 $svg = $this->meter
->makeSVG(strtolower($tag), $type, $value, $max, $min, $optimum, $low, $high);
15275 //Save to local file
15276 $srcpath= _MPDF_TEMP_PATH
.'_tempSVG'.RAND(1,10000).'_'.strtolower($tag).'.svg';
15277 file_put_contents($srcpath, $svg);
15278 $orig_srcpath = $srcpath;
15279 $this->GetFullPath($srcpath);
15281 $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
15283 $info = $this->_getImage($this->noImageFile
);
15285 $srcpath = $this->noImageFile
;
15286 $w = ($info['w'] * (25.4/$this->dpi
));
15287 $h = ($info['h'] * (25.4/$this->dpi
));
15292 $objattr['file'] = $srcpath;
15293 //Default width and height calculation if needed
15294 if($w==0 and $h==0) {
15295 // SVG units are pixels
15296 $w = $this->FontSize
/(10/_MPDFK
) * abs($info['w'])/_MPDFK
; // mPDF 5.5.21
15297 $h = $this->FontSize
/(10/_MPDFK
) * abs($info['h'])/_MPDFK
;
15299 // IF WIDTH OR HEIGHT SPECIFIED
15300 if($w==0) $w=abs($h*$info['w']/$info['h']);
15301 if($h==0) $h=abs($w*$info['h']/$info['w']);
15303 // Resize to maximum dimensions of page
15304 $maxWidth = $this->blk
[$this->blklvl
]['inner_width'];
15305 $maxHeight = $this->h
- ($this->tMargin +
$this->bMargin +
1) ;
15306 if ($this->fullImageHeight
) { $maxHeight
= $this
->fullImageHeight
; }
15307 if ($w +
$extrawidth > $maxWidth ) {
15308 $w = $maxWidth - $extrawidth;
15309 $h=abs($w*$info['h']/$info['w']);
15312 if ($h +
$extraheight > $maxHeight ) {
15313 $h = $maxHeight - $extraheight;
15314 $w=abs($h*$info['w']/$info['h']);
15316 $objattr['type'] = 'image';
15317 $objattr['itype'] = $info['type'];
15319 $objattr['orig_h'] = $info['h'];
15320 $objattr['orig_w'] = $info['w'];
15321 $objattr['wmf_x'] = $info['x'];
15322 $objattr['wmf_y'] = $info['y'];
15323 $objattr['height'] = $h +
$extraheight;
15324 $objattr['width'] = $w +
$extrawidth;
15325 $objattr['image_height'] = $h;
15326 $objattr['image_width'] = $w;
15327 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
15328 $properties = array();
15329 if ($this->tableLevel
) {
15330 $this->_saveCellTextBuffer($e, $this->HREF
);
15331 $this->cell
[$this->row
][$this->col
]['s'] +
= $objattr['width'] ;
15334 $this->_saveTextBuffer($e, $this->HREF
);
15341 // Added mPDF 3.0 Float DIV - CLEAR
15342 if (isset($attr['STYLE'])) {
15343 $properties = $this->cssmgr
->readInlineCSS($attr['STYLE']);
15344 if (isset($properties['CLEAR'])) { $this
->ClearFloats(strtoupper($properties
['CLEAR']),$this
->blklvl
); } // *CSS-FLOAT*
15349 if($this->tableLevel
) {
15351 if ($this->blockjustfinished
|| $this->listjustfinished
) {
15352 $this->_saveCellTextBuffer("\n");
15355 $this->_saveCellTextBuffer("\n");
15356 if (!isset($this->cell
[$this->row
][$this->col
]['maxs'])) {
15357 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
15359 elseif($this->cell
[$this->row
][$this->col
]['maxs'] < $this->cell
[$this->row
][$this->col
]['s']) {
15360 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
15362 $this->cell
[$this->row
][$this->col
]['s'] = 0 ;// reset
15365 /*-- END TABLES --*/
15366 if (count($this->textbuffer
)) {
15367 $this->textbuffer
[count($this->textbuffer
)-1][0] = preg_replace('/ $/','',$this->textbuffer
[count($this->textbuffer
)-1][0]);
15369 $this->_saveTextBuffer("\n");
15371 $this->ignorefollowingspaces
= true;
15372 $this->blockjustfinished
=false;
15373 $this->listjustfinished
=false;
15375 $this->linebreakjustfinished
=true;
15379 // *********** BLOCKS ********************
15383 $this->ispre
=true; // ADDED - Prevents left trim of textbuffer in printbuffer()
15417 $p = $this->cssmgr
->PreviewBlockCSS($tag,$attr);
15418 if(isset($p['DISPLAY']) && strtolower($p['DISPLAY'])=='none') {
15420 $this->blk
[$this->blklvl
]['hide'] = true;
15423 if($tag == 'CAPTION') {
15424 // position is written in AdjstHTML
15425 if (isset($attr['POSITION']) && strtolower($attr['POSITION'])=='bottom') { $divpos
= 'B'; }
15426 else { $divpos
= 'T'; }
15427 if (isset($attr['ALIGN']) && strtolower($attr['ALIGN'])=='bottom') { $cappos
= 'B'; }
15428 else if (isset($p['CAPTION-SIDE']) && strtolower($p['CAPTION-SIDE'])=='bottom') { $cappos
= 'B'; }
15429 else { $cappos
= 'T'; }
15430 if (isset($attr['ALIGN'])) { unset($attr
['ALIGN']); }
15431 if ($cappos != $divpos) {
15433 $this->blk
[$this->blklvl
]['hide'] = true;
15439 if($tag == 'FORM') {
15440 if (isset($attr['METHOD']) && strtolower($attr['METHOD'])=='get') { $this
->form
->formMethod
= 'GET'; }
15441 else { $this
->form
->formMethod
= 'POST'; }
15442 if (isset($attr['ACTION'])) { $this
->form
->formAction
= $attr
['ACTION']; }
15443 else { $this
->form
->formAction
= ''; }
15445 /*-- END FORMS --*/
15448 /*-- CSS-POSITION --*/
15449 if ((isset($p['POSITION']) && (strtolower($p['POSITION'])=='fixed' || strtolower($p['POSITION'])=='absolute')) && $this->blklvl
==0) {
15450 if ($this->inFixedPosBlock
) {
15451 $this->Error("Cannot nest block with position:fixed or position:absolute");
15453 $this->inFixedPosBlock
= true;
15456 /*-- END CSS-POSITION --*/
15458 $this->ignorefollowingspaces
= true;
15460 if ($this->blockjustfinished
&& !count($this->textbuffer
) && $this->y
!= $this->tMargin
&& $this->collapseBlockMargins
) { $lastbottommargin
= $this
->lastblockbottommargin
; }
15461 else { $lastbottommargin
= 0; }
15462 $this->lastblockbottommargin
= 0;
15463 $this->blockjustfinished
=false;
15466 if ($this->listlvl
>0) { return; }
15467 /*-- END LISTS --*/
15469 $this->InlineProperties
= array();
15470 $this->spanlvl
= 0;
15471 $this->listjustfinished
=false;
15472 $this->divbegin
=true;
15474 $this->linebreakjustfinished
=false;
15477 if ($this->tableLevel
) {
15479 // If already something on the line
15480 if ($this->cell
[$this->row
][$this->col
]['s'] > 0 && !$this->nestedtablejustfinished
) {
15481 $this->_saveCellTextBuffer("\n");
15482 if (!isset($this->cell
[$this->row
][$this->col
]['maxs'])) {
15483 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
15485 elseif($this->cell
[$this->row
][$this->col
]['maxs'] < $this->cell
[$this->row
][$this->col
]['s']) {
15486 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
15488 $this->cell
[$this->row
][$this->col
]['s'] = 0 ;// reset
15490 // Cannot set block properties inside table - use Bold to indicate h1-h6
15491 if ($tag == 'CENTER' && $this->tdbegin
) { $this
->cell
[$this
->row
][$this
->col
]['a'] = $align
['center']; }
15493 $this->InlineProperties
['BLOCKINTABLE'] = $this->saveInlineProperties();
15494 $properties = $this->cssmgr
->MergeCSS('',$tag,$attr);
15495 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15500 /*-- END TABLES --*/
15502 if ($tag == 'P' || $tag == 'DT' || $tag == 'DD') { $this
->lastoptionaltag
= $tag
; } // Save current HTML specified optional endtag
15503 else { $this
->lastoptionaltag
= ''; }
15505 if ($this->lastblocklevelchange
== 1) { $blockstate
= 1; } // Top margins/padding only
15506 else if ($this->lastblocklevelchange
< 1) { $blockstate
= 0; } // NO margins/padding
15507 $this->printbuffer($this->textbuffer
,$blockstate);
15508 $this->textbuffer
=array();
15510 $save_blklvl = $this->blklvl
;
15511 $save_blk = $this->blk
;
15512 $save_silp = $this->saveInlineProperties();
15513 $save_spanlvl = $this->spanlvl
;
15514 $save_ilp = $this->InlineProperties
;
15518 $currblk =& $this->blk
[$this->blklvl
];
15519 $this->initialiseBlock($currblk);
15520 $prevblk =& $this->blk
[$this->blklvl
-1];
15522 $currblk['tag'] = $tag;
15523 $currblk['attr'] = $attr;
15526 $properties = $this->cssmgr
->MergeCSS('BLOCK',$tag,$attr);
15530 if (isset($properties['PAGE'])) { $pagesel
= $properties
['PAGE']; }
15531 /*-- END CSS-PAGE --*/
15533 // If page-box has changed AND/OR PAGE-BREAK-BEFORE
15534 $save_cols = false;
15535 if (($pagesel && $pagesel != $this->page_box
['current']) || (isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE'])) {
15536 if ($this->blklvl
>1) {
15537 // Close any open block tags
15538 for ($b= $this->blklvl
;$b>0;$b--) { $this
->CloseTag($this
->blk
[$b
]['tag']); }
15539 // Output any text left in buffer
15540 if (count($this->textbuffer
)) { $this
->printbuffer($this
->textbuffer
); $this
->textbuffer
=array(); }
15543 if ($this->ColActive
) {
15545 $save_nbcol = $this->NbCol
; // other values of gap and vAlign will not change by setting Columns off
15546 $this->SetColumns(0);
15548 /*-- END COLUMNS --*/
15551 // Must Add new page if changed page properties
15552 if (isset($properties['PAGE-BREAK-BEFORE'])) {
15553 if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'RIGHT') { $this
->AddPage($this
->CurOrientation
,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel
); }
15554 else if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'LEFT') { $this
->AddPage($this
->CurOrientation
,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel
); }
15555 else if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'ALWAYS') { $this
->AddPage($this
->CurOrientation
,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel
); }
15556 else if ($this->page_box
['current'] != $pagesel) { $this
->AddPage($this
->CurOrientation
,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel
); } // *CSS-PAGE*
15559 else if ($pagesel != $this->page_box
['current']) { $this
->AddPage($this
->CurOrientation
,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel
); }
15560 /*-- END CSS-PAGE --*/
15562 // if using htmlheaders, the headers need to be rewritten when new page
15563 // done by calling WriteHTML() within resethtmlheaders
15564 // so block is reset to 0 - now we need to resurrect it
15565 // As in WriteHTML() initialising
15566 if (!($this->restoreBlockPagebreaks
&& isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE'])) {
15568 $this->lastblocklevelchange
= 0;
15569 $this->blk
= array();
15570 $this->initialiseBlock($this->blk
[0]);
15571 $this->blk
[0]['width'] =& $this->pgwidth
;
15572 $this->blk
[0]['inner_width'] =& $this->pgwidth
;
15573 $this->blk
[0]['blockContext'] = $this->blockContext
;
15574 $properties = $this->cssmgr
->MergeCSS('BLOCK','BODY','');
15575 $this->setCSS($properties,'','BODY');
15577 $currblk =& $this->blk
[$this->blklvl
];
15578 $prevblk =& $this->blk
[$this->blklvl
-1];
15580 $this->initialiseBlock($currblk);
15581 $currblk['tag'] = $tag;
15582 $currblk['attr'] = $attr;
15585 $properties = $this->cssmgr
->MergeCSS('BLOCK',$tag,$attr);
15590 $this->SetColumns($save_nbcol,$this->colvAlign
,$this->ColGap
);
15592 /*-- END COLUMNS --*/
15593 if ($this->restoreBlockPagebreaks
&& isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE']) {
15594 $this->blk
= $save_blk;
15595 // Re-open block tags
15596 $t = $this->blk
[0]['tag'];
15597 $a = $this->blk
[0]['attr'];
15599 for ($b=0; $b<=$save_blklvl;$b++
) {
15602 $t = $this->blk
[$b+
1]['tag'];
15603 $a = $this->blk
[$b+
1]['attr'];
15604 unset($this->blk
[$b+
1]);
15605 $this->OpenTag($tc,$ac);
15607 $this->spanlvl
= $save_spanlvl;
15608 $this->InlineProperties
= $save_ilp;
15609 $this->restoreInlineProperties($save_silp);
15613 if (isset($properties['PAGE-BREAK-INSIDE']) && strtoupper($properties['PAGE-BREAK-INSIDE']) == 'AVOID' && !$this->ColActive
&& !$this->keep_block_together
) {
15614 $currblk['keep_block_together'] = 1;
15615 $this->kt_y00
= $this->y
;
15616 $this->kt_p00
= $this->page
;
15617 $this->keep_block_together
= 1;
15618 $this->divbuffer
= array();
15619 $this->ktLinks
= array();
15620 $this->ktAnnots
= array();
15621 $this->ktForms
= array();
15622 $this->ktBlock
= array();
15623 $this->ktReference
= array();
15624 $this->ktBMoutlines
= array();
15625 $this->_kttoc
= array();
15627 if ($lastbottommargin && isset($properties['MARGIN-TOP']) && $properties['MARGIN-TOP'] && empty($properties['FLOAT'])) { $currblk
['lastbottommargin'] = $lastbottommargin
; }
15629 // mPDF 5.6.01 - LAYERS
15630 if (isset($properties['Z-INDEX']) && $this->currentlayer
==0) {
15631 $v = intval($properties['Z-INDEX']);
15633 $currblk['z-index'] = $v;
15634 $this->BeginLayer($v);
15638 $this->setCSS($properties,'BLOCK',$tag); //name(id/class/style) found in the CSS array!
15639 $currblk['InlineProperties'] = $this->saveInlineProperties();
15641 if (isset($properties['VISIBILITY'])) {
15642 $v = strtolower($properties['VISIBILITY']);
15643 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility
=='visible' && !$this->tableLevel
) {
15644 $currblk['visibility'] = $v;
15645 $this->SetVisibility($v);
15649 if(isset($attr['DIR']) && $attr['DIR']) { $currblk
['direction'] = strtolower($attr
['DIR']); }
15650 if(isset($attr['ALIGN']) && $attr['ALIGN']) { $currblk
['block-align'] = $align
[strtolower($attr
['ALIGN'])]; }
15652 if (isset($properties['HEIGHT'])) {
15653 $currblk['css_set_height'] = $this->ConvertSize($properties['HEIGHT'],($this->h
- $this->tMargin
- $this->bMargin
),$this->FontSize
,false);
15654 if (($currblk['css_set_height'] +
$this->y
) > $this->PageBreakTrigger
&& $this->y
> $this->tMargin+
5 && $currblk['css_set_height'] < ($this->h
- ($this->tMargin +
$this->bMargin
))) { $this
->AddPage($this
->CurOrientation
); }
15656 else { $currblk
['css_set_height'] = false; }
15659 // Added mPDF 3.0 Float DIV
15660 if (isset($prevblk['blockContext'])) { $currblk
['blockContext'] = $prevblk
['blockContext'] ; } // *CSS-FLOAT*
15662 if (isset($properties['CLEAR'])) { $this
->ClearFloats(strtoupper($properties
['CLEAR']), $this
->blklvl
-1); } // *CSS-FLOAT*
15664 $container_w = $prevblk['inner_width'];
15665 $bdr = $currblk['border_right']['w'];
15666 $bdl = $currblk['border_left']['w'];
15667 $pdr = $currblk['padding_right'];
15668 $pdl = $currblk['padding_left'];
15670 if (isset($currblk['css_set_width'])) { $setwidth
= $currblk
['css_set_width']; }
15671 else { $setwidth
= 0; }
15673 /*-- CSS-FLOAT --*/
15674 if (isset($properties['FLOAT']) && strtoupper($properties['FLOAT']) == 'RIGHT' && !$this->ColActive
) {
15675 // Cancel Keep-Block-together
15676 $currblk['keep_block_together'] = false;
15677 $this->kt_y00
= '';
15678 $this->keep_block_together
= 0;
15680 $this->blockContext++
;
15681 $currblk['blockContext'] = $this->blockContext
;
15683 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl
-1);
15685 // DIV is too narrow for text to fit!
15686 $maxw = $container_w - $l_width - $r_width;
15687 if (($setwidth +
$currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr) > $maxw || ($maxw - ($currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr)) < (2*$this->GetCharWidth('W',false))) {
15688 // Too narrow to fit - try to move down past L or R float
15689 if ($l_max < $r_max && ($setwidth +
$currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr) <= ($container_w - $r_width) && (($container_w - $r_width) - ($currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr)) > (2*$this->GetCharWidth('W',false))) {
15690 $this->ClearFloats('LEFT', $this->blklvl
-1);
15692 else if ($r_max < $l_max && ($setwidth +
$currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr) <= ($container_w - $l_width) && (($container_w - $l_width) - ($currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr)) > (2*$this->GetCharWidth('W',false))) {
15693 $this->ClearFloats('RIGHT', $this->blklvl
-1);
15695 else { $this
->ClearFloats('BOTH', $this
->blklvl
-1); }
15696 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl
-1);
15699 if ($r_exists) { $currblk
['margin_right'] +
= $r_width
; }
15701 $currblk['float'] = 'R';
15702 $currblk['float_start_y'] = $this->y
;
15703 if ($currblk['css_set_width']) {
15704 $currblk['margin_left'] = $container_w - ($setwidth +
$bdl +
$pdl +
$bdr +
$pdr +
$currblk['margin_right']);
15705 $currblk['float_width'] = ($setwidth +
$bdl +
$pdl +
$bdr +
$pdr +
$currblk['margin_right']);
15708 // *** If no width set - would need to buffer and keep track of max width, then Right-align if not full width
15709 // and do borders and backgrounds - For now - just set to maximum width left
15711 if ($l_exists) { $currblk
['margin_left'] +
= $l_width
; }
15712 $currblk['css_set_width'] = $container_w - ($currblk['margin_left'] +
$currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr);
15714 $currblk['float_width'] = ($currblk['css_set_width'] +
$bdl +
$pdl +
$bdr +
$pdr +
$currblk['margin_right']);
15717 else if (isset($properties['FLOAT']) && strtoupper($properties['FLOAT']) == 'LEFT' && !$this->ColActive
) {
15718 // Cancel Keep-Block-together
15719 $currblk['keep_block_together'] = false;
15720 $this->kt_y00
= '';
15721 $this->keep_block_together
= 0;
15723 $this->blockContext++
;
15724 $currblk['blockContext'] = $this->blockContext
;
15726 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl
-1);
15728 // DIV is too narrow for text to fit!
15729 $maxw = $container_w - $l_width - $r_width;
15730 if (($setwidth +
$currblk['margin_left'] +
$bdl +
$pdl +
$bdr +
$pdr) > $maxw || ($maxw - ($currblk['margin_left'] +
$bdl +
$pdl +
$bdr +
$pdr)) < (2*$this->GetCharWidth('W',false))) {
15731 // Too narrow to fit - try to move down past L or R float
15732 if ($l_max < $r_max && ($setwidth +
$currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr) <= ($container_w - $r_width) && (($container_w - $r_width) - ($currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr)) > (2*$this->GetCharWidth('W',false))) {
15733 $this->ClearFloats('LEFT', $this->blklvl
-1);
15735 else if ($r_max < $l_max && ($setwidth +
$currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr) <= ($container_w - $l_width) && (($container_w - $l_width) - ($currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr)) > (2*$this->GetCharWidth('W',false))) {
15736 $this->ClearFloats('RIGHT', $this->blklvl
-1);
15738 else { $this
->ClearFloats('BOTH', $this
->blklvl
-1); }
15739 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl
-1);
15742 if ($l_exists) { $currblk
['margin_left'] +
= $l_width
; }
15744 $currblk['float'] = 'L';
15745 $currblk['float_start_y'] = $this->y
;
15747 $currblk['margin_right'] = $container_w - ($setwidth +
$bdl +
$pdl +
$bdr +
$pdr +
$currblk['margin_left']);
15748 $currblk['float_width'] = ($setwidth +
$bdl +
$pdl +
$bdr +
$pdr +
$currblk['margin_left']);
15751 // *** If no width set - would need to buffer and keep track of max width, then Right-align if not full width
15752 // and do borders and backgrounds - For now - just set to maximum width left
15754 if ($r_exists) { $currblk
['margin_right'] +
= $r_width
; }
15755 $currblk['css_set_width'] = $container_w - ($currblk['margin_left'] +
$currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr);
15757 $currblk['float_width'] = ($currblk['css_set_width'] +
$bdl +
$pdl +
$bdr +
$pdr +
$currblk['margin_left']);
15762 // Don't allow overlap - if floats present - adjust padding to avoid overlap with Floats
15763 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl
-1);
15764 $maxw = $container_w - $l_width - $r_width;
15765 if (($setwidth +
$currblk['margin_left'] +
$currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr) > $maxw || ($maxw - ($currblk['margin_right'] +
$currblk['margin_left'] +
$bdl +
$pdl +
$bdr +
$pdr)) < (2*$this->GetCharWidth('W',false))) {
15766 // Too narrow to fit - try to move down past L or R float
15767 if ($l_max < $r_max && ($setwidth +
$currblk['margin_left'] +
$currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr) <= ($container_w - $r_width) && (($container_w - $r_width) - ($currblk['margin_right'] +
$currblk['margin_left'] +
$bdl +
$pdl +
$bdr +
$pdr)) > (2*$this->GetCharWidth('W',false))) {
15768 $this->ClearFloats('LEFT', $this->blklvl
-1);
15770 else if ($r_max < $l_max && ($setwidth +
$currblk['margin_left'] +
$currblk['margin_right'] +
$bdl +
$pdl +
$bdr +
$pdr) <= ($container_w - $l_width) && (($container_w - $l_width) - ($currblk['margin_right'] +
$currblk['margin_left'] +
$bdl +
$pdl +
$bdr +
$pdr)) > (2*$this->GetCharWidth('W',false))) {
15771 $this->ClearFloats('RIGHT', $this->blklvl
-1);
15773 else { $this
->ClearFloats('BOTH', $this
->blklvl
-1); }
15774 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl
-1);
15776 if ($r_exists) { $currblk
['padding_right'] = max(($r_width
-$currblk
['margin_right']-$bdr
), $pdr
); }
15777 if ($l_exists) { $currblk
['padding_left'] = max(($l_width
-$currblk
['margin_left']-$bdl
), $pdl
); }
15779 /*-- END CSS-FLOAT --*/
15782 /*-- BORDER-RADIUS --*/
15783 // Automatically increase padding if required for border-radius
15784 if ($this->autoPadding
&& !$this->ColActive
&& !$this->keep_block_together
) {
15785 if ($currblk['border_radius_TL_H']>$currblk['padding_left'] && $currblk['border_radius_TL_V']>$currblk['padding_top']) {
15786 if ($currblk['border_radius_TL_H']>$currblk['border_radius_TL_V']) {
15787 $this->_borderPadding($currblk['border_radius_TL_H'],$currblk['border_radius_TL_V'], $currblk['padding_left'], $currblk['padding_top']);
15790 $this->_borderPadding($currblk['border_radius_TL_V'],$currblk['border_radius_TL_H'], $currblk['padding_top'], $currblk['padding_left']);
15793 if ($currblk['border_radius_TR_H']>$currblk['padding_right'] && $currblk['border_radius_TR_V']>$currblk['padding_top']) {
15794 if ($currblk['border_radius_TR_H']>$currblk['border_radius_TR_V']) {
15795 $this->_borderPadding($currblk['border_radius_TR_H'],$currblk['border_radius_TR_V'], $currblk['padding_right'], $currblk['padding_top']);
15798 $this->_borderPadding($currblk['border_radius_TR_V'],$currblk['border_radius_TR_H'], $currblk['padding_top'], $currblk['padding_right']);
15801 if ($currblk['border_radius_BL_H']>$currblk['padding_left'] && $currblk['border_radius_BL_V']>$currblk['padding_bottom']) {
15802 if ($currblk['border_radius_BL_H']>$currblk['border_radius_BL_V']) {
15803 $this->_borderPadding($currblk['border_radius_BL_H'],$currblk['border_radius_BL_V'], $currblk['padding_left'], $currblk['padding_bottom']);
15806 $this->_borderPadding($currblk['border_radius_BL_V'],$currblk['border_radius_BL_H'], $currblk['padding_bottom'], $currblk['padding_left']);
15809 if ($currblk['border_radius_BR_H']>$currblk['padding_right'] && $currblk['border_radius_BR_V']>$currblk['padding_bottom']) {
15810 if ($currblk['border_radius_BR_H']>$currblk['border_radius_BR_V']) {
15811 $this->_borderPadding($currblk['border_radius_BR_H'],$currblk['border_radius_BR_V'], $currblk['padding_right'], $currblk['padding_bottom']);
15814 $this->_borderPadding($currblk['border_radius_BR_V'],$currblk['border_radius_BR_H'], $currblk['padding_bottom'], $currblk['padding_right']);
15818 /*-- END BORDER-RADIUS --*/
15821 // Hanging indent - if negative indent: ensure padding is >= indent
15822 if(!isset($currblk['text_indent'])) { $currblk
['text_indent'] = null; }
15823 if(!isset($currblk['inner_width'])) { $currblk
['inner_width'] = null; }
15824 $cbti = $this->ConvertSize($currblk['text_indent'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
15826 $hangind = -($cbti);
15827 if ($currblk['direction'] == 'rtl') { // *RTL*
15828 $currblk['padding_right'] = max($currblk['padding_right'],$hangind); // *RTL*
15831 $currblk['padding_left'] = max($currblk['padding_left'],$hangind);
15835 if (isset($currblk['css_set_width'])) {
15836 if (isset($properties['MARGIN-LEFT']) && isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-LEFT'])=='auto' && strtolower($properties['MARGIN-RIGHT'])=='auto') {
15837 // Try to reduce margins to accomodate - if still too wide, set margin-right/left=0 (reduces width)
15838 $anyextra = $prevblk['inner_width'] - ($currblk['css_set_width'] +
$currblk['border_left']['w'] +
$currblk['padding_left'] +
$currblk['border_right']['w'] +
$currblk['padding_right']);
15840 $currblk['margin_left'] = $currblk['margin_right'] = $anyextra /2;
15843 $currblk['margin_left'] = $currblk['margin_right'] = 0;
15846 else if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
15847 // Try to reduce margin-left to accomodate - if still too wide, set margin-left=0 (reduces width)
15848 $currblk['margin_left'] = $prevblk['inner_width'] - ($currblk['css_set_width'] +
$currblk['border_left']['w'] +
$currblk['padding_left'] +
$currblk['border_right']['w'] +
$currblk['padding_right'] +
$currblk['margin_right']);
15849 if ($currblk['margin_left'] < 0) {
15850 $currblk['margin_left'] = 0;
15853 else if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
15854 // Try to reduce margin-right to accomodate - if still too wide, set margin-right=0 (reduces width)
15855 $currblk['margin_right'] = $prevblk['inner_width'] - ($currblk['css_set_width'] +
$currblk['border_left']['w'] +
$currblk['padding_left'] +
$currblk['border_right']['w'] +
$currblk['padding_right'] +
$currblk['margin_left']);
15856 if ($currblk['margin_right'] < 0) {
15857 $currblk['margin_right'] = 0;
15861 if ($currblk['direction'] == 'rtl') { // *RTL*
15862 // Try to reduce margin-left to accomodate - if still too wide, set margin-left=0 (reduces width)
15863 $currblk['margin_left'] = $prevblk['inner_width'] - ($currblk['css_set_width'] +
$currblk['border_left']['w'] +
$currblk['padding_left'] +
$currblk['border_right']['w'] +
$currblk['padding_right'] +
$currblk['margin_right']); // *RTL*
15864 if ($currblk['margin_left'] < 0) { // *RTL*
15865 $currblk['margin_left'] = 0; // *RTL*
15869 // Try to reduce margin-right to accomodate - if still too wide, set margin-right=0 (reduces width)
15870 $currblk['margin_right'] = $prevblk['inner_width'] - ($currblk['css_set_width'] +
$currblk['border_left']['w'] +
$currblk['padding_left'] +
$currblk['border_right']['w'] +
$currblk['padding_right'] +
$currblk['margin_left']);
15871 if ($currblk['margin_right'] < 0) {
15872 $currblk['margin_right'] = 0;
15878 $currblk['outer_left_margin'] = $prevblk['outer_left_margin'] +
$currblk['margin_left'] +
$prevblk['border_left']['w'] +
$prevblk['padding_left'];
15879 $currblk['outer_right_margin'] = $prevblk['outer_right_margin'] +
$currblk['margin_right'] +
$prevblk['border_right']['w'] +
$prevblk['padding_right'];
15881 $currblk['width'] = $this->pgwidth
- ($currblk['outer_right_margin'] +
$currblk['outer_left_margin']);
15882 $currblk['inner_width'] = $currblk['width'] - ($currblk['border_left']['w'] +
$currblk['padding_left'] +
$currblk['border_right']['w'] +
$currblk['padding_right']);
15884 // Check DIV is not now too narrow to fit text
15885 $mw = 2*$this->GetCharWidth('W',false);
15886 if ($currblk['inner_width'] < $mw) {
15887 $currblk['padding_left'] = 0;
15888 $currblk['padding_right'] = 0;
15889 $currblk['border_left']['w'] = 0.2;
15890 $currblk['border_right']['w'] = 0.2;
15891 $currblk['margin_left'] = 0;
15892 $currblk['margin_right'] = 0;
15893 $currblk['outer_left_margin'] = $prevblk['outer_left_margin'] +
$currblk['margin_left'] +
$prevblk['border_left']['w'] +
$prevblk['padding_left'];
15894 $currblk['outer_right_margin'] = $prevblk['outer_right_margin'] +
$currblk['margin_right'] +
$prevblk['border_right']['w'] +
$prevblk['padding_right'];
15895 $currblk['width'] = $this->pgwidth
- ($currblk['outer_right_margin'] +
$currblk['outer_left_margin']);
15896 $currblk['inner_width'] = $this->pgwidth
- ($currblk['outer_right_margin'] +
$currblk['outer_left_margin'] +
$currblk['border_left']['w'] +
$currblk['padding_left'] +
$currblk['border_right']['w'] +
$currblk['padding_right']);
15897 // if ($currblk['inner_width'] < $mw) { $this->Error("DIV is too narrow for text to fit!"); }
15900 $this->x
= $this->lMargin +
$currblk['outer_left_margin'];
15902 /*-- BACKGROUNDS --*/
15903 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt
&& !$this->ColActive
&& !$this->keep_block_together
) {
15904 $ret = $this->SetBackground($properties, $currblk['inner_width']);
15905 if ($ret) { $currblk
['background-image'] = $ret
; }
15907 /*-- END BACKGROUNDS --*/
15910 if ($this->use_kwt
&& isset($attr['KEEP-WITH-TABLE']) && !$this->ColActive
&& !$this->keep_block_together
) {
15912 $this->kwt_y0
= $this->y
;
15913 $this->kwt_x0
= $this->x
;
15914 $this->kwt_height
= 0;
15915 $this->kwt_buffer
= array();
15916 $this->kwt_Links
= array();
15917 $this->kwt_Annots
= array();
15918 $this->kwt_moved
= false;
15919 $this->kwt_saved
= false;
15920 $this->kwt_Reference
= array();
15921 $this->kwt_BMoutlines
= array();
15922 $this->kwt_toc
= array();
15925 /*-- END TABLES --*/
15926 $this->kwt
= false;
15929 //Save x,y coords in case we need to print borders...
15930 $currblk['y0'] = $this->y
;
15931 $currblk['x0'] = $this->x
;
15932 $currblk['startpage'] = $this->page
;
15933 $this->oldy
= $this->y
;
15935 $this->lastblocklevelchange
= 1 ;
15940 // Added mPDF 3.0 Float DIV - CLEAR
15941 if (isset($attr['STYLE'])) {
15942 $properties = $this->cssmgr
->readInlineCSS($attr['STYLE']);
15943 if (isset($properties['CLEAR'])) { $this
->ClearFloats(strtoupper($properties
['CLEAR']),$this
->blklvl
); } // *CSS-FLOAT*
15946 $this->ignorefollowingspaces
= true;
15948 $objattr = array();
15949 $objattr['margin_top'] = 0;
15950 $objattr['margin_bottom'] = 0;
15951 $objattr['margin_left'] = 0;
15952 $objattr['margin_right'] = 0;
15953 $objattr['width'] = 0;
15954 $objattr['height'] = 0;
15955 $objattr['border_top']['w'] = 0;
15956 $objattr['border_bottom']['w'] = 0;
15957 $objattr['border_left']['w'] = 0;
15958 $objattr['border_right']['w'] = 0;
15959 $properties = $this->cssmgr
->MergeCSS('',$tag,$attr);
15960 if (isset($properties['MARGIN-TOP'])) { $objattr
['margin_top'] = $this
->ConvertSize($properties
['MARGIN-TOP'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
15961 if (isset($properties['MARGIN-BOTTOM'])) { $objattr
['margin_bottom'] = $this
->ConvertSize($properties
['MARGIN-BOTTOM'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
15962 if (isset($properties['WIDTH'])) { $objattr
['width'] = $this
->ConvertSize($properties
['WIDTH'],$this
->blk
[$this
->blklvl
]['inner_width']); }
15963 else if(isset($attr['WIDTH']) && $attr['WIDTH'] != '') $objattr['width'] = $this->ConvertSize($attr['WIDTH'],$this->blk
[$this->blklvl
]['inner_width']);
15964 if (isset($properties['TEXT-ALIGN'])) { $objattr
['align'] = $align
[strtolower($properties
['TEXT-ALIGN'])]; }
15965 else if(isset($attr['ALIGN']) && $attr['ALIGN'] != '') $objattr['align'] = $align[strtolower($attr['ALIGN'])];
15967 if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
15968 $objattr['align'] = 'R';
15970 if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
15971 $objattr['align'] = 'L';
15972 if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto' && isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
15973 $objattr['align'] = 'C';
15976 if (isset($properties['COLOR'])) { $objattr
['color'] = $this
->ConvertColor($properties
['COLOR']); }
15977 else if(isset($attr['COLOR']) && $attr['COLOR'] != '') $objattr['color'] = $this->ConvertColor($attr['COLOR']);
15978 if (isset($properties['HEIGHT'])) { $objattr
['linewidth'] = $this
->ConvertSize($properties
['HEIGHT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
15982 if ($this->tableLevel
) {
15983 $objattr['W-PERCENT'] = 100;
15984 if (isset($properties['WIDTH']) && stristr($properties['WIDTH'],'%')) {
15985 $properties['WIDTH'] +
= 0; //make "90%" become simply "90"
15986 $objattr['W-PERCENT'] = $properties['WIDTH'];
15988 if (isset($attr['WIDTH']) && stristr($attr['WIDTH'],'%')) {
15989 $attr['WIDTH'] +
= 0; //make "90%" become simply "90"
15990 $objattr['W-PERCENT'] = $attr['WIDTH'];
15993 /*-- END TABLES --*/
15995 $objattr['type'] = 'hr';
15996 $objattr['height'] = $objattr['linewidth'] +
$objattr['margin_top'] +
$objattr['margin_bottom'];
15997 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
15999 // Clear properties - tidy up
16000 $properties = array();
16003 // Output it to buffers
16004 if ($this->tableLevel
) {
16005 if (!isset($this->cell
[$this->row
][$this->col
]['maxs'])) {
16006 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
16008 elseif($this->cell
[$this->row
][$this->col
]['maxs'] < $this->cell
[$this->row
][$this->col
]['s']) {
16009 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
16011 $this->cell
[$this->row
][$this->col
]['s'] = 0 ;// reset
16012 $this->_saveCellTextBuffer($e, $this->HREF
);
16015 /*-- END TABLES --*/
16016 $this->_saveTextBuffer($e, $this->HREF
);
16025 if(isset($attr['CODE']) && $attr['CODE']) {
16026 $objattr = array();
16027 $objattr['margin_top'] = 0;
16028 $objattr['margin_bottom'] = 0;
16029 $objattr['margin_left'] = 0;
16030 $objattr['margin_right'] = 0;
16031 $objattr['padding_top'] = 0;
16032 $objattr['padding_bottom'] = 0;
16033 $objattr['padding_left'] = 0;
16034 $objattr['padding_right'] = 0;
16035 $objattr['width'] = 0;
16036 $objattr['height'] = 0;
16037 $objattr['border_top']['w'] = 0;
16038 $objattr['border_bottom']['w'] = 0;
16039 $objattr['border_left']['w'] = 0;
16040 $objattr['border_right']['w'] = 0;
16041 $objattr['code'] = $attr['CODE'];
16043 if(isset($attr['TYPE'])) {
16044 $objattr['btype'] = trim(strtoupper($attr['TYPE']));
16046 else { $objattr
['btype'] = 'EAN13'; } // default
16047 if (preg_match('/^(EAN13|ISBN|ISSN|EAN8|UPCA|UPCE)P([25])$/',$objattr['btype'],$m)) {
16048 $objattr['btype'] = $m[1];
16049 $objattr['bsupp'] = $m[2];
16050 if (preg_match('/^(\S+)\s+(.*)$/',$objattr['code'],$mm)) {
16051 $objattr['code'] = $mm[1];
16052 $objattr['bsupp_code'] = $mm[2];
16055 else { $objattr
['bsupp'] = 0; }
16057 if(isset($attr['TEXT']) && $attr['TEXT']==1) { $objattr
['showtext'] = 1; }
16058 else { $objattr
['showtext'] = 0; }
16059 if(isset($attr['SIZE']) && $attr['SIZE']>0) { $objattr
['bsize'] = $attr
['SIZE']; }
16060 else { $objattr
['bsize'] = 1; }
16061 if(isset($attr['HEIGHT']) && $attr['HEIGHT']>0) { $objattr
['bheight'] = $attr
['HEIGHT']; }
16062 else { $objattr
['bheight'] = 1; }
16063 if(isset($attr['PR']) && $attr['PR']>0) { $objattr
['pr_ratio'] = $attr
['PR']; }
16064 else { $objattr
['pr_ratio'] = ''; }
16065 $properties = $this->cssmgr
->MergeCSS('',$tag,$attr);
16066 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
16069 if (isset($properties['MARGIN-TOP'])) { $objattr
['margin_top']=$this
->ConvertSize($properties
['MARGIN-TOP'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16070 if (isset($properties['MARGIN-BOTTOM'])) { $objattr
['margin_bottom'] = $this
->ConvertSize($properties
['MARGIN-BOTTOM'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16071 if (isset($properties['MARGIN-LEFT'])) { $objattr
['margin_left'] = $this
->ConvertSize($properties
['MARGIN-LEFT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16072 if (isset($properties['MARGIN-RIGHT'])) { $objattr
['margin_right'] = $this
->ConvertSize($properties
['MARGIN-RIGHT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16074 if (isset($properties['PADDING-TOP'])) { $objattr
['padding_top']=$this
->ConvertSize($properties
['PADDING-TOP'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16075 if (isset($properties['PADDING-BOTTOM'])) { $objattr
['padding_bottom'] = $this
->ConvertSize($properties
['PADDING-BOTTOM'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16076 if (isset($properties['PADDING-LEFT'])) { $objattr
['padding_left'] = $this
->ConvertSize($properties
['PADDING-LEFT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16077 if (isset($properties['PADDING-RIGHT'])) { $objattr
['padding_right'] = $this
->ConvertSize($properties
['PADDING-RIGHT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16079 if (isset($properties['BORDER-TOP'])) { $objattr
['border_top'] = $this
->border_details($properties
['BORDER-TOP']); }
16080 if (isset($properties['BORDER-BOTTOM'])) { $objattr
['border_bottom'] = $this
->border_details($properties
['BORDER-BOTTOM']); }
16081 if (isset($properties['BORDER-LEFT'])) { $objattr
['border_left'] = $this
->border_details($properties
['BORDER-LEFT']); }
16082 if (isset($properties['BORDER-RIGHT'])) { $objattr
['border_right'] = $this
->border_details($properties
['BORDER-RIGHT']); }
16084 if (isset($properties['VERTICAL-ALIGN'])) { $objattr
['vertical-align'] = $align
[strtolower($properties
['VERTICAL-ALIGN'])]; }
16085 if (isset($properties['COLOR']) && $properties['COLOR'] != '') { $objattr
['color'] = $this
->ConvertColor($properties
['COLOR']); }
16086 else { $objattr
['color'] = false; }
16087 if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { $objattr
['bgcolor'] = $this
->ConvertColor($properties
['BACKGROUND-COLOR']); }
16088 else { $objattr
['bgcolor'] = false; }
16090 if (!class_exists('PDFBarcode', false)) {
16091 include(_MPDF_PATH
.'classes/barcode.php');
16093 $this->barcode
= new PDFBarcode();
16095 if ($objattr['btype'] == 'EAN13' || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN' || $objattr['btype'] == 'UPCA' || $objattr['btype'] == 'UPCE' || $objattr['btype'] == 'EAN8') {
16096 $code = preg_replace('/\-/','',$objattr['code']);
16097 if ($objattr['btype'] == 'ISSN' || $objattr['btype'] == 'ISBN') {
16098 $arrcode = $this->barcode
->getBarcodeArray($code, 'EAN13');
16100 else { $arrcode
= $this
->barcode
->getBarcodeArray($code
, $objattr
['btype'] ); }
16101 if ($arrcode === false) { $this
->Error('Error in barcode string.'); }
16103 if ($objattr['bsupp'] == 2 || $objattr['bsupp'] == 5) { // EAN-2 or -5 Supplement
16104 $supparrcode = $this->barcode
->getBarcodeArray($objattr['bsupp_code'], 'EAN'.$objattr['bsupp'] );
16105 $w = ($arrcode["maxw"] +
$arrcode['lightmL'] +
$arrcode['lightmR'] +
$supparrcode["maxw"] +
$supparrcode['sepM']) * $arrcode['nom-X'] * $objattr['bsize'];
16108 $w = ($arrcode["maxw"] +
$arrcode['lightmL'] +
$arrcode['lightmR']) * $arrcode['nom-X'] * $objattr['bsize'];
16110 $h = $arrcode['nom-H'] * $objattr['bsize'] * $objattr['bheight'];
16111 // Add height for ISBN string + margin from top of bars
16112 if (($objattr['showtext'] && $objattr['btype'] == 'EAN13') || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN') {
16113 $tisbnm = 1.5 * $objattr['bsize']; // Top margin between TOP TEXT (isbn - if shown) & bars
16114 $isbn_fontsize = 2.1 * $objattr['bsize'];
16115 $h +
= $isbn_fontsize +
$tisbnm ;
16119 else if ($objattr['btype'] == 'QR') {
16120 $w = $h = $objattr['bsize']*25; // Factor of 25mm (default)
16121 $objattr['errorlevel'] = 'L';
16122 if (isset($attr['ERROR'])) { $objattr
['errorlevel'] = $attr
['ERROR']; }
16124 else if ($objattr['btype'] == 'IMB' || $objattr['btype'] == 'RM4SCC' || $objattr['btype'] == 'KIX' || $objattr['btype'] == 'POSTNET' || $objattr['btype'] == 'PLANET') {
16125 $arrcode = $this->barcode
->getBarcodeArray($objattr['code'], $objattr['btype'] );
16126 if ($arrcode === false) { $this
->Error('Error in barcode string.'); }
16127 $w = ($arrcode["maxw"] * $arrcode['nom-X'] * $objattr['bsize']) +
$arrcode['quietL'] +
$arrcode['quietR'];
16128 $h = ($arrcode['nom-H'] * $objattr['bsize']) +
(2*$arrcode['quietTB']);
16130 else if (in_array($objattr['btype'], array('C128A','C128B','C128C','EAN128A','EAN128B','EAN128C','C39','C39+','C39E','C39E+','S25','S25+','I25','I25+','I25B','I25B+','C93','MSI','MSI+','CODABAR','CODE11'))) {
16131 $arrcode = $this->barcode
->getBarcodeArray($objattr['code'], $objattr['btype'], $objattr['pr_ratio'] );
16132 if ($arrcode === false) { $this
->Error('Error in barcode string.'); }
16133 $w = ($arrcode["maxw"] +
$arrcode['lightmL'] +
$arrcode['lightmR']) * $arrcode['nom-X'] * $objattr['bsize'];
16134 $h = ((2*$arrcode['lightTB'] * $arrcode['nom-X']) +
$arrcode['nom-H']) * $objattr['bsize'] * $objattr['bheight'];
16138 $extraheight = $objattr['padding_top'] +
$objattr['padding_bottom'] +
$objattr['margin_top'] +
$objattr['margin_bottom'] +
$objattr['border_top']['w'] +
$objattr['border_bottom']['w'];
16139 $extrawidth = $objattr['padding_left'] +
$objattr['padding_right'] +
$objattr['margin_left'] +
$objattr['margin_right'] +
$objattr['border_left']['w'] +
$objattr['border_right']['w'];
16141 $objattr['type'] = 'barcode';
16142 $objattr['height'] = $h +
$extraheight;
16143 $objattr['width'] = $w +
$extrawidth;
16144 $objattr['barcode_height'] = $h;
16145 $objattr['barcode_width'] = $w;
16146 /*-- CSS-IMAGE-FLOAT --*/
16147 if (!$this->ColActive
&& !$this->tableLevel
&& !$this->listlvl
&& !$this->kwt
&& !$this->keep_block_together
) {
16148 if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) == 'RIGHT' || strtoupper($properties['FLOAT']) == 'LEFT')) {
16149 $objattr['float'] = substr(strtoupper($properties['FLOAT']),0,1);
16152 /*-- END CSS-IMAGE-FLOAT --*/
16154 $e = "\xbb\xa4\xactype=barcode,objattr=".serialize($objattr)."\xbb\xa4\xac";
16156 // Clear properties - tidy up
16157 $properties = array();
16160 // Output it to buffers
16161 if ($this->tableLevel
) {
16162 $this->_saveCellTextBuffer($e, $this->HREF
);
16163 $this->cell
[$this->row
][$this->col
]['s'] +
= $objattr['width'] ;
16166 /*-- END TABLES --*/
16167 $this->_saveTextBuffer($e, $this->HREF
);
16172 /*-- END BARCODES --*/
16175 // *********** FORM ELEMENTS ********************
16179 $this->lastoptionaltag
= ''; // Save current HTML specified optional endtag
16180 $this->InlineProperties
[$tag] = $this->saveInlineProperties();
16181 $properties = $this->cssmgr
->MergeCSS('',$tag,$attr);
16182 if (isset($properties['FONT-FAMILY'])) {
16183 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle
,0,false);
16185 if (isset($properties['FONT-SIZE'])) {
16186 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size
/_MPDFK
);
16187 $this->SetFontSize($mmsize*_MPDFK
,false);
16189 if (isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') {
16190 $this->selectoption
['SPELLCHECK'] = true;
16193 if (isset($properties['COLOR'])) { $this
->selectoption
['COLOR'] = $this
->ConvertColor($properties
['COLOR']); }
16194 $this->specialcontent
= "type=select";
16195 if(isset($attr['DISABLED'])) { $this
->selectoption
['DISABLED'] = $attr
['DISABLED']; }
16196 if(isset($attr['READONLY'])) { $this
->selectoption
['READONLY'] = $attr
['READONLY']; }
16197 if(isset($attr['REQUIRED'])) { $this
->selectoption
['REQUIRED'] = $attr
['REQUIRED']; }
16198 if(isset($attr['EDITABLE'])) { $this
->selectoption
['EDITABLE'] = $attr
['EDITABLE']; }
16199 if(isset($attr['TITLE'])) { $this
->selectoption
['TITLE'] = $attr
['TITLE']; }
16200 if(isset($attr['MULTIPLE'])) { $this
->selectoption
['MULTIPLE'] = $attr
['MULTIPLE']; }
16201 if(isset($attr['SIZE']) && $attr['SIZE']>1) { $this
->selectoption
['SIZE'] = $attr
['SIZE']; }
16202 if ($this->useActiveForms
) {
16203 if(isset($attr['NAME'])) { $this
->selectoption
['NAME'] = $attr
['NAME']; }
16204 if (isset($attr['ONCHANGE'])) { $this
->selectoption
['ONCHANGE'] = $attr
['ONCHANGE']; }
16207 $properties = array();
16211 $this->lastoptionaltag
= 'OPTION'; // Save current HTML specified optional endtag
16212 $this->selectoption
['ACTIVE'] = true;
16213 $this->selectoption
['currentSEL'] = false;
16214 if (empty($this->selectoption
)) {
16215 $this->selectoption
['MAXWIDTH'] = '';
16216 $this->selectoption
['SELECTED'] = '';
16218 if (isset($attr['SELECTED'])) {
16219 $this->selectoption
['SELECTED'] = '';
16220 $this->selectoption
['currentSEL'] = true;
16222 if(isset($attr['VALUE'])) {
16223 $attr['VALUE'] = strcode2utf($attr['VALUE']);
16224 $attr['VALUE'] = $this->lesser_entity_decode($attr['VALUE']);
16225 if ($this->onlyCoreFonts
)
16226 $attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mb_enc
,'UTF-8');
16228 $this->selectoption
['currentVAL'] = $attr['VALUE'];
16232 $objattr = array();
16233 $objattr['margin_top'] = 0;
16234 $objattr['margin_bottom'] = 0;
16235 $objattr['margin_left'] = 0;
16236 $objattr['margin_right'] = 0;
16237 $objattr['width'] = 0;
16238 $objattr['height'] = 0;
16239 $objattr['border_top']['w'] = 0;
16240 $objattr['border_bottom']['w'] = 0;
16241 $objattr['border_left']['w'] = 0;
16242 $objattr['border_right']['w'] = 0;
16243 if(isset($attr['DISABLED'])) { $objattr
['disabled'] = true; }
16244 if(isset($attr['READONLY'])) { $objattr
['readonly'] = true; }
16245 if(isset($attr['REQUIRED'])) { $objattr
['required'] = true; }
16246 if(isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') { $objattr
['spellcheck'] = true; }
16247 if(isset($attr['TITLE'])) { $objattr
['title'] = $attr
['TITLE']; }
16248 if ($this->onlyCoreFonts
)
16249 $objattr['title'] = mb_convert_encoding($objattr['title'], $this->mb_enc
,'UTF-8');
16250 if ($this->useActiveForms
) {
16251 if(isset($attr['NAME'])) { $objattr
['fieldname'] = $attr
['NAME']; }
16252 $this->form
->form_element_spacing
['textarea']['outer']['v'] = 0;
16253 $this->form
->form_element_spacing
['textarea']['inner']['v'] = 0;
16254 if (isset($attr['ONCALCULATE'])) { $objattr
['onCalculate'] = $attr
['ONCALCULATE']; }
16255 else if (isset($attr['ONCHANGE'])) { $objattr
['onCalculate'] = $attr
['ONCHANGE']; }
16256 if (isset($attr['ONVALIDATE'])) { $objattr
['onValidate'] = $attr
['ONVALIDATE']; }
16257 if (isset($attr['ONKEYSTROKE'])) { $objattr
['onKeystroke'] = $attr
['ONKEYSTROKE']; }
16258 if (isset($attr['ONFORMAT'])) { $objattr
['onFormat'] = $attr
['ONFORMAT']; }
16260 $this->InlineProperties
[$tag] = $this->saveInlineProperties();
16261 $properties = $this->cssmgr
->MergeCSS('',$tag,$attr);
16262 if (isset($properties['FONT-FAMILY'])) {
16263 $this->SetFont($properties['FONT-FAMILY'],'',0,false);
16265 if (isset($properties['FONT-SIZE'])) {
16266 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size
/_MPDFK
);
16267 $this->SetFontSize($mmsize*_MPDFK
,false);
16269 if (isset($properties['COLOR'])) { $objattr
['color'] = $this
->ConvertColor($properties
['COLOR']); }
16270 $objattr['fontfamily'] = $this->FontFamily
;
16271 $objattr['fontsize'] = $this->FontSizePt
;
16272 if ($this->useActiveForms
) {
16273 if(isset($properties['TEXT-ALIGN'])) { $objattr
['text_align'] = $align
[strtolower($properties
['TEXT-ALIGN'])]; }
16274 else if(isset($attr['ALIGN'])) { $objattr
['text_align'] = $align
[strtolower($attr
['ALIGN'])]; }
16275 if (isset($properties['OVERFLOW']) && strtolower($properties['OVERFLOW'])=='hidden') { $objattr
['donotscroll'] = true; }
16276 if (isset($properties['BORDER-TOP-COLOR'])) { $objattr
['border-col'] = $this
->ConvertColor($properties
['BORDER-TOP-COLOR']); }
16277 if (isset($properties['BACKGROUND-COLOR'])) { $objattr
['background-col'] = $this
->ConvertColor($properties
['BACKGROUND-COLOR']); }
16279 $this->SetLineHeight('',$this->form
->textarea_lineheight
);
16280 $formLineHeight = $this->lineheight
;
16284 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
16285 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
16286 if ($properties['VERTICAL-ALIGN']) { $objattr
['vertical-align'] = $align
[strtolower($properties
['VERTICAL-ALIGN'])]; }
16288 $colsize = 20; //HTML default value
16289 $rowsize = 2; //HTML default value
16290 if (isset($attr['COLS'])) $colsize = intval($attr['COLS']);
16291 if (isset($attr['ROWS'])) $rowsize = intval($attr['ROWS']);
16293 $charsize = $this->GetCharWidth('w',false);
16294 if ($w) { $colsize
= round(($w
-($this
->form
->form_element_spacing
['textarea']['outer']['h']*2)-($this
->form
->form_element_spacing
['textarea']['inner']['h']*2))/$charsize
); }
16295 if ($h) { $rowsize
= round(($h
-($this
->form
->form_element_spacing
['textarea']['outer']['v']*2)-($this
->form
->form_element_spacing
['textarea']['inner']['v']*2))/$formLineHeight
); }
16297 $objattr['type'] = 'textarea';
16298 $objattr['width'] = ($colsize * $charsize) +
($this->form
->form_element_spacing
['textarea']['outer']['h']*2)+
($this->form
->form_element_spacing
['textarea']['inner']['h']*2);
16299 $objattr['height'] = ($rowsize * $formLineHeight) +
($this->form
->form_element_spacing
['textarea']['outer']['v']*2)+
($this->form
->form_element_spacing
['textarea']['inner']['v']*2);
16300 $objattr['rows'] = $rowsize;
16301 $objattr['cols'] = $colsize;
16303 $this->specialcontent
= serialize($objattr);
16305 if ($this->tableLevel
) { // *TABLES*
16306 $this->cell
[$this->row
][$this->col
]['s'] +
= $objattr['width'] ; // *TABLES*
16309 // Clear properties - tidy up
16310 $properties = array();
16315 // *********** FORM - INPUT ********************
16318 if (!isset($attr['TYPE'])) $attr['TYPE'] == 'TEXT';
16319 $objattr = array();
16320 $objattr['margin_top'] = 0;
16321 $objattr['margin_bottom'] = 0;
16322 $objattr['margin_left'] = 0;
16323 $objattr['margin_right'] = 0;
16324 $objattr['width'] = 0;
16325 $objattr['height'] = 0;
16326 $objattr['border_top']['w'] = 0;
16327 $objattr['border_bottom']['w'] = 0;
16328 $objattr['border_left']['w'] = 0;
16329 $objattr['border_right']['w'] = 0;
16330 $objattr['type'] = 'input';
16331 if(isset($attr['DISABLED'])) { $objattr
['disabled'] = true; }
16332 if(isset($attr['READONLY'])) { $objattr
['readonly'] = true; }
16333 if(isset($attr['REQUIRED'])) { $objattr
['required'] = true; }
16334 if(isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') { $objattr
['spellcheck'] = true; }
16335 if(isset($attr['TITLE'])) { $objattr
['title'] = $attr
['TITLE']; }
16336 else if(isset($attr['ALT'])) { $objattr
['title'] = $attr
['ALT']; }
16337 else $objattr['title'] = '';
16338 $objattr['title'] = strcode2utf($objattr['title']);
16339 $objattr['title'] = $this->lesser_entity_decode($objattr['title']);
16340 if ($this->onlyCoreFonts
)
16341 $objattr['title'] = mb_convert_encoding($objattr['title'], $this->mb_enc
,'UTF-8');
16342 if ($this->useActiveForms
) {
16343 if(isset($attr['NAME'])) { $objattr
['fieldname'] = $attr
['NAME']; }
16345 if(isset($attr['VALUE'])) {
16346 $attr['VALUE'] = strcode2utf($attr['VALUE']);
16347 $attr['VALUE'] = $this->lesser_entity_decode($attr['VALUE']);
16348 if ($this->onlyCoreFonts
)
16349 $attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mb_enc
,'UTF-8');
16350 $objattr['value'] = $attr['VALUE'];
16353 $this->InlineProperties
[$tag] = $this->saveInlineProperties();
16354 $properties = $this->cssmgr
->MergeCSS('',$tag,$attr);
16355 $objattr['vertical-align'] = '';
16357 if (isset($properties['FONT-FAMILY'])) {
16358 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle
,0,false);
16360 if (isset($properties['FONT-SIZE'])) {
16361 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],($this->default_font_size
/_MPDFK
));
16362 $this->SetFontSize($mmsize*_MPDFK
,false);
16364 if (isset($properties['COLOR'])) { $objattr
['color'] = $this
->ConvertColor($properties
['COLOR']); }
16365 $objattr['fontfamily'] = $this->FontFamily
;
16366 $objattr['fontsize'] = $this->FontSizePt
;
16367 if ($this->useActiveForms
) {
16368 if(isset($attr['ALIGN'])) { $objattr
['text_align'] = $align
[strtolower($attr
['ALIGN'])]; }
16369 else if(isset($properties['TEXT-ALIGN'])) { $objattr
['text_align'] = $align
[strtolower($properties
['TEXT-ALIGN'])]; }
16370 if (isset($properties['BORDER-TOP-COLOR'])) { $objattr
['border-col'] = $this
->ConvertColor($properties
['BORDER-TOP-COLOR']); }
16371 if (isset($properties['BACKGROUND-COLOR'])) { $objattr
['background-col'] = $this
->ConvertColor($properties
['BACKGROUND-COLOR']); }
16376 $height = $this->FontSize
;
16378 $spacesize = $this->GetCharWidth(' ',false);
16381 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk
[$this->blklvl
]['inner_width']);
16383 if ($properties['VERTICAL-ALIGN']) { $objattr
['vertical-align'] = $align
[strtolower($properties
['VERTICAL-ALIGN'])]; }
16385 switch(strtoupper($attr['TYPE'])){
16387 $this->ignorefollowingspaces
= true; //Eliminate exceeding left-side spaces
16388 if ($this->useActiveForms
) {
16389 $this->form
->SetFormText( 0, 0, $objattr['fieldname'], $objattr['value'], $objattr['value'], '', 0, '', true );
16391 if ($this->InlineProperties
[$tag]) { $this
->restoreInlineProperties($this
->InlineProperties
[$tag
]); }
16392 unset($this->InlineProperties
[$tag]);
16394 case 'CHECKBOX': //Draw Checkbox
16395 $type = 'CHECKBOX';
16396 if (isset($attr['CHECKED'])) { $objattr
['checked'] = true; }
16397 else { $objattr
['checked'] = false; }
16398 $width = $this->FontSize
;
16399 $height = $this->FontSize
;
16402 case 'RADIO': //Draw Radio button
16404 if (isset($attr['CHECKED'])) $objattr['checked'] = true;
16405 $width = $this->FontSize
;
16406 $height = $this->FontSize
;
16409 /*-- IMAGES-CORE --*/
16410 case 'IMAGE': // Draw an Image button
16411 if(isset($attr['SRC'])) {
16413 $srcpath = $attr['SRC'];
16414 $orig_srcpath = $attr['ORIG_SRC'];
16415 // VSPACE and HSPACE converted to margins in MergeCSS
16416 if (isset($properties['MARGIN-TOP'])) { $objattr
['margin_top']=$this
->ConvertSize($properties
['MARGIN-TOP'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16417 if (isset($properties['MARGIN-BOTTOM'])) { $objattr
['margin_bottom'] = $this
->ConvertSize($properties
['MARGIN-BOTTOM'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16418 if (isset($properties['MARGIN-LEFT'])) { $objattr
['margin_left'] = $this
->ConvertSize($properties
['MARGIN-LEFT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16419 if (isset($properties['MARGIN-RIGHT'])) { $objattr
['margin_right'] = $this
->ConvertSize($properties
['MARGIN-RIGHT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16422 if (isset($properties['BORDER-TOP'])) { $objattr
['border_top'] = $this
->border_details($properties
['BORDER-TOP']); }
16423 if (isset($properties['BORDER-BOTTOM'])) { $objattr
['border_bottom'] = $this
->border_details($properties
['BORDER-BOTTOM']); }
16424 if (isset($properties['BORDER-LEFT'])) { $objattr
['border_left'] = $this
->border_details($properties
['BORDER-LEFT']); }
16425 if (isset($properties['BORDER-RIGHT'])) { $objattr
['border_right'] = $this
->border_details($properties
['BORDER-RIGHT']); }
16427 $objattr['padding_top'] = 0;
16428 $objattr['padding_bottom'] = 0;
16429 $objattr['padding_left'] = 0;
16430 $objattr['padding_right'] = 0;
16432 if (isset($properties['VERTICAL-ALIGN'])) { $objattr
['vertical-align'] = $align
[strtolower($properties
['VERTICAL-ALIGN'])]; }
16436 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk
[$this->blklvl
]['inner_width']);
16437 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk
[$this->blklvl
]['inner_width']);
16439 $extraheight = $objattr['margin_top'] +
$objattr['margin_bottom'] +
$objattr['border_top']['w'] +
$objattr['border_bottom']['w'];
16440 $extrawidth = $objattr['margin_left'] +
$objattr['margin_right'] +
$objattr['border_left']['w'] +
$objattr['border_right']['w'];
16443 $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
16445 $info = $this->_getImage($this->noImageFile
);
16447 $srcpath = $this->noImageFile
;
16448 $w = ($info['w'] * (25.4/$this->dpi
));
16449 $h = ($info['h'] * (25.4/$this->dpi
));
16453 if ($info['cs']=='Indexed') { $objattr
['Indexed'] = true; }
16454 $objattr['file'] = $srcpath;
16455 //Default width and height calculation if needed
16456 if($w==0 and $h==0) {
16457 /*-- IMAGES-WMF --*/
16458 if ($info['type']=='wmf') {
16459 // WMF units are twips (1/20pt)
16460 // divide by 20 to get points
16461 // divide by k to get user units
16462 $w = abs($info['w'])/(20*_MPDFK
);
16463 $h = abs($info['h']) / (20*_MPDFK
);
16466 /*-- END IMAGES-WMF --*/
16467 if ($info['type']=='svg') {
16468 // SVG units are pixels
16469 $w = abs($info['w'])/_MPDFK
;
16470 $h = abs($info['h'])/_MPDFK
;
16473 //Put image at default image dpi
16474 $w=($info['w']/_MPDFK
) * (72/$this->img_dpi
);
16475 $h=($info['h']/_MPDFK
) * (72/$this->img_dpi
);
16477 if (isset($properties['IMAGE-RESOLUTION'])) {
16478 if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi']>0) {
16479 $w *= $this->img_dpi
/ $info['set-dpi'];
16480 $h *= $this->img_dpi
/ $info['set-dpi'];
16482 else if (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) {
16485 $w *= $this->img_dpi
/ $dpi;
16486 $h *= $this->img_dpi
/ $dpi;
16491 // IF WIDTH OR HEIGHT SPECIFIED
16492 if($w==0) $w=$h*$info['w']/$info['h'];
16493 if($h==0) $h=$w*$info['h']/$info['w'];
16494 // Resize to maximum dimensions of page
16495 $maxWidth = $this->blk
[$this->blklvl
]['inner_width'];
16496 $maxHeight = $this->h
- ($this->tMargin +
$this->bMargin +
10) ;
16497 if ($this->fullImageHeight
) { $maxHeight
= $this
->fullImageHeight
; }
16498 if ($w +
$extrawidth > $maxWidth ) {
16499 $w = $maxWidth - $extrawidth;
16500 $h=$w*$info['h']/$info['w'];
16502 if ($h +
$extraheight > $maxHeight ) {
16503 $h = $maxHeight - $extraheight;
16504 $w=$h*$info['w']/$info['h'];
16506 $height = $h +
$extraheight;
16507 $width = $w +
$extrawidth;
16508 $objattr['type'] = 'image';
16509 $objattr['itype'] = $info['type'];
16510 $objattr['orig_h'] = $info['h'];
16511 $objattr['orig_w'] = $info['w'];
16512 /*-- IMAGES-WMF --*/
16513 if ($info['type']=='wmf') {
16514 $objattr['wmf_x'] = $info['x'];
16515 $objattr['wmf_y'] = $info['y'];
16518 /*-- END IMAGES-WMF --*/
16519 if ($info['type']=='svg') {
16520 $objattr['wmf_x'] = $info['x'];
16521 $objattr['wmf_y'] = $info['y'];
16523 $objattr['height'] = $h +
$extraheight;
16524 $objattr['width'] = $w +
$extrawidth;
16526 $objattr['image_height'] = $h;
16527 $objattr['image_width'] = $w;
16528 $objattr['ID'] = $info['i'];
16530 if ($this->useActiveForms
) {
16531 if (isset($attr['ONCLICK'])) { $objattr
['onClick'] = $attr
['ONCLICK']; }
16532 $objattr['type'] = 'input';
16537 /*-- END IMAGES-CORE --*/
16539 case 'BUTTON': // Draw a button
16542 $type = strtoupper($attr['TYPE']);
16543 if ($type=='IMAGE') { $type
= 'BUTTON'; } // src path not found
16544 if(isset($attr['NOPRINT'])) { $objattr
['noprint'] = true; }
16545 if (!isset($attr['VALUE'])) {
16546 $objattr['value'] = ucfirst(strtolower($type));
16549 $texto = " " . $objattr['value'] . " ";
16550 $width = $this->GetStringWidth($texto) +
($this->form
->form_element_spacing
['button']['outer']['h']*2)+
($this->form
->form_element_spacing
['button']['inner']['h']*2);
16551 $height = $this->FontSize +
($this->form
->form_element_spacing
['button']['outer']['v']*2)+
($this->form
->form_element_spacing
['button']['inner']['v']*2);
16552 if ($this->useActiveForms
) {
16553 if (isset($attr['ONCLICK'])) { $objattr
['onClick'] = $attr
['ONCLICK']; }
16560 if ($type == '') { $type
= 'TEXT'; }
16561 if(strtoupper($attr['TYPE'])=='PASSWORD') { $type
= 'PASSWORD'; }
16562 if (isset($attr['VALUE'])) {
16563 if ($type == 'PASSWORD') {
16564 $num_stars = mb_strlen($attr['VALUE'],$this->mb_enc
);
16565 $texto = str_repeat('*',$num_stars);
16567 else { $texto
= $attr
['VALUE']; }
16569 $xw = ($this->form
->form_element_spacing
['input']['outer']['h']*2)+
($this->form
->form_element_spacing
['input']['inner']['h']*2);
16570 $xh = ($this->form
->form_element_spacing
['input']['outer']['v']*2)+
($this->form
->form_element_spacing
['input']['inner']['v']*2);
16571 if ($w) { $width
= $w + $xw
; }
16572 else { $width
= (20 * $spacesize
) + $xw
; } // Default width in chars
16573 if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $width = ($attr['SIZE'] * $spacesize) +
$xw;
16574 $height = $this->FontSize +
$xh;
16575 if (isset($attr['MAXLENGTH']) and ctype_digit($attr['MAXLENGTH']) ) $objattr['maxlength'] = $attr['MAXLENGTH'];
16576 if ($this->useActiveForms
) {
16577 if (isset($attr['ONCALCULATE'])) { $objattr
['onCalculate'] = $attr
['ONCALCULATE']; }
16578 else if (isset($attr['ONCHANGE'])) { $objattr
['onCalculate'] = $attr
['ONCHANGE']; }
16579 if (isset($attr['ONVALIDATE'])) { $objattr
['onValidate'] = $attr
['ONVALIDATE']; }
16580 if (isset($attr['ONKEYSTROKE'])) { $objattr
['onKeystroke'] = $attr
['ONKEYSTROKE']; }
16581 if (isset($attr['ONFORMAT'])) { $objattr
['onFormat'] = $attr
['ONFORMAT']; }
16586 $objattr['subtype'] = $type;
16587 $objattr['text'] = $texto;
16588 $objattr['width'] = $width;
16589 $objattr['height'] = $height;
16590 $e = "\xbb\xa4\xactype=input,objattr=".serialize($objattr)."\xbb\xa4\xac";
16592 // Clear properties - tidy up
16593 $properties = array();
16596 // Output it to buffers
16597 if ($this->tableLevel
) {
16598 $this->_saveCellTextBuffer($e, $this->HREF
);
16599 $this->cell
[$this->row
][$this->col
]['s'] +
= $objattr['width'] ;
16603 /*-- END TABLES --*/
16604 $this->_saveTextBuffer($e, $this->HREF
);
16607 if ($this->InlineProperties
[$tag]) { $this
->restoreInlineProperties($this
->InlineProperties
[$tag
]); }
16608 unset($this->InlineProperties
[$tag]);
16610 break; // END of INPUT
16611 /*-- END FORMS --*/
16614 // *********** GRAPH ********************
16616 if (!$this->useGraphs
) { break; }
16617 if ($attr['TABLE']) { $gid
= strtoupper($attr
['TABLE']); }
16618 else { $gid
= '0'; }
16619 if (!is_array($this->graphs
[$gid]) || count($this->graphs
[$gid])==0 ) { break; }
16620 include_once(_MPDF_PATH
.'graph.php');
16621 $this->graphs
[$gid]['attr'] = $attr;
16624 if (isset($this->graphs
[$gid]['attr']['WIDTH']) && $this->graphs
[$gid]['attr']['WIDTH']) {
16625 $this->graphs
[$gid]['attr']['cWIDTH']=$this->ConvertSize($this->graphs
[$gid]['attr']['WIDTH'],$pgwidth);
16627 if (isset($this->graphs
[$gid]['attr']['HEIGHT']) && $this->graphs
[$gid]['attr']['HEIGHT']) {
16628 $this->graphs
[$gid]['attr']['cHEIGHT']=$this->ConvertSize($this->graphs
[$gid]['attr']['HEIGHT'],$pgwidth);
16631 $graph_img = print_graph($this->graphs
[$gid],$this->blk
[$this->blklvl
]['inner_width']);
16633 if(isset($attr['ROTATE'])) {
16634 if ($attr['ROTATE']==90 || $attr['ROTATE']==-90) {
16635 $tmpw = $graph_img['w'];
16636 $graph_img['w']= $graph_img['h'];
16637 $graph_img['h']= $tmpw;
16640 $attr['SRC'] = $graph_img['file'];
16641 $attr['WIDTH'] = $graph_img['w'];
16642 $attr['HEIGHT'] = $graph_img['h'];
16646 // *********** IMAGE ********************
16647 /*-- IMAGES-CORE --*/
16649 if ($this->progressBar
) { $this
->UpdateProgressBar(1,'','IMG'); } // *PROGRESS-BAR*
16650 $objattr = array();
16651 $objattr['margin_top'] = 0;
16652 $objattr['margin_bottom'] = 0;
16653 $objattr['margin_left'] = 0;
16654 $objattr['margin_right'] = 0;
16655 $objattr['padding_top'] = 0;
16656 $objattr['padding_bottom'] = 0;
16657 $objattr['padding_left'] = 0;
16658 $objattr['padding_right'] = 0;
16659 $objattr['width'] = 0;
16660 $objattr['height'] = 0;
16661 $objattr['border_top']['w'] = 0;
16662 $objattr['border_bottom']['w'] = 0;
16663 $objattr['border_left']['w'] = 0;
16664 $objattr['border_right']['w'] = 0;
16665 if(isset($attr['SRC'])) {
16666 $srcpath = $attr['SRC'];
16667 $orig_srcpath = $attr['ORIG_SRC'];
16668 $properties = $this->cssmgr
->MergeCSS('',$tag,$attr);
16669 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
16672 // mPDF 5.6.01 - LAYERS
16673 if (isset($properties['Z-INDEX']) && $this->currentlayer
==0) {
16674 $v = intval($properties['Z-INDEX']);
16676 $objattr['z-index'] = $v;
16680 $objattr['visibility'] = 'visible';
16681 if (isset($properties['VISIBILITY'])) {
16682 $v = strtolower($properties['VISIBILITY']);
16683 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility
=='visible') {
16684 $objattr['visibility'] = $v;
16688 // VSPACE and HSPACE converted to margins in MergeCSS
16689 if (isset($properties['MARGIN-TOP'])) { $objattr
['margin_top']=$this
->ConvertSize($properties
['MARGIN-TOP'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16690 if (isset($properties['MARGIN-BOTTOM'])) { $objattr
['margin_bottom'] = $this
->ConvertSize($properties
['MARGIN-BOTTOM'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16691 if (isset($properties['MARGIN-LEFT'])) { $objattr
['margin_left'] = $this
->ConvertSize($properties
['MARGIN-LEFT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16692 if (isset($properties['MARGIN-RIGHT'])) { $objattr
['margin_right'] = $this
->ConvertSize($properties
['MARGIN-RIGHT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16694 if (isset($properties['PADDING-TOP'])) { $objattr
['padding_top']=$this
->ConvertSize($properties
['PADDING-TOP'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16695 if (isset($properties['PADDING-BOTTOM'])) { $objattr
['padding_bottom'] = $this
->ConvertSize($properties
['PADDING-BOTTOM'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16696 if (isset($properties['PADDING-LEFT'])) { $objattr
['padding_left'] = $this
->ConvertSize($properties
['PADDING-LEFT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16697 if (isset($properties['PADDING-RIGHT'])) { $objattr
['padding_right'] = $this
->ConvertSize($properties
['PADDING-RIGHT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16699 if (isset($properties['BORDER-TOP'])) { $objattr
['border_top'] = $this
->border_details($properties
['BORDER-TOP']); }
16700 if (isset($properties['BORDER-BOTTOM'])) { $objattr
['border_bottom'] = $this
->border_details($properties
['BORDER-BOTTOM']); }
16701 if (isset($properties['BORDER-LEFT'])) { $objattr
['border_left'] = $this
->border_details($properties
['BORDER-LEFT']); }
16702 if (isset($properties['BORDER-RIGHT'])) { $objattr
['border_right'] = $this
->border_details($properties
['BORDER-RIGHT']); }
16704 if (isset($properties['VERTICAL-ALIGN'])) { $objattr
['vertical-align'] = $align
[strtolower($properties
['VERTICAL-ALIGN'])]; }
16707 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
16708 else if(isset($attr['WIDTH'])) $w = $this->ConvertSize($attr['WIDTH'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
16709 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
16710 else if(isset($attr['HEIGHT'])) $h = $this->ConvertSize($attr['HEIGHT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
16711 // mPDF 5.5.15 // mPDF 5.6.60
16712 $maxw=$maxh=$minw=$minh=false;
16713 if(isset($properties['MAX-WIDTH'])) $maxw = $this->ConvertSize($properties['MAX-WIDTH'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
16714 else if(isset($attr['MAX-WIDTH'])) $maxw = $this->ConvertSize($attr['MAX-WIDTH'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
16715 if(isset($properties['MAX-HEIGHT'])) $maxh = $this->ConvertSize($properties['MAX-HEIGHT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
16716 else if(isset($attr['MAX-HEIGHT'])) $maxh = $this->ConvertSize($attr['MAX-HEIGHT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
16717 if(isset($properties['MIN-WIDTH'])) $minw = $this->ConvertSize($properties['MIN-WIDTH'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
16718 else if(isset($attr['MIN-WIDTH'])) $minw = $this->ConvertSize($attr['MIN-WIDTH'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
16719 if(isset($properties['MIN-HEIGHT'])) $minh = $this->ConvertSize($properties['MIN-HEIGHT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
16720 else if(isset($attr['MIN-HEIGHT'])) $minh = $this->ConvertSize($attr['MIN-HEIGHT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
16722 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr
['opacity'] = $properties
['OPACITY']; }
16724 if (strpos($this->HREF
,".") === false && strpos($this->HREF
,"@") !== 0) {
16725 $href = $this->HREF
;
16726 while(array_key_exists($href,$this->internallink
)) $href="#".$href;
16727 $this->internallink
[$href] = $this->AddLink();
16728 $objattr['link'] = $this->internallink
[$href];
16730 else { $objattr
['link'] = $this
->HREF
; }
16732 $extraheight = $objattr['padding_top'] +
$objattr['padding_bottom'] +
$objattr['margin_top'] +
$objattr['margin_bottom'] +
$objattr['border_top']['w'] +
$objattr['border_bottom']['w'];
16733 $extrawidth = $objattr['padding_left'] +
$objattr['padding_right'] +
$objattr['margin_left'] +
$objattr['margin_right'] +
$objattr['border_left']['w'] +
$objattr['border_right']['w'];
16735 /*-- BACKGROUNDS --*/
16736 if(isset($properties['GRADIENT-MASK']) && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/',$properties['GRADIENT-MASK'])) {
16737 $objattr['GRADIENT-MASK'] = $properties['GRADIENT-MASK'];
16739 /*-- END BACKGROUNDS --*/
16742 $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
16744 $info = $this->_getImage($this->noImageFile
);
16746 $srcpath = $this->noImageFile
;
16747 $w = ($info['w'] * (25.4/$this->dpi
));
16748 $h = ($info['h'] * (25.4/$this->dpi
));
16753 if(isset($attr['ROTATE'])) { $image_orientation
= $attr
['ROTATE']; }
16754 else if(isset($properties['IMAGE-ORIENTATION'])) { $image_orientation
= $properties
['IMAGE-ORIENTATION']; }
16755 else { $image_orientation
= 0; }
16756 if($image_orientation) {
16757 if ($image_orientation==90 || $image_orientation==-90 || $image_orientation==270) {
16758 $tmpw = $info['w'];
16759 $info['w'] = $info['h'];
16760 $info['h'] = $tmpw;
16762 $objattr['ROTATE'] = $image_orientation;
16765 $objattr['file'] = $srcpath;
16766 //Default width and height calculation if needed
16767 if($w==0 and $h==0) {
16768 /*-- IMAGES-WMF --*/
16769 if ($info['type']=='wmf') {
16770 // WMF units are twips (1/20pt)
16771 // divide by 20 to get points
16772 // divide by k to get user units
16773 $w = abs($info['w'])/(20*_MPDFK
);
16774 $h = abs($info['h']) / (20*_MPDFK
);
16777 /*-- END IMAGES-WMF --*/
16778 if ($info['type']=='svg') {
16779 // SVG units are pixels
16780 $w = abs($info['w'])/_MPDFK
;
16781 $h = abs($info['h'])/_MPDFK
;
16784 //Put image at default image dpi
16785 $w=($info['w']/_MPDFK
) * (72/$this->img_dpi
);
16786 $h=($info['h']/_MPDFK
) * (72/$this->img_dpi
);
16788 if (isset($properties['IMAGE-RESOLUTION'])) {
16789 if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi']>0) {
16790 $w *= $this->img_dpi
/ $info['set-dpi'];
16791 $h *= $this->img_dpi
/ $info['set-dpi'];
16793 else if (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) {
16796 $w *= $this->img_dpi
/ $dpi;
16797 $h *= $this->img_dpi
/ $dpi;
16802 // IF WIDTH OR HEIGHT SPECIFIED
16803 if($w==0) $w=abs($h*$info['w']/$info['h']);
16804 if($h==0) $h=abs($w*$info['h']/$info['w']);
16807 if ($minw && $w<$minw) { $w
= $minw
; $h
=abs($w
*$info
['h']/$info
['w']); }
16808 if ($maxw && $w>$maxw) { $w
= $maxw
; $h
=abs($w
*$info
['h']/$info
['w']); }
16809 if ($minh && $h<$minh) { $h
= $minh
; $w
=abs($h
*$info
['w']/$info
['h']); }
16810 if ($maxh && $h>$maxh) { $h
= $maxh
; $w
=abs($h
*$info
['w']/$info
['h']); }
16812 // Resize to maximum dimensions of page
16813 $maxWidth = $this->blk
[$this->blklvl
]['inner_width'];
16814 $maxHeight = $this->h
- ($this->tMargin +
$this->bMargin +
1) ;
16815 if ($this->fullImageHeight
) { $maxHeight
= $this
->fullImageHeight
; }
16816 if ($w +
$extrawidth > $maxWidth ) {
16817 $w = $maxWidth - $extrawidth;
16818 $h=abs($w*$info['h']/$info['w']);
16821 if ($h +
$extraheight > $maxHeight ) {
16822 $h = $maxHeight - $extraheight;
16823 $w=abs($h*$info['w']/$info['h']);
16825 $objattr['type'] = 'image';
16826 $objattr['itype'] = $info['type'];
16828 $objattr['orig_h'] = $info['h'];
16829 $objattr['orig_w'] = $info['w'];
16830 /*-- IMAGES-WMF --*/
16831 if ($info['type']=='wmf') {
16832 $objattr['wmf_x'] = $info['x'];
16833 $objattr['wmf_y'] = $info['y'];
16836 /*-- END IMAGES-WMF --*/
16837 if ($info['type']=='svg') {
16838 $objattr['wmf_x'] = $info['x'];
16839 $objattr['wmf_y'] = $info['y'];
16841 $objattr['height'] = $h +
$extraheight;
16842 $objattr['width'] = $w +
$extrawidth;
16843 $objattr['image_height'] = $h;
16844 $objattr['image_width'] = $w;
16845 /*-- CSS-IMAGE-FLOAT --*/
16846 if (!$this->ColActive
&& !$this->tableLevel
&& !$this->listlvl
&& !$this->kwt
&& !$this->keep_block_together
) {
16847 if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) == 'RIGHT' || strtoupper($properties['FLOAT']) == 'LEFT')) {
16848 $objattr['float'] = substr(strtoupper($properties['FLOAT']),0,1);
16851 /*-- END CSS-IMAGE-FLOAT --*/
16853 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
16855 // Clear properties - tidy up
16856 $properties = array();
16859 // Output it to buffers
16860 if ($this->tableLevel
) {
16861 $this->_saveCellTextBuffer($e, $this->HREF
);
16862 $this->cell
[$this->row
][$this->col
]['s'] +
= $objattr['width'] ;
16865 /*-- END TABLES --*/
16866 $this->_saveTextBuffer($e, $this->HREF
);
16868 /*-- ANNOTATIONS --*/
16869 if ($this->title2annots
&& isset($attr['TITLE'])) {
16870 $objattr = array();
16871 $objattr['margin_top'] = 0;
16872 $objattr['margin_bottom'] = 0;
16873 $objattr['margin_left'] = 0;
16874 $objattr['margin_right'] = 0;
16875 $objattr['width'] = 0;
16876 $objattr['height'] = 0;
16877 $objattr['border_top']['w'] = 0;
16878 $objattr['border_bottom']['w'] = 0;
16879 $objattr['border_left']['w'] = 0;
16880 $objattr['border_right']['w'] = 0;
16881 $objattr['CONTENT'] = $attr['TITLE'];
16882 $objattr['type'] = 'annot';
16883 $objattr['POS-X'] = 0;
16884 $objattr['POS-Y'] = 0;
16885 $objattr['ICON'] = 'Comment';
16886 $objattr['AUTHOR'] = '';
16887 $objattr['SUBJECT'] = '';
16888 $objattr['OPACITY'] = $this->annotOpacity
;
16889 $objattr['COLOR'] = $this->ConvertColor('yellow');
16890 $e = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
16891 if($this->tableLevel
) { // *TABLES*
16892 $this->cell
[$this->row
][$this->col
]['textbuffer'][] = array($e); // *TABLES*
16895 $this->textbuffer
[] = array($e);
16898 /*-- END ANNOTATIONS --*/
16901 /*-- END IMAGES-CORE --*/
16904 // *********** CIRCULAR TEXT = TEXTCIRCLE ********************
16906 $objattr = array();
16907 $objattr['margin_top'] = 0;
16908 $objattr['margin_bottom'] = 0;
16909 $objattr['margin_left'] = 0;
16910 $objattr['margin_right'] = 0;
16911 $objattr['padding_top'] = 0;
16912 $objattr['padding_bottom'] = 0;
16913 $objattr['padding_left'] = 0;
16914 $objattr['padding_right'] = 0;
16915 $objattr['width'] = 0;
16916 $objattr['height'] = 0;
16917 $objattr['border_top']['w'] = 0;
16918 $objattr['border_bottom']['w'] = 0;
16919 $objattr['border_left']['w'] = 0;
16920 $objattr['border_right']['w'] = 0;
16921 $objattr['top-text'] = '';
16922 $objattr['bottom-text'] = '';
16923 $objattr['r'] = 20; // radius (default value here for safety)
16924 $objattr['space-width'] = 120;
16925 $objattr['char-width'] = 100;
16927 $this->InlineProperties
[$tag] = $this->saveInlineProperties();
16928 $properties = $this->cssmgr
->MergeCSS('INLINE',$tag,$attr);
16930 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
16933 if (isset($attr['R'])) { $objattr
['r']=$this
->ConvertSize($attr
['R'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16934 if(isset($attr['TOP-TEXT'])) {
16935 $objattr['top-text'] = strcode2utf($attr['TOP-TEXT']);
16936 $objattr['top-text'] = $this->lesser_entity_decode($objattr['top-text']);
16937 if ($this->onlyCoreFonts
)
16938 $objattr['top-text'] = mb_convert_encoding($objattr['top-text'], $this->mb_enc
,'UTF-8');
16940 if(isset($attr['BOTTOM-TEXT'])) {
16941 $objattr['bottom-text'] = strcode2utf($attr['BOTTOM-TEXT']);
16942 $objattr['bottom-text'] = $this->lesser_entity_decode($objattr['bottom-text']);
16943 if ($this->onlyCoreFonts
)
16944 $objattr['bottom-text'] = mb_convert_encoding($objattr['bottom-text'], $this->mb_enc
,'UTF-8');
16946 if(isset($attr['SPACE-WIDTH']) && $attr['SPACE-WIDTH']) { $objattr
['space-width'] = $attr
['SPACE-WIDTH']; }
16947 if(isset($attr['CHAR-WIDTH']) && $attr['CHAR-WIDTH']) { $objattr
['char-width'] = $attr
['CHAR-WIDTH']; }
16950 $objattr['visibility'] = 'visible';
16951 if (isset($properties['VISIBILITY'])) {
16952 $v = strtolower($properties['VISIBILITY']);
16953 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility
=='visible') {
16954 $objattr['visibility'] = $v;
16958 if (isset($properties['FONT-SIZE'])) {
16959 if (strtolower($properties['FONT-SIZE'])=='auto') {
16960 if ($objattr['top-text'] && $objattr['bottom-text']) {
16961 $objattr['fontsize'] = -2;
16964 $objattr['fontsize'] = -1;
16968 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],($this->default_font_size
/_MPDFK
));
16969 $this->SetFontSize($mmsize*_MPDFK
,false);
16970 $objattr['fontsize'] = $this->FontSizePt
;
16974 if(isset($attr['DIVIDER'])) {
16975 $objattr['divider'] = strcode2utf($attr['DIVIDER']);
16976 $objattr['divider'] = $this->lesser_entity_decode($objattr['divider']);
16977 if ($this->onlyCoreFonts
)
16978 $objattr['divider'] = mb_convert_encoding($objattr['divider'], $this->mb_enc
,'UTF-8');
16982 if (isset($properties['COLOR'])) { $objattr
['color'] = $this
->ConvertColor($properties
['COLOR']); }
16984 $objattr['fontstyle'] = '';
16985 if (isset($properties['FONT-WEIGHT'])) {
16986 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $objattr
['fontstyle'] .= 'B'; }
16988 if (isset($properties['FONT-STYLE'])) {
16989 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $objattr
['fontstyle'] .= 'I'; }
16992 if (isset($properties['FONT-FAMILY'])) {
16993 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle
,0,false);
16995 $objattr['fontfamily'] = $this->FontFamily
;
16997 // VSPACE and HSPACE converted to margins in MergeCSS
16998 if (isset($properties['MARGIN-TOP'])) { $objattr
['margin_top']=$this
->ConvertSize($properties
['MARGIN-TOP'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
16999 if (isset($properties['MARGIN-BOTTOM'])) { $objattr
['margin_bottom'] = $this
->ConvertSize($properties
['MARGIN-BOTTOM'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
17000 if (isset($properties['MARGIN-LEFT'])) { $objattr
['margin_left'] = $this
->ConvertSize($properties
['MARGIN-LEFT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
17001 if (isset($properties['MARGIN-RIGHT'])) { $objattr
['margin_right'] = $this
->ConvertSize($properties
['MARGIN-RIGHT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
17003 if (isset($properties['PADDING-TOP'])) { $objattr
['padding_top']=$this
->ConvertSize($properties
['PADDING-TOP'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
17004 if (isset($properties['PADDING-BOTTOM'])) { $objattr
['padding_bottom'] = $this
->ConvertSize($properties
['PADDING-BOTTOM'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
17005 if (isset($properties['PADDING-LEFT'])) { $objattr
['padding_left'] = $this
->ConvertSize($properties
['PADDING-LEFT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
17006 if (isset($properties['PADDING-RIGHT'])) { $objattr
['padding_right'] = $this
->ConvertSize($properties
['PADDING-RIGHT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
17008 if (isset($properties['BORDER-TOP'])) { $objattr
['border_top'] = $this
->border_details($properties
['BORDER-TOP']); }
17009 if (isset($properties['BORDER-BOTTOM'])) { $objattr
['border_bottom'] = $this
->border_details($properties
['BORDER-BOTTOM']); }
17010 if (isset($properties['BORDER-LEFT'])) { $objattr
['border_left'] = $this
->border_details($properties
['BORDER-LEFT']); }
17011 if (isset($properties['BORDER-RIGHT'])) { $objattr
['border_right'] = $this
->border_details($properties
['BORDER-RIGHT']); }
17013 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr
['opacity'] = $properties
['OPACITY']; }
17014 if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { $objattr
['bgcolor'] = $this
->ConvertColor($properties
['BACKGROUND-COLOR']); }
17015 else { $objattr
['bgcolor'] = false; }
17017 if (strpos($this->HREF
,".") === false && strpos($this->HREF
,"@") !== 0) {
17018 $href = $this->HREF
;
17019 while(array_key_exists($href,$this->internallink
)) $href="#".$href;
17020 $this->internallink
[$href] = $this->AddLink();
17021 $objattr['link'] = $this->internallink
[$href];
17023 else { $objattr
['link'] = $this
->HREF
; }
17025 $extraheight = $objattr['padding_top'] +
$objattr['padding_bottom'] +
$objattr['margin_top'] +
$objattr['margin_bottom'] +
$objattr['border_top']['w'] +
$objattr['border_bottom']['w'];
17026 $extrawidth = $objattr['padding_left'] +
$objattr['padding_right'] +
$objattr['margin_left'] +
$objattr['margin_right'] +
$objattr['border_left']['w'] +
$objattr['border_right']['w'];
17029 $w = $objattr['r']*2;
17031 $objattr['height'] = $h +
$extraheight;
17032 $objattr['width'] = $w +
$extrawidth;
17033 $objattr['type'] = 'textcircle';
17035 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
17037 // Clear properties - tidy up
17038 $properties = array();
17041 // Output it to buffers
17042 if ($this->tableLevel
) {
17043 $this->_saveCellTextBuffer($e, $this->HREF
);
17044 $this->cell
[$this->row
][$this->col
]['s'] +
= $objattr['width'] ;
17047 /*-- END TABLES --*/
17048 $this->_saveTextBuffer($e, $this->HREF
);
17051 if ($this->InlineProperties
[$tag]) { $this
->restoreInlineProperties($this
->InlineProperties
[$tag
]); }
17052 unset($this->InlineProperties
[$tag]);
17059 case 'TABLE': // TABLE-BEGIN
17060 $this->tdbegin
= false;
17061 $this->lastoptionaltag
= '';
17062 // Disable vertical justification in columns
17063 if ($this->ColActive
) { $this
->colvAlign
= ''; } // *COLUMNS*
17064 if ($this->lastblocklevelchange
== 1) { $blockstate
= 1; } // Top margins/padding only
17065 else if ($this->lastblocklevelchange
< 1) { $blockstate
= 0; } // NO margins/padding
17066 // called from block after new div e.g. <div> ... <table> ... Outputs block top margin/border and padding
17067 if (count($this->textbuffer
) == 0 && $this->lastblocklevelchange
== 1 && !$this->tableLevel
&& !$this->kwt
) {
17068 $this->newFlowingBlock( $this->blk
[$this->blklvl
]['width'],$this->lineheight
,'',false,false,1,true, $this->blk
[$this->blklvl
]['direction']);
17069 $this->finishFlowingBlock(true); // true = END of flowing block
17071 else if (!$this->tableLevel
&& count($this->textbuffer
)) { $this
->printbuffer($this
->textbuffer
,$blockstate
); }
17073 $this->textbuffer
=array();
17074 $this->lastblocklevelchange
= -1;
17075 if ($this->tableLevel
) { // i.e. now a nested table coming...
17076 // Save current level table
17078 $this->cell
['PARENTCELL'] = $this->saveInlineProperties();
17079 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['baseProperties']= $this->base_table_properties
;
17080 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['cells'] = $this->cell
;
17081 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['currrow'] = $this->row
;
17082 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['currcol'] = $this->col
;
17084 $this->tableLevel++
;
17085 $this->cssmgr
->tbCSSlvl++
;
17087 if ($this->tableLevel
>1) { // inherit table properties from cell in which nested
17088 $this->base_table_properties
['FONT-KERNING'] = $this->kerning
;
17089 $this->base_table_properties
['LETTER-SPACING'] = $this->lSpacingCSS
;
17090 $this->base_table_properties
['WORD-SPACING'] = $this->wSpacingCSS
;
17093 if (isset($this->tbctr
[$this->tableLevel
])) { $this
->tbctr
[$this
->tableLevel
]++
; }
17094 else { $this
->tbctr
[$this
->tableLevel
] = 1; }
17096 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['level'] = $this->tableLevel
;
17097 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['levelid'] = $this->tbctr
[$this->tableLevel
];
17099 if ($this->tableLevel
> $this->innermostTableLevel
) { $this
->innermostTableLevel
= $this
->tableLevel
; }
17100 if ($this->tableLevel
> 1) {
17101 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['nestedpos'] = array($this->row
,$this->col
,$this->tbctr
[($this->tableLevel
-1)]);
17103 //++++++++++++++++++++++++++++
17105 $this->cell
= array();
17106 $this->col
=-1; //int
17107 $this->row
=-1; //int
17108 $table = &$this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]];
17110 // New table - any level
17111 if ($this->cacheTables
) {
17112 $this->packTableData
= true; // required for cacheTables
17113 $this->simpleTables
= false; // Cannot co-exist with cacheTables
17114 $table['cache'] = _MPDF_TEMP_PATH
.'_tempTblCache'.RAND(1,1000000).'.dat';
17115 $fh = fopen($table['cache'] , "wb") or $this->Error("When using cacheTables, you must have read/write access to cache files (".$table['cache'] .")");
17116 fwrite($fh, "\x00");
17118 $table['ptr'] = 1 ; // Must not be 0
17121 $table['direction'] = $this->directionality
;
17122 $table['bgcolor'] = false;
17123 $table['va'] = false;
17124 $table['txta'] = false;
17125 $table['topntail'] = false;
17126 $table['thead-underline'] = false;
17127 $table['border'] = false;
17128 $table['border_details']['R']['w'] = 0;
17129 $table['border_details']['L']['w'] = 0;
17130 $table['border_details']['T']['w'] = 0;
17131 $table['border_details']['B']['w'] = 0;
17132 $table['border_details']['R']['style'] = '';
17133 $table['border_details']['L']['style'] = '';
17134 $table['border_details']['T']['style'] = '';
17135 $table['border_details']['B']['style'] = '';
17136 $table['max_cell_border_width']['R'] = 0;
17137 $table['max_cell_border_width']['L'] = 0;
17138 $table['max_cell_border_width']['T'] = 0;
17139 $table['max_cell_border_width']['B'] = 0;
17140 $table['padding']['L'] = false;
17141 $table['padding']['R'] = false;
17142 $table['padding']['T'] = false;
17143 $table['padding']['B'] = false;
17144 $table['margin']['L'] = false;
17145 $table['margin']['R'] = false;
17146 $table['margin']['T'] = false;
17147 $table['margin']['B'] = false;
17148 $table['a'] = false;
17149 $table['border_spacing_H'] = false;
17150 $table['border_spacing_V'] = false;
17151 $table['decimal_align'] = false; // mPDF 5.6.13
17153 $this->InlineProperties
= array();
17154 $this->spanlvl
= 0;
17155 $table['nc'] = $table['nr'] = 0;
17156 $this->tablethead
= 0;
17157 $this->tabletfoot
= 0;
17158 $this->tabletheadjustfinished
= false;
17161 if ($this->blockjustfinished
&& !count($this->textbuffer
) && $this->y
!= $this->tMargin
&& $this->collapseBlockMargins
&& $this->tableLevel
==1) { $lastbottommargin
= $this
->lastblockbottommargin
; }
17162 else { $lastbottommargin
= 0; }
17163 $this->lastblockbottommargin
= 0;
17164 $this->blockjustfinished
=false;
17166 if ($this->tableLevel
==1) {
17167 $this->tableCJK
= false;
17168 $this->table_lineheight
= $this->normalLineheight
;
17169 $table['headernrows'] = 0;
17170 $table['footernrows'] = 0;
17171 $this->base_table_properties
= array();
17174 // ADDED CSS FUNCIONS FOR TABLE
17175 if ($this->cssmgr
->tbCSSlvl
==1) {
17176 $properties = $this->cssmgr
->MergeCSS('TOPTABLE',$tag,$attr);
17179 $properties = $this->cssmgr
->MergeCSS('TABLE',$tag,$attr);
17182 if (isset($properties['WIDTH'])) { $w
= $properties
['WIDTH']; }
17183 else if (isset($attr['WIDTH']) && $attr['WIDTH']) { $w
= $attr
['WIDTH']; }
17186 if(isset($properties['DIRECTION']) && $properties['DIRECTION']) { $table
['direction'] = strtolower($properties
['DIRECTION']); }
17187 else if(isset($attr['DIR']) && $attr['DIR']) { $table
['direction'] = strtolower($attr
['DIR']); }
17188 else if (!isset($table['direction'])){ $table
['direction'] = $this
->blk
[$this
->blklvl
]['direction']; }
17190 if (isset($properties['BACKGROUND-COLOR'])) { $table
['bgcolor'][-1] = $properties
['BACKGROUND-COLOR']; }
17191 else if (isset($properties['BACKGROUND'])) { $table
['bgcolor'][-1] = $properties
['BACKGROUND']; }
17192 else if (isset($attr['BGCOLOR'])) { $table
['bgcolor'][-1] = $attr
['BGCOLOR']; }
17193 if (isset($properties['VERTICAL-ALIGN'])) { $table
['va'] = $align
[strtolower($properties
['VERTICAL-ALIGN'])]; }
17194 if (isset($properties['TEXT-ALIGN'])) { $table
['txta'] = $align
[strtolower($properties
['TEXT-ALIGN'])]; }
17195 if (isset($attr['ALIGN'])) { $table
['a'] = $align
[strtolower($attr
['ALIGN'])]; }
17196 if (!$table['a']) {
17197 if ($table['direction'] == 'rtl' ) { $table
['a'] = 'R'; }
17198 else { $table
['a'] = 'L'; }
17201 if (isset($properties['AUTOSIZE']) && $properties['AUTOSIZE'] && $this->tableLevel
==1) {
17202 $this->shrink_this_table_to_fit
= $properties['AUTOSIZE'];
17203 if ($this->shrink_this_table_to_fit
< 1) { $this
->shrink_this_table_to_fit
= 0; }
17205 if (isset($properties['ROTATE']) && $properties['ROTATE'] && $this->tableLevel
==1) {
17206 $this->table_rotate
= $properties['ROTATE'];
17208 if (isset($properties['TOPNTAIL'])) { $table
['topntail'] = $properties
['TOPNTAIL']; }
17209 if (isset($properties['THEAD-UNDERLINE'])) { $table
['thead-underline'] = $properties
['THEAD-UNDERLINE']; }
17211 if (isset($properties['BORDER'])) {
17212 $bord = $this->border_details($properties['BORDER']);
17214 $table['border'] = _BORDER_ALL
;
17215 $table['border_details']['R'] = $bord;
17216 $table['border_details']['L'] = $bord;
17217 $table['border_details']['T'] = $bord;
17218 $table['border_details']['B'] = $bord;
17221 if (isset($properties['BORDER-RIGHT'])) {
17222 if ($table['direction'] == 'rtl') { // *RTL*
17223 $table['border_details']['R'] = $this->border_details($properties['BORDER-LEFT']); // *RTL*
17226 $table['border_details']['R'] = $this->border_details($properties['BORDER-RIGHT']);
17228 $this->setBorder($table['border'], _BORDER_RIGHT
, $table['border_details']['R']['s']);
17230 if (isset($properties['BORDER-LEFT'])) {
17231 if ($table['direction'] == 'rtl') { // *RTL*
17232 $table['border_details']['L'] = $this->border_details($properties['BORDER-RIGHT']); // *RTL*
17235 $table['border_details']['L'] = $this->border_details($properties['BORDER-LEFT']);
17237 $this->setBorder($table['border'], _BORDER_LEFT
, $table['border_details']['L']['s']);
17239 if (isset($properties['BORDER-BOTTOM'])) {
17240 $table['border_details']['B'] = $this->border_details($properties['BORDER-BOTTOM']);
17241 $this->setBorder($table['border'], _BORDER_BOTTOM
, $table['border_details']['B']['s']);
17243 if (isset($properties['BORDER-TOP'])) {
17244 $table['border_details']['T'] = $this->border_details($properties['BORDER-TOP']);
17245 $this->setBorder($table['border'], _BORDER_TOP
, $table['border_details']['T']['s']);
17247 if ($table['border']){
17248 $this->table_border_css_set
= 1;
17251 $this->table_border_css_set
= 0;
17254 if (isset($properties['FONT-FAMILY'])) {
17255 $this->default_font
= $properties['FONT-FAMILY'];
17256 $this->SetFont($this->default_font
,'',0,false);
17258 $this->base_table_properties
['FONT-FAMILY'] = $this->FontFamily
; // mPDF 5.4.10
17260 if (isset($properties['FONT-SIZE'])) {
17262 if ($this->tableLevel
>1) { $mmsize
= $this
->ConvertSize($properties
['FONT-SIZE'], $this
->base_table_properties
['FONT-SIZE']); }
17263 else { $mmsize
= $this
->ConvertSize($properties
['FONT-SIZE'],$this
->default_font_size
/_MPDFK
); }
17265 $this->default_font_size
= $mmsize*(_MPDFK
);
17266 $this->SetFontSize($this->default_font_size
,false);
17269 $this->base_table_properties
['FONT-SIZE'] = $this->FontSize
.'mm'; // mPDF 5.4.10
17271 if (isset($properties['FONT-WEIGHT'])) {
17272 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this
->base_table_properties
['FONT-WEIGHT'] = 'BOLD'; }
17274 if (isset($properties['FONT-STYLE'])) {
17275 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this
->base_table_properties
['FONT-STYLE'] = 'ITALIC'; }
17277 if (isset($properties['COLOR'])) {
17278 $this->base_table_properties
['COLOR'] = $properties['COLOR'];
17280 if (isset($properties['FONT-KERNING'])) {
17281 $this->base_table_properties
['FONT-KERNING'] = $properties['FONT-KERNING'];
17283 if (isset($properties['LETTER-SPACING'])) {
17284 $this->base_table_properties
['LETTER-SPACING'] = $properties['LETTER-SPACING'];
17286 if (isset($properties['WORD-SPACING'])) {
17287 $this->base_table_properties
['WORD-SPACING'] = $properties['WORD-SPACING'];
17290 if (isset($properties['PADDING-LEFT'])) {
17291 $table['padding']['L'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17293 if (isset($properties['PADDING-RIGHT'])) {
17294 $table['padding']['R'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17296 if (isset($properties['PADDING-TOP'])) {
17297 $table['padding']['T'] = $this->ConvertSize($properties['PADDING-TOP'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17299 if (isset($properties['PADDING-BOTTOM'])) {
17300 $table['padding']['B'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17303 if (isset($properties['MARGIN-TOP'])) {
17304 if ($lastbottommargin) {
17305 $tmp = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17306 if ($tmp > $lastbottommargin) { $properties
['MARGIN-TOP'] -= $lastbottommargin
; }
17307 else { $properties
['MARGIN-TOP'] = 0; }
17309 $table['margin']['T'] = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17312 if (isset($properties['MARGIN-BOTTOM'])) {
17313 $table['margin']['B'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17315 if (isset($properties['MARGIN-LEFT'])) {
17316 $table['margin']['L'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17319 if (isset($properties['MARGIN-RIGHT'])) {
17320 $table['margin']['R'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17322 if (isset($properties['MARGIN-LEFT']) && isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-LEFT'])=='auto' && strtolower($properties['MARGIN-RIGHT'])=='auto') {
17325 else if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
17328 else if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
17332 if (isset($properties['LINE-HEIGHT']) && $this->tableLevel
==1) {
17333 $this->table_lineheight
= $this->fixLineheight($properties['LINE-HEIGHT']);
17334 if (!$this->table_lineheight
) { $this
->table_lineheight
= $this
->normalLineheight
; }
17337 if (isset($properties['BORDER-COLLAPSE']) && strtoupper($properties['BORDER-COLLAPSE'])=='SEPARATE') {
17338 $table['borders_separate'] = true;
17341 $table['borders_separate'] = false;
17344 if (!$table['borders_separate']) { $table
['border_spacing_H'] = $table
['border_spacing_V'] = 0; }
17345 else if (isset($attr['CELLSPACING'])) {
17346 $table['border_spacing_H'] = $table['border_spacing_V'] = $this->ConvertSize($attr['CELLSPACING'],$this->blk
[$this->blklvl
]['inner_width']);
17348 if (isset($properties['BORDER-SPACING-H'])) {
17349 $table['border_spacing_H'] = $this->ConvertSize($properties['BORDER-SPACING-H'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17351 if (isset($properties['BORDER-SPACING-V'])) {
17352 $table['border_spacing_V'] = $this->ConvertSize($properties['BORDER-SPACING-V'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17355 if (isset($properties['EMPTY-CELLS'])) {
17356 $table['empty_cells'] = strtolower($properties['EMPTY-CELLS']); // 'hide' or 'show'
17358 else { $table
['empty_cells'] = ''; }
17360 if (isset($properties['PAGE-BREAK-INSIDE']) && strtoupper($properties['PAGE-BREAK-INSIDE'])=='AVOID' && $this->tableLevel
==1 && !$this->writingHTMLfooter
) {
17361 $this->table_keep_together
= true;
17363 else if ($this->tableLevel
==1) {
17364 $this->table_keep_together
= false;
17366 if (isset($properties['PAGE-BREAK-AFTER']) && $this->tableLevel
==1) {
17367 $table['page_break_after'] = strtoupper($properties['PAGE-BREAK-AFTER']);
17370 /*-- BACKGROUNDS --*/
17371 if (isset($properties['BACKGROUND-GRADIENT']) && !$this->kwt
&& !$this->ColActive
) { $table
['gradient'] = $properties
['BACKGROUND-GRADIENT']; }
17373 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt
&& !$this->ColActive
) {
17374 $ret = $this->SetBackground($properties, $currblk['inner_width']);
17375 if ($ret) { $table
['background-image'] = $ret
; }
17377 /*-- END BACKGROUNDS --*/
17379 if (isset($properties['OVERFLOW'])) {
17380 $table['overflow'] = strtolower($properties['OVERFLOW']); // 'hidden' 'wrap' or 'visible' or 'auto'
17381 if (($this->ColActive
|| $this->tableLevel
>1) && $table['overflow']=='visible') { unset($table
['overflow']); }
17384 $properties = array();
17388 if (isset($attr['CELLPADDING'])) {
17389 $table['cell_padding'] = $attr['CELLPADDING'];
17392 $table['cell_padding'] = false;
17395 if (isset($attr['BORDER']) && $attr['BORDER']=='1') { // mPDF 5.5.08
17396 $this->table_border_attr_set
= 1; // mPDF 5.5.08
17397 $bord = $this->border_details('#000000 1px solid');
17399 $table['border'] = _BORDER_ALL
;
17400 $table['border_details']['R'] = $bord;
17401 $table['border_details']['L'] = $bord;
17402 $table['border_details']['T'] = $bord;
17403 $table['border_details']['B'] = $bord;
17407 $this->table_border_attr_set
= 0;
17411 $maxwidth = $this->blk
[$this->blklvl
]['inner_width'];
17412 if ($table['borders_separate']) {
17413 $tblblw = $table['margin']['L'] +
$table['margin']['R'] +
$table['border_details']['L']['w']/2 +
$table['border_details']['R']['w']/2;
17416 $tblblw = $table['margin']['L'] +
$table['margin']['R'] +
$table['max_cell_border_width']['L']/2 +
$table['max_cell_border_width']['R']/2;
17418 if (strpos($w,'%') && $this->tableLevel
== 1 && !$this->ignore_table_percents
) {
17419 // % needs to be of inner box without table margins etc.
17420 $maxwidth -= $tblblw ;
17421 $wmm = $this->ConvertSize($w,$maxwidth,$this->FontSize
,false);
17422 $table['w'] = $wmm +
$tblblw ;
17424 if (strpos($w,'%') && $this->tableLevel
> 1 && !$this->ignore_table_percents
&& $this->keep_table_proportions
) {
17425 $table['wpercent'] = $w +
0; // makes 80% -> 80
17427 if (!strpos($w,'%') && !$this->ignore_table_widths
) {
17428 $wmm = $this->ConvertSize($w,$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17429 $table['w'] = $wmm +
$tblblw ;
17431 if (!$this->keep_table_proportions
) {
17432 if (isset($table['w']) && $table['w'] > $this->blk
[$this->blklvl
]['inner_width']) { $table
['w'] = $this
->blk
[$this
->blklvl
]['inner_width']; }
17436 if (isset($attr['AUTOSIZE']) && $this->tableLevel
==1) {
17437 $this->shrink_this_table_to_fit
= $attr['AUTOSIZE'];
17438 if ($this->shrink_this_table_to_fit
< 1) { $this
->shrink_this_table_to_fit
= 1; }
17440 if (isset($attr['ROTATE']) && $this->tableLevel
==1) {
17441 $this->table_rotate
= $attr['ROTATE'];
17444 //++++++++++++++++++++++++++++
17445 // keeping block together on one page
17446 // Autosize is now forced therefore keep block together disabled
17447 if ($this->keep_block_together
) {
17448 $this->keep_block_together
= 0;
17449 $this->printdivbuffer();
17450 $this->blk
[$this->blklvl
]['keep_block_together'] = 0;
17452 if ($this->table_rotate
) {
17453 $this->tbrot_Links
= array();
17454 $this->tbrot_Annots
= array();
17455 $this->tbrotForms
= array();
17456 $this->tbrot_Reference
= array();
17457 $this->tbrot_BMoutlines
= array();
17458 $this->tbrot_toc
= array();
17462 if ($this->table_rotate
) { $this
->table_keep_together
= true; }
17463 $this->kwt
= false;
17464 $this->kwt_saved
= true;
17467 if ($this->tableLevel
==1 && $this->useGraphs
) {
17468 if (isset($attr['ID']) && $attr['ID']) { $this
->currentGraphId
= strtoupper($attr
['ID']); }
17469 else { $this
->currentGraphId
= '0'; }
17470 $this->graphs
[$this->currentGraphId
] = array();
17472 //++++++++++++++++++++++++++++
17473 $this->plainCell_properties
= array();
17478 $this->lastoptionaltag
= $tag; // Save current HTML specified optional endtag
17479 $this->cssmgr
->tbCSSlvl++
;
17480 $this->tablethead
= 1;
17481 $this->tabletfoot
= 0;
17482 $properties = $this->cssmgr
->MergeCSS('TABLE',$tag,$attr);
17483 if (isset($properties['FONT-WEIGHT'])) {
17484 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this
->thead_font_weight
= 'B'; }
17485 else { $this
->thead_font_weight
= ''; }
17488 if (isset($properties['FONT-STYLE'])) {
17489 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this
->thead_font_style
= 'I'; }
17490 else { $this
->thead_font_style
= ''; }
17492 if (isset($properties['FONT-VARIANT'])) {
17493 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this
->thead_font_smCaps
= 'S'; }
17494 else { $this
->thead_font_smCaps
= ''; }
17497 if (isset($properties['VERTICAL-ALIGN'])) {
17498 $this->thead_valign_default
= $properties['VERTICAL-ALIGN'];
17500 if (isset($properties['TEXT-ALIGN'])) {
17501 $this->thead_textalign_default
= $properties['TEXT-ALIGN'];
17503 $properties = array();
17507 $this->lastoptionaltag
= $tag; // Save current HTML specified optional endtag
17508 $this->cssmgr
->tbCSSlvl++
;
17509 $this->tabletfoot
= 1;
17510 $this->tablethead
= 0;
17511 $properties = $this->cssmgr
->MergeCSS('TABLE',$tag,$attr);
17512 if (isset($properties['FONT-WEIGHT'])) {
17513 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this
->tfoot_font_weight
= 'B'; }
17514 else { $this
->tfoot_font_weight
= ''; }
17517 if (isset($properties['FONT-STYLE'])) {
17518 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this
->tfoot_font_style
= 'I'; }
17519 else { $this
->tfoot_font_style
= ''; }
17521 if (isset($properties['FONT-VARIANT'])) {
17522 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this
->tfoot_font_smCaps
= 'S'; }
17523 else { $this
->tfoot_font_smCaps
= ''; }
17526 if (isset($properties['VERTICAL-ALIGN'])) {
17527 $this->tfoot_valign_default
= $properties['VERTICAL-ALIGN'];
17529 if (isset($properties['TEXT-ALIGN'])) {
17530 $this->tfoot_textalign_default
= $properties['TEXT-ALIGN'];
17532 $properties = array();
17537 $this->tablethead
= 0;
17538 $this->tabletfoot
= 0;
17539 $this->lastoptionaltag
= $tag; // Save current HTML specified optional endtag
17540 $this->cssmgr
->tbCSSlvl++
;
17541 $this->cssmgr
->MergeCSS('TABLE',$tag,$attr);
17546 $this->lastoptionaltag
= $tag; // Save current HTML specified optional endtag
17547 $this->cssmgr
->tbCSSlvl++
;
17549 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['nr']++
;
17551 $properties = $this->cssmgr
->MergeCSS('TABLE',$tag,$attr);
17553 if (!$this->simpleTables
&& (!isset($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['borders_separate']) || !$this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['borders_separate'])) {
17554 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) { $this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['trborder-left'][$this
->row
] = $properties
['BORDER-LEFT']; }
17555 if (isset($properties['BORDER-RIGHT']) && $properties['BORDER-RIGHT']) { $this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['trborder-right'][$this
->row
] = $properties
['BORDER-RIGHT']; }
17556 if (isset($properties['BORDER-TOP']) && $properties['BORDER-TOP']) { $this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['trborder-top'][$this
->row
] = $properties
['BORDER-TOP']; }
17557 if (isset($properties['BORDER-BOTTOM']) && $properties['BORDER-BOTTOM']) { $this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['trborder-bottom'][$this
->row
] = $properties
['BORDER-BOTTOM']; }
17560 if (isset($properties['BACKGROUND-COLOR'])) { $this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['bgcolor'][$this
->row
] = $properties
['BACKGROUND-COLOR']; }
17561 else if (isset($attr['BGCOLOR'])) $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['bgcolor'][$this->row
] = $attr['BGCOLOR'];
17563 /*-- BACKGROUNDS --*/
17564 if (isset($properties['BACKGROUND-GRADIENT']) && !$this->kwt
&& !$this->ColActive
) { $this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['trgradients'][$this
->row
] = $properties
['BACKGROUND-GRADIENT']; }
17566 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt
&& !$this->ColActive
) {
17567 $ret = $this->SetBackground($properties, $currblk['inner_width']);
17568 if ($ret) { $this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['trbackground-images'][$this
->row
] = $ret
; }
17570 /*-- END BACKGROUNDS --*/
17573 if (isset($properties['TEXT-ROTATE'])) {
17574 $this->trow_text_rotate
= $properties['TEXT-ROTATE'];
17576 if (isset($attr['TEXT-ROTATE'])) $this->trow_text_rotate
= $attr['TEXT-ROTATE'];
17578 if ($this->tablethead
) { $this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['is_thead'][$this
->row
] = true; }
17579 if ($this->tabletfoot
) { $this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['is_tfoot'][$this
->row
] = true; }
17580 $properties = array();
17586 $this->ignorefollowingspaces
= true;
17587 $this->lastoptionaltag
= $tag; // Save current HTML specified optional endtag
17588 $this->cssmgr
->tbCSSlvl++
;
17589 $this->InlineProperties
= array();
17590 $this->spanlvl
= 0;
17591 $this->tdbegin
= true;
17593 while (isset($this->cell
[$this->row
][$this->col
])) { $this
->col++
; }
17595 //Update number column
17596 if ($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['nc'] < $this->col+
1) { $this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['nc'] = $this
->col+
1; }
17598 $table = &$this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]];
17600 $c = array('a' => false,
17603 'bgcolor' => false,
17604 'padding' => array('L' => false,
17611 if ($this->simpleTables
&& $this->row
==0 && $this->col
==0){
17612 $table['simple']['border'] = false;
17613 $table['simple']['border_details']['R']['w'] = 0;
17614 $table['simple']['border_details']['L']['w'] = 0;
17615 $table['simple']['border_details']['T']['w'] = 0;
17616 $table['simple']['border_details']['B']['w'] = 0;
17617 $table['simple']['border_details']['R']['style'] = '';
17618 $table['simple']['border_details']['L']['style'] = '';
17619 $table['simple']['border_details']['T']['style'] = '';
17620 $table['simple']['border_details']['B']['style'] = '';
17622 else if (!$this->simpleTables
) {
17623 $c['border'] = false;
17624 $c['border_details']['R']['w'] = 0;
17625 $c['border_details']['L']['w'] = 0;
17626 $c['border_details']['T']['w'] = 0;
17627 $c['border_details']['B']['w'] = 0;
17628 $c['border_details']['mbw']['BL'] = 0;
17629 $c['border_details']['mbw']['BR'] = 0;
17630 $c['border_details']['mbw']['RT'] = 0;
17631 $c['border_details']['mbw']['RB'] = 0;
17632 $c['border_details']['mbw']['TL'] = 0;
17633 $c['border_details']['mbw']['TR'] = 0;
17634 $c['border_details']['mbw']['LT'] = 0;
17635 $c['border_details']['mbw']['LB'] = 0;
17636 $c['border_details']['R']['style'] = '';
17637 $c['border_details']['L']['style'] = '';
17638 $c['border_details']['T']['style'] = '';
17639 $c['border_details']['B']['style'] = '';
17640 $c['border_details']['R']['s'] = 0;
17641 $c['border_details']['L']['s'] = 0;
17642 $c['border_details']['T']['s'] = 0;
17643 $c['border_details']['B']['s'] = 0;
17644 $c['border_details']['R']['c'] = $this->ConvertColor(0);
17645 $c['border_details']['L']['c'] = $this->ConvertColor(0);
17646 $c['border_details']['T']['c'] = $this->ConvertColor(0);
17647 $c['border_details']['B']['c'] = $this->ConvertColor(0);
17648 $c['border_details']['R']['dom'] = 0;
17649 $c['border_details']['L']['dom'] = 0;
17650 $c['border_details']['T']['dom'] = 0;
17651 $c['border_details']['B']['dom'] = 0;
17655 if ($table['va']) { $c
['va'] = $table
['va']; }
17656 if ($table['txta']) { $c
['a'] = $table
['txta']; }
17657 if ($this->table_border_attr_set
) {
17658 if ($table['border_details']) {
17659 if (!$this->simpleTables
){
17660 $c['border_details']['R'] = $table['border_details']['R'];
17661 $c['border_details']['L'] = $table['border_details']['L'];
17662 $c['border_details']['T'] = $table['border_details']['T'];
17663 $c['border_details']['B'] = $table['border_details']['B'];
17664 $c['border'] = $table['border'];
17665 $c['border_details']['L']['dom'] = 1;
17666 $c['border_details']['R']['dom'] = 1;
17667 $c['border_details']['T']['dom'] = 1;
17668 $c['border_details']['B']['dom'] = 1;
17670 else if ($this->simpleTables
&& $this->row
==0 && $this->col
==0){
17671 $table['simple']['border_details']['R'] = $table['border_details']['R'];
17672 $table['simple']['border_details']['L'] = $table['border_details']['L'];
17673 $table['simple']['border_details']['T'] = $table['border_details']['T'];
17674 $table['simple']['border_details']['B'] = $table['border_details']['B'];
17675 $table['simple']['border'] = $table['border'];
17679 // INHERITED THEAD CSS Properties
17680 if ($this->tablethead
) {
17681 if ($this->thead_valign_default
) $c['va'] = $align[strtolower($this->thead_valign_default
)];
17682 if ($this->thead_textalign_default
) $c['a'] = $align[strtolower($this->thead_textalign_default
)];
17683 if ($this->thead_font_weight
== 'B') { $this
->SetStyle('B',true); }
17684 if ($this->thead_font_style
== 'I') { $this
->SetStyle('I',true); }
17685 if ($this->thead_font_smCaps
== 'S') { $this
->SetStyle('S',true); }
17688 // INHERITED TFOOT CSS Properties
17689 if ($this->tabletfoot
) {
17690 if ($this->tfoot_valign_default
) $c['va'] = $align[strtolower($this->tfoot_valign_default
)];
17691 if ($this->tfoot_textalign_default
) $c['a'] = $align[strtolower($this->tfoot_textalign_default
)];
17692 if ($this->tfoot_font_weight
== 'B') { $this
->SetStyle('B',true); }
17693 if ($this->tfoot_font_style
== 'I') { $this
->SetStyle('I',true); }
17694 if ($this->tfoot_font_style
== 'S') { $this
->SetStyle('S',true); }
17698 if ($this->trow_text_rotate
){
17699 $c['R'] = $this->trow_text_rotate
;
17702 $this->cell_border_dominance_L
= 0;
17703 $this->cell_border_dominance_R
= 0;
17704 $this->cell_border_dominance_T
= 0;
17705 $this->cell_border_dominance_B
= 0;
17707 $properties = $this->cssmgr
->MergeCSS('TABLE',$tag,$attr);
17708 $properties = $this->cssmgr
->array_merge_recursive_unique($this->base_table_properties
, $properties);
17710 if (isset($properties['FONT-KERNING']) && (strtoupper($properties['FONT-KERNING'])=='NORMAL' || strtoupper($properties['FONT-KERNING'])=='AUTO')) {
17711 $this->kerning
= true;
17713 else { $this
->kerning
= false; }
17715 if (isset($properties['LETTER-SPACING']) && ($properties['LETTER-SPACING'] || $properties['LETTER-SPACING']==='0') && strtoupper($properties['LETTER-SPACING']) != 'NORMAL') {
17716 $this->lSpacingCSS
= strtoupper($properties['LETTER-SPACING']);
17717 $this->fixedlSpacing
= $this->ConvertSize($this->lSpacingCSS
,$this->FontSize
);
17720 $this->lSpacingCSS
= '';
17721 $this->fixedlSpacing
= false;
17723 if (isset($properties['WORD-SPACING']) && strtoupper($properties['WORD-SPACING']) != 'NORMAL') {
17724 $this->wSpacingCSS
= strtoupper($properties['WORD-SPACING']);
17725 $this->minwSpacing
= $this->ConvertSize($this->wSpacingCSS
,$this->FontSize
);
17728 $this->minwSpacing
= 0;
17729 $this->wSpacingCSS
= '';
17732 if (isset($properties['HYPHENS']) && $properties['HYPHENS']) {
17733 if (strtoupper($properties['HYPHENS']) == 'NONE') { $this
->textparam
['hyphens'] = 2; }
17734 else if (strtoupper($properties['HYPHENS']) == 'AUTO') { $this
->textparam
['hyphens'] = 1; }
17735 else if (strtoupper($properties['HYPHENS']) == 'MANUAL') { $this
->textparam
['hyphens'] = 0; }
17738 if (isset($properties['BACKGROUND-COLOR'])) { $c
['bgcolor'] = $properties
['BACKGROUND-COLOR']; }
17739 else if (isset($properties['BACKGROUND'])) { $c
['bgcolor'] = $properties
['BACKGROUND']; }
17740 else if (isset($attr['BGCOLOR'])) $c['bgcolor'] = $attr['BGCOLOR'];
17744 /*-- BACKGROUNDS --*/
17745 if (isset($properties['BACKGROUND-GRADIENT'])) { $c
['gradient'] = $properties
['BACKGROUND-GRADIENT']; }
17746 else { $c
['gradient'] = false; }
17748 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->keep_block_together
) {
17749 $ret = $this->SetBackground($properties, $this->blk
[$this->blklvl
]['inner_width']);
17750 if ($ret) { $c
['background-image'] = $ret
; }
17752 /*-- END BACKGROUNDS --*/
17753 if (isset($properties['VERTICAL-ALIGN'])) { $c
['va']=$align
[strtolower($properties
['VERTICAL-ALIGN'])]; }
17754 else if (isset($attr['VALIGN'])) $c['va'] = $align[strtolower($attr['VALIGN'])];
17758 if (isset($properties['TEXT-ALIGN']) && $properties['TEXT-ALIGN']) {
17759 if (substr($properties['TEXT-ALIGN'],0,1)=='D') { $c
['a'] = $properties
['TEXT-ALIGN']; }
17760 else { $c
['a'] = $align
[strtolower($properties
['TEXT-ALIGN'])]; }
17763 if (isset($attr['ALIGN']) && $attr['ALIGN']) {
17764 if (strtolower($attr['ALIGN']) == 'char') {
17765 if (isset($attr['CHAR']) && $attr['CHAR']) {
17766 $char = html_entity_decode($attr['CHAR']);
17767 $char = strcode2utf($char);
17768 $d = array_search($char,$this->decimal_align
);
17769 if ($d !== false) { $c
['a'] = $d
.'R'; }
17771 else { $c
['a'] = 'DPR'; }
17773 else { $c
['a'] = $align
[strtolower($attr
['ALIGN'])]; }
17777 if (isset($table['direction']) && $table['direction'] == 'rtl' ) { $c
['a'] = 'R'; }
17778 else { $c
['a'] = 'L'; }
17782 if (isset($properties['TEXT-ROTATE']) && ($properties['TEXT-ROTATE'] || $properties['TEXT-ROTATE']==="0")){
17783 $c['R'] = $properties['TEXT-ROTATE'];
17785 if (isset($properties['BORDER'])) {
17786 $bord = $this->border_details($properties['BORDER']);
17788 if (!$this->simpleTables
){
17789 $c['border'] = _BORDER_ALL
;
17790 $c['border_details']['R'] = $bord;
17791 $c['border_details']['L'] = $bord;
17792 $c['border_details']['T'] = $bord;
17793 $c['border_details']['B'] = $bord;
17794 $c['border_details']['L']['dom'] = $this->cell_border_dominance_L
;
17795 $c['border_details']['R']['dom'] = $this->cell_border_dominance_R
;
17796 $c['border_details']['T']['dom'] = $this->cell_border_dominance_T
;
17797 $c['border_details']['B']['dom'] = $this->cell_border_dominance_B
;
17799 else if ($this->simpleTables
&& $this->row
==0 && $this->col
==0){
17800 $table['simple']['border'] = _BORDER_ALL
;
17801 $table['simple']['border_details']['R'] = $bord;
17802 $table['simple']['border_details']['L'] = $bord;
17803 $table['simple']['border_details']['T'] = $bord;
17804 $table['simple']['border_details']['B'] = $bord;
17808 if (!$this->simpleTables
){
17809 if (isset($properties['BORDER-RIGHT']) && $properties['BORDER-RIGHT']) {
17810 $c['border_details']['R'] = $this->border_details($properties['BORDER-RIGHT']);
17811 $this->setBorder($c['border'], _BORDER_RIGHT
, $c['border_details']['R']['s']);
17812 $c['border_details']['R']['dom'] = $this->cell_border_dominance_R
;
17814 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) {
17815 $c['border_details']['L'] = $this->border_details($properties['BORDER-LEFT']);
17816 $this->setBorder($c['border'], _BORDER_LEFT
, $c['border_details']['L']['s']);
17817 $c['border_details']['L']['dom'] = $this->cell_border_dominance_L
;
17819 if (isset($properties['BORDER-BOTTOM']) && $properties['BORDER-BOTTOM']) {
17820 $c['border_details']['B'] = $this->border_details($properties['BORDER-BOTTOM']);
17821 $this->setBorder($c['border'], _BORDER_BOTTOM
, $c['border_details']['B']['s']);
17822 $c['border_details']['B']['dom'] = $this->cell_border_dominance_B
;
17824 if (isset($properties['BORDER-TOP']) && $properties['BORDER-TOP']) {
17825 $c['border_details']['T'] = $this->border_details($properties['BORDER-TOP']);
17826 $this->setBorder($c['border'], _BORDER_TOP
, $c['border_details']['T']['s']);
17827 $c['border_details']['T']['dom'] = $this->cell_border_dominance_T
;
17830 else if ($this->simpleTables
&& $this->row
==0 && $this->col
==0){
17831 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) {
17832 $bord = $this->border_details($properties['BORDER-LEFT']);
17833 if ($bord['s']) { $table
['simple']['border'] = _BORDER_ALL
; }
17834 else { $table
['simple']['border'] = 0; }
17835 $table['simple']['border_details']['R'] = $bord;
17836 $table['simple']['border_details']['L'] = $bord;
17837 $table['simple']['border_details']['T'] = $bord;
17838 $table['simple']['border_details']['B'] = $bord;
17842 if ($this->simpleTables
&& $this->row
==0 && $this->col
==0 && !$table['borders_separate'] && $table['simple']['border'] ){
17843 $table['border_details'] = $table['simple']['border_details'];
17844 $table['border'] = $table['simple']['border'];
17847 // Border set on TR (if collapsed only)
17848 if (!$table['borders_separate'] && !$this->simpleTables
&& isset($table['trborder-left'][$this->row
])) {
17849 if ($this->col
==0) {
17850 $left = $this->border_details($table['trborder-left'][$this->row
]);
17851 $c['border_details']['L'] = $left;
17852 $this->setBorder($c['border'], _BORDER_LEFT
, $c['border_details']['L']['s']);
17854 $c['border_details']['B'] = $this->border_details($table['trborder-bottom'][$this->row
]);
17855 $this->setBorder($c['border'], _BORDER_BOTTOM
, $c['border_details']['B']['s']);
17856 $c['border_details']['T'] = $this->border_details($table['trborder-top'][$this->row
]);
17857 $this->setBorder($c['border'], _BORDER_TOP
, $c['border_details']['T']['s']);
17860 if ($this->packTableData
&& !$this->simpleTables
) {
17861 $c['borderbin'] = $this->_packCellBorder($c);
17862 unset($c['border']);
17863 unset($c['border_details']);
17866 if (isset($properties['PADDING-LEFT'])) {
17867 $c['padding']['L'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17869 if (isset($properties['PADDING-RIGHT'])) {
17870 $c['padding']['R'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17872 if (isset($properties['PADDING-BOTTOM'])) {
17873 $c['padding']['B'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17875 if (isset($properties['PADDING-TOP'])) {
17876 $c['padding']['T'] = $this->ConvertSize($properties['PADDING-TOP'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17880 if (isset($properties['WIDTH'])) { $w
= $properties
['WIDTH']; }
17881 else if (isset($attr['WIDTH'])) { $w
= $attr
['WIDTH']; }
17883 if (strpos($w,'%') && !$this->ignore_table_percents
) { $c
['wpercent'] = $w +
0; } // makes 80% -> 80
17884 else if (!strpos($w,'%') && !$this->ignore_table_widths
) { $c
['w'] = $this
->ConvertSize($w
,$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
17887 if (isset($properties['HEIGHT']) && !strpos($properties['HEIGHT'],'%')) { $c
['h'] = $this
->ConvertSize($properties
['HEIGHT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
17888 else if (isset($attr['HEIGHT']) && !strpos($attr['HEIGHT'],'%')) $c['h'] = $this->ConvertSize($attr['HEIGHT'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
17891 if (isset($properties['COLOR'])) {
17892 $cor = $this->ConvertColor($properties['COLOR']);
17894 $this->colorarray
= $cor;
17895 $this->SetTColor($cor);
17898 if (isset($properties['FONT-FAMILY'])) {
17899 $this->SetFont($properties['FONT-FAMILY'],'',0,false);
17901 if (isset($properties['FONT-SIZE'])) {
17902 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size
/_MPDFK
);
17904 $this->SetFontSize($mmsize*(_MPDFK
),false);
17907 $c['dfs'] = $this->FontSize
; // Default Font size
17908 if (isset($properties['FONT-WEIGHT'])) {
17909 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this
->SetStyle('B',true); }
17911 if (isset($properties['FONT-STYLE'])) {
17912 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this
->SetStyle('I',true); }
17914 if (isset($properties['FONT-VARIANT'])) {
17915 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this
->SetStyle('S',true); }
17917 if (isset($properties['TEXT-DECORATION'])) {
17918 if (strtoupper($properties['TEXT-DECORATION']) == 'LINE-THROUGH') { $this
->strike
= true; }
17919 else if (strtoupper($properties['TEXT-DECORATION']) == 'UNDERLINE') { $this
->SetStyle('U',true); }
17921 if (isset($properties['TEXT-SHADOW'])) {
17922 $ts = $this->cssmgr
->setCSStextshadow($properties['TEXT-SHADOW']);
17923 if ($ts) { $this
->textshadow
= $ts
; }
17925 if (isset($properties['TEXT-TRANSFORM'])) {
17926 if (strtoupper($properties['TEXT-TRANSFORM']) == 'CAPITALIZE') { $this
->capitalize
= true; }
17927 else if (strtoupper($properties['TEXT-TRANSFORM']) == 'UPPERCASE') { $this
->toupper
= true; }
17928 else if (strtoupper($properties['TEXT-TRANSFORM']) == 'LOWERCASE') { $this
->tolower
= true; }
17930 if (isset($properties['WHITE-SPACE'])) {
17931 if (strtoupper($properties['WHITE-SPACE']) == 'NOWRAP') { $c
['nowrap']= 1; }
17933 $properties = array();
17935 if (isset($attr['TEXT-ROTATE'])) {
17936 $c['R'] = $attr['TEXT-ROTATE'];
17938 if (isset($attr['NOWRAP']) && $attr['NOWRAP']) $c['nowrap']= 1;
17940 $this->cell
[$this->row
][$this->col
] = $c;
17942 $this->cell
[$this->row
][$this->col
]['s'] = 0 ;
17945 if (isset($attr['COLSPAN']) && $attr['COLSPAN']>1) $cs = $this->cell
[$this->row
][$this->col
]['colspan'] = $attr['COLSPAN'];
17946 if ($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['nc'] < $this->col+
$cs) {
17947 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['nc'] = $this->col+
$cs;
17948 } // following code moved outside if...
17949 for($l=$this->col
; $l < $this->col+
$cs ;$l++
) {
17950 if ($l-$this->col
) $this->cell
[$this->row
][$l] = 0;
17952 if (isset($attr['ROWSPAN']) && $attr['ROWSPAN']>1) $rs = $this->cell
[$this->row
][$this->col
]['rowspan'] = $attr['ROWSPAN'];
17953 for ($k=$this->row
; $k < $this->row+
$rs ;$k++
) {
17954 for($l=$this->col
; $l < $this->col+
$cs ;$l++
) {
17955 if ($k-$this->row
|| $l-$this->col
) $this->cell
[$k][$l] = 0;
17960 /*-- END TABLES --*/
17964 // *********** LISTS ********************
17967 $this->listjustfinished
= false;
17969 if ($this->blockjustfinished
&& !count($this->textbuffer
) && $this->y
!= $this->tMargin
&& $this->collapseBlockMargins
) { $lastbottommargin
= $this
->lastblockbottommargin
; }
17970 else { $lastbottommargin
= 0; }
17971 $this->lastblockbottommargin
= 0;
17972 $this->blockjustfinished
=false;
17974 $this->linebreakjustfinished
=false;
17975 $this->lastoptionaltag
= ''; // Save current HTML specified optional endtag
17976 $this->cssmgr
->listCSSlvl++
;
17977 if((!$this->tableLevel
) && ($this->listlvl
== 0)) {
17979 //if ($this->lastblocklevelchange == 1) { $blockstate = -1; } // Top margins/padding only
17980 //else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
17981 // called from block after new div e.g. <div> ... <ol> ... Outputs block top margin/border and padding
17982 if (count($this->textbuffer
) == 0 && $this->lastblocklevelchange
== 1 && !$this->tableLevel
&& !$this->kwt
) {
17983 $this->newFlowingBlock( $this->blk
[$this->blklvl
]['width'],$this->lineheight
,'',false,false,1,true, $this->blk
[$this->blklvl
]['direction']);
17984 $this->finishFlowingBlock(true); // true = END of flowing block
17986 else if (count($this->textbuffer
)) { $this
->printbuffer($this
->textbuffer
,$blockstate
); }
17987 $this->textbuffer
=array();
17988 $this->lastblocklevelchange
= -1;
17990 // ol and ul types are mixed here
17991 if ($this->listlvl
== 0) {
17992 $this->list_indent
= array();
17993 $this->list_align
= array();
17994 $this->list_lineheight
= array();
17995 $this->InlineProperties
['LIST'] = array();
17996 $this->InlineProperties
['LISTITEM'] = array();
18000 // A simple list for inside a table
18001 if($this->tableLevel
) {
18002 $this->list_indent
[$this->listlvl
] = 0; // mm default indent for each level
18003 if ($tag == 'OL') $this->listtype
= '1';
18004 else if ($tag == 'UL') $this->listtype
= 'disc';
18005 if ($this->listlvl
> 0) {
18006 $this->listlist
[$this->listlvl
]['MAXNUM'] = $this->listnum
; //save previous lvl's maxnum
18010 if (isset($attr['START'])) { $this
->listnum
= intval($attr
['START']); }
18011 else { $this
->listnum
= 0; }
18012 $this->listlist
[$this->listlvl
] = array('TYPE'=>$this->listtype
,'MAXNUM'=>$this->listnum
);
18015 /*-- END TABLES --*/
18018 if (($this->PDFA
|| $this->PDFX
) && $tag == 'UL') {
18019 if (($this->PDFA
&& !$this->PDFAauto
) || ($this->PDFX
&& !$this->PDFXauto
)) { $this
->PDFAXwarnings
[] = "List bullets cannot use core font Zapfdingbats in PDFA1-b or PDFX/1-a. (Substitute characters from current font used if available, otherwise substitutes hyphen '-')"; }
18022 if ($this->cssmgr
->listCSSlvl
==1) {
18023 $properties = $this->cssmgr
->MergeCSS('TOPLIST',$tag,$attr);
18026 $properties = $this->cssmgr
->MergeCSS('LIST',$tag,$attr);
18028 if (!empty($properties)) $this->setCSS($properties,'LIST');
18031 $this->listtype
= '';
18032 if (isset($properties['LIST-STYLE-TYPE'])) {
18033 $this->listtype
= $this->_getListStyle($properties['LIST-STYLE-TYPE']);
18035 else if (isset($properties['LIST-STYLE'])) {
18036 $this->listtype
= $this->_getListStyle($properties['LIST-STYLE']);
18038 else if (isset($attr['TYPE']) && $attr['TYPE']) { $this
->listtype
= $attr
['TYPE']; }
18039 if (!$this->listtype
) {
18040 if ($tag == 'OL') $this->listtype
= '1';
18041 if ($tag == 'UL') {
18042 if ($this->listlvl %
3 == 0) $this->listtype
= 'disc';
18043 elseif ($this->listlvl %
3 == 1) $this->listtype
= 'circle';
18044 else $this->listtype
= 'square';
18047 if ($this->listlvl
== 0) {
18048 $this->inherit_lineheight
= 0;
18049 $this->listlvl++
; // first depth level
18051 if (isset($attr['START'])) { $this
->listnum
= intval($attr
['START']); }
18052 else { $this
->listnum
= 0; }
18053 $this->listDir
= (isset($this->blk
[$this->blklvl
]['direction']) ? $this->blk
[$this->blklvl
]['direction'] : null);
18054 $occur = $this->listoccur
[$this->listlvl
] = 1;
18055 $this->listlist
[$this->listlvl
][1] = array('TYPE'=>$this->listtype
,'MAXNUM'=>$this->listnum
);
18058 if (!empty($this->textbuffer
))
18060 $this->listitem
[] = array($this->listlvl
,$this->listnum
,$this->textbuffer
,$this->listoccur
[$this->listlvl
],$this->listitemtype
);
18063 // Save current lineheight to inherit
18064 $this->textbuffer
= array();
18065 $occur = $this->listoccur
[$this->listlvl
];
18066 $this->listlist
[$this->listlvl
][$occur]['MAXNUM'] = $this->listnum
; //save previous lvl's maxnum
18069 if (isset($attr['START'])) { $this
->listnum
= intval($attr
['START']); }
18070 else { $this
->listnum
= 0; }
18073 if (!isset($this->listoccur
[$this->listlvl
]) || $this->listoccur
[$this->listlvl
] == 0) $this->listoccur
[$this->listlvl
] = 1;
18074 else $this->listoccur
[$this->listlvl
]++
;
18075 $occur = $this->listoccur
[$this->listlvl
];
18076 $this->listlist
[$this->listlvl
][$occur] = array('TYPE'=>$this->listtype
,'MAXNUM'=>$this->listnum
);
18081 if ($this->listlvl
== 1) {
18082 if (isset($properties['MARGIN-TOP'])) {
18083 if ($lastbottommargin) {
18084 $tmp = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
18085 if ($tmp > $lastbottommargin) { $properties
['MARGIN-TOP'] -= $lastbottommargin
; }
18086 else { $properties
['MARGIN-TOP'] = 0; }
18088 $this->DivLn($this->ConvertSize($properties['MARGIN-TOP'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false),$this->blklvl
,true,1); // collapsible
18090 if (isset($properties['MARGIN-BOTTOM'])) {
18091 $this->list_margin_bottom
= $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
,false);
18094 if (isset($this->blk
[$this->blklvl
]['line_height'])) {
18095 $this->list_lineheight
[$this->listlvl
][$occur] = $this->blk
[$this->blklvl
]['line_height'];
18098 if (isset($properties['DIRECTION']) && $properties['DIRECTION']) { $this
->listDir
= strtolower($properties
['DIRECTION']); }
18099 else if (isset($attr['DIR']) && $attr['DIR']) { $this
->listDir
= strtolower($attr
['DIR']); }
18102 $this->list_indent
[$this->listlvl
][$occur] = 5; // mm default indent for each level
18103 if (isset($properties['TEXT-INDENT'])) { $this
->list_indent
[$this
->listlvl
][$occur
] = $this
->ConvertSize($properties
['TEXT-INDENT'],$this
->blk
[$this
->blklvl
]['inner_width'],$this
->FontSize
,false); }
18105 if (isset($properties['TEXT-ALIGN'])) {
18106 $this->list_align
[$this->listlvl
][$occur] = $align[strtolower($properties['TEXT-ALIGN'])];
18110 if (isset($properties['LINE-HEIGHT'])) {
18111 $this->list_lineheight
[$this->listlvl
][$occur] = $this->fixLineheight($properties['LINE-HEIGHT']);
18113 else if ($this->listlvl
>1 && isset($this->list_lineheight
[($this->listlvl
- 1)][1])) {
18114 $this->list_lineheight
[$this->listlvl
][$occur] = end($this->list_lineheight
[($this->listlvl
- 1)]);
18116 if (!isset($this->list_lineheight
[$this->listlvl
][$occur]) || !$this->list_lineheight
[$this->listlvl
][$occur]) {
18117 $this->list_lineheight
[$this->listlvl
][$occur] = $this->normalLineheight
;
18120 $this->InlineProperties
['LIST'][$this->listlvl
][$occur] = $this->saveInlineProperties();
18121 $properties = array();
18128 $this->lastoptionaltag
= $tag; // Save current HTML specified optional endtag
18129 $this->ignorefollowingspaces
= true; //Eliminate exceeding left-side spaces
18131 // A simple list for inside a table
18132 if($this->tableLevel
) {
18133 $this->blockjustfinished
=false;
18135 // If already something in the Cell
18136 if ((isset($this->cell
[$this->row
][$this->col
]['maxs']) && $this->cell
[$this->row
][$this->col
]['maxs'] > 0 ) || $this->cell
[$this->row
][$this->col
]['s'] > 0 ) {
18137 $this->_saveCellTextBuffer("\n");
18138 if (!isset($this->cell
[$this->row
][$this->col
]['maxs'])) {
18139 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
18141 elseif($this->cell
[$this->row
][$this->col
]['maxs'] < $this->cell
[$this->row
][$this->col
]['s']) {
18142 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
18144 $this->cell
[$this->row
][$this->col
]['s'] = 0 ;
18146 if ($this->listlvl
== 0) { //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
18147 $this->listlvl++
; // first depth level
18148 $this->listnum
= 0; // reset
18149 $this->listlist
[$this->listlvl
] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum
);
18153 switch($this->listlist
[$this->listlvl
]['TYPE']) {
18155 $blt = $this->dec2alpha($this->listnum
,true).$this->list_number_suffix
;
18158 $blt = $this->dec2alpha($this->listnum
,false).$this->list_number_suffix
;
18161 $blt = $this->dec2roman($this->listnum
,true).$this->list_number_suffix
;
18164 $blt = $this->dec2roman($this->listnum
,false).$this->list_number_suffix
;
18167 $blt = $this->listnum
.$this->list_number_suffix
;
18170 if ($this->listlvl %
3 == 1 && $this->_charDefined($this->CurrentFont
['cw'],8226)) { $blt
= "\xe2\x80\xa2"; } // •
18171 else if ($this->listlvl %
3 == 2 && $this->_charDefined($this->CurrentFont
['cw'],9900)) { $blt
= "\xe2\x9a\xac"; } // ⚬
18172 else if ($this->listlvl %
3 == 0 && $this->_charDefined($this->CurrentFont
['cw'],9642)) { $blt
= "\xe2\x96\xaa"; } // ▪
18173 else { $blt
= '-'; }
18177 // change to spaces
18178 if ($this->usingCoreFont
) {
18179 $ls = str_repeat(chr(160).chr(160),($this->listlvl
-1)*2) . $blt . ' ';
18182 $ls = str_repeat("\xc2\xa0\xc2\xa0",($this->listlvl
-1)*2) . $blt . ' ';
18185 $this->_saveCellTextBuffer($ls, $this->HREF
);
18186 $this->cell
[$this->row
][$this->col
]['s'] +
= $this->GetStringWidth($ls);
18189 /*-- END TABLES --*/
18190 //Observation: </LI> is ignored
18191 if ($this->listlvl
== 0) { //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
18192 //First of all, skip a line
18193 $this->listlvl++
; // first depth level
18194 $this->listnum
= 0; // reset
18195 $this->listoccur
[$this->listlvl
] = 1;
18196 $this->listlist
[$this->listlvl
][1] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum
);
18198 if ($this->listnum
== 0) {
18200 $this->textbuffer
= array();
18203 if (!empty($this->textbuffer
)) {
18204 if (!$this->listjustfinished
) {
18205 $this->listitem
[] = array($this->listlvl
,$this->listnum
,$this->textbuffer
,$this->listoccur
[$this->listlvl
],$this->listitemtype
);
18209 $this->listitem
[] = array($this->listlvl
,$this->listnum
,$this->textbuffer
,$this->listoccur
[$this->listlvl
],$this->listitemtype
, true);
18212 $this->textbuffer
= array();
18214 $this->listjustfinished
= false;
18216 $this->cssmgr
->listCSSlvl++
;
18217 $properties = $this->cssmgr
->MergeCSS('LIST',$tag,$attr);
18218 if (!empty($properties)) $this->setCSS($properties,'LIST');
18219 $this->InlineProperties
['LISTITEM'][$this->listlvl
][$this->listoccur
[$this->listlvl
]][$this->listnum
] = $this->saveInlineProperties();
18222 if (isset($properties['LIST-STYLE-TYPE'])) {
18223 $this->listitemtype
= $this->_getListStyle($properties['LIST-STYLE-TYPE']);
18225 else if (isset($properties['LIST-STYLE'])) {
18226 $this->listitemtype
= $this->_getListStyle($properties['LIST-STYLE']);
18228 else if (isset($attr['TYPE']) && $attr['TYPE']) { $this
->listitemtype
= $attr
['TYPE']; }
18229 else $this->listitemtype
= '';
18231 /*-- END LISTS --*/
18238 function _getListStyle($ls) {
18239 if (stristr($ls,'decimal')) { return '1'; }
18240 /* CSS3 list-styles numeric (selected) + I added tamil
18241 arabic-indic | bengali | devanagari | gujarati | gurmukhi | kannada | malayalam | oriya | persian | telugu | thai | urdu
18243 else if (preg_match('/(disc|circle|square|arabic-indic|bengali|devanagari|gujarati|gurmukhi|kannada|malayalam|oriya|persian|tamil|telugu|thai|urdu)/i',$ls,$m)) {
18244 return strtolower(trim($m[1]));
18246 else if (stristr($ls,'lower-roman')) { return 'i'; }
18247 else if (stristr($ls,'upper-roman')) { return 'I'; }
18248 else if (stristr($ls,'lower-latin')|| stristr($ls,'lower-alpha')) { return 'a'; }
18249 else if (stristr($ls,'upper-latin') || stristr($ls,'upper-alpha')) { return 'A'; }
18250 else if (stristr($ls,'none')) { return 'none'; }
18251 else if (preg_match('/U\+([a-fA-F0-9]+)/i',$ls)) { return $ls
; }
18252 else {
return ''; }
18254 /*-- END LISTS --*/
18258 function CloseTag($tag)
18260 $this->ignorefollowingspaces
= false; //Eliminate exceeding left-side spaces
18262 if($tag=='OPTION') { $this
->selectoption
['ACTIVE'] = false; $this
->lastoptionaltag
= ''; }
18264 if($tag=='TTS' or $tag=='TTA' or $tag=='TTZ') {
18265 if ($this->InlineProperties
[$tag]) { $this
->restoreInlineProperties($this
->InlineProperties
[$tag
]); }
18266 unset($this->InlineProperties
[$tag]);
18267 $ltag = strtolower($tag);
18268 $this->$ltag = false;
18272 if($tag=='FONT' || $tag=='SPAN' || $tag=='CODE' || $tag=='KBD' || $tag=='SAMP' || $tag=='TT' || $tag=='VAR'
18273 || $tag=='INS' || $tag=='STRONG' || $tag=='CITE' || $tag=='SUB' || $tag=='SUP' || $tag=='S' || $tag=='STRIKE' || $tag=='DEL'
18274 || $tag=='Q' || $tag=='EM' || $tag=='B' || $tag=='I' || $tag=='U' | $tag=='SMALL' || $tag=='BIG' || $tag=='ACRONYM'
18275 || $tag=='MARK' || $tag=='TIME' || $tag=='PROGRESS' || $tag=='METER'
18278 if ($tag == 'SPAN') {
18279 if (isset($this->InlineProperties
['SPAN'][$this->spanlvl
]) && $this->InlineProperties
['SPAN'][$this->spanlvl
]) { $this
->restoreInlineProperties($this
->InlineProperties
['SPAN'][$this
->spanlvl
]); }
18280 unset($this->InlineProperties
['SPAN'][$this->spanlvl
]);
18281 if (isset($this->InlineAnnots
['SPAN'][$this->spanlvl
]) && $this->InlineAnnots
['SPAN'][$this->spanlvl
]) { $annot
= $this
->InlineAnnots
['SPAN'][$this
->spanlvl
]; } // *ANNOTATIONS*
18282 unset($this->InlineAnnots
['SPAN'][$this->spanlvl
]); // *ANNOTATIONS*
18286 if (isset($this->InlineProperties
[$tag]) && $this->InlineProperties
[$tag]) { $this
->restoreInlineProperties($this
->InlineProperties
[$tag
]); }
18287 unset($this->InlineProperties
[$tag]);
18288 if (isset($this->InlineAnnots
[$tag]) && $this->InlineAnnots
[$tag]) { $annot
= $this
->InlineAnnots
[$tag
]; } // *ANNOTATIONS*
18289 unset($this->InlineAnnots
[$tag]); // *ANNOTATIONS*
18292 /*-- ANNOTATIONS --*/
18293 if (isset($annot)) {
18294 if($this->tableLevel
) { // *TABLES*
18295 $this->cell
[$this->row
][$this->col
]['textbuffer'][] = array($annot); // *TABLES*
18298 $this->textbuffer
[] = array($annot);
18301 /*-- END ANNOTATIONS --*/
18304 if($tag=='METER' || $tag=='PROGRESS') {
18305 $this->inMeter
= false; // mPDF 5.5.09
18311 if (isset($this->InlineProperties
['A'])) { $this
->restoreInlineProperties($this
->InlineProperties
['A']); }
18312 unset($this->InlineProperties
['A']);
18315 if($tag=='LEGEND') { // mPDF 5.4.18
18316 if (count($this->textbuffer
) && !$this->tableLevel
) {
18317 $leg = $this->textbuffer
[(count($this->textbuffer
)-1)];
18318 unset($this->textbuffer
[(count($this->textbuffer
)-1)]);
18319 $this->textbuffer
= array_values($this->textbuffer
);
18320 $this->blk
[$this->blklvl
]['border_legend'] = $leg;
18321 $this->blk
[$this->blklvl
]['margin_top'] +
= ($leg[11]/2)/_MPDFK
;
18322 $this->blk
[$this->blklvl
]['padding_top'] +
= ($leg[11]/2)/_MPDFK
;
18324 if (isset($this->InlineProperties
['LEGEND'])) { $this
->restoreInlineProperties($this
->InlineProperties
['LEGEND']); }
18325 unset($this->InlineProperties
['LEGEND']);
18326 $this->ignorefollowingspaces
= true; //Eliminate exceeding left-side spaces
18332 // *********** FORM ELEMENTS ********************
18334 if($tag=='TEXTAREA') {
18335 $this->specialcontent
= '';
18336 if ($this->InlineProperties
[$tag]) { $this
->restoreInlineProperties($this
->InlineProperties
[$tag
]); }
18337 unset($this->InlineProperties
[$tag]);
18341 if($tag=='SELECT') {
18342 $this->lastoptionaltag
= '';
18344 if (isset($this->selectoption
['SELECTED'])) { $texto
= $this
->selectoption
['SELECTED']; }
18346 if ($this->useActiveForms
) { $w
= $this
->selectoption
['MAXWIDTH']; }
18347 else { $w
= $this
->GetStringWidth($texto
); }
18348 if ($w == 0) { $w
= 5; }
18349 $objattr['type'] = 'select';
18350 $objattr['text'] = $texto;
18351 if (isset($this->selectoption
['NAME'])) { $objattr
['fieldname'] = $this
->selectoption
['NAME']; }
18352 if (isset($this->selectoption
['READONLY'])) { $objattr
['readonly'] = true; }
18353 if (isset($this->selectoption
['REQUIRED'])) { $objattr
['required'] = true; }
18354 if (isset($this->selectoption
['SPELLCHECK'])) { $objattr
['spellcheck'] = true; }
18355 if (isset($this->selectoption
['EDITABLE'])) { $objattr
['editable'] = true; }
18356 if (isset($this->selectoption
['ONCHANGE'])) { $objattr
['onChange'] = $this
->selectoption
['ONCHANGE']; }
18357 if (isset($this->selectoption
['ITEMS'])) { $objattr
['items'] = $this
->selectoption
['ITEMS']; }
18358 if (isset($this->selectoption
['MULTIPLE'])) { $objattr
['multiple'] = $this
->selectoption
['MULTIPLE']; }
18359 if (isset($this->selectoption
['DISABLED'])) { $objattr
['disabled'] = $this
->selectoption
['DISABLED']; }
18360 if (isset($this->selectoption
['TITLE'])) { $objattr
['title'] = $this
->selectoption
['TITLE']; }
18361 if (isset($this->selectoption
['COLOR'])) { $objattr
['color'] = $this
->selectoption
['COLOR']; }
18362 if (isset($this->selectoption
['SIZE'])) { $objattr
['size'] = $this
->selectoption
['SIZE']; }
18363 if (isset($objattr['size']) && $objattr['size']>1) { $rows
=$objattr
['size']; } else { $rows
= 1; }
18365 $objattr['fontfamily'] = $this->FontFamily
;
18366 $objattr['fontsize'] = $this->FontSizePt
;
18368 $objattr['width'] = $w +
($this->form
->form_element_spacing
['select']['outer']['h']*2)+
($this->form
->form_element_spacing
['select']['inner']['h']*2) +
($this->FontSize
*1.4);
18369 $objattr['height'] = ($this->FontSize
*$rows) +
($this->form
->form_element_spacing
['select']['outer']['v']*2)+
($this->form
->form_element_spacing
['select']['inner']['v']*2);
18370 $e = "\xbb\xa4\xactype=select,objattr=".serialize($objattr)."\xbb\xa4\xac";
18372 // Clear properties - tidy up
18373 $properties = array();
18375 // Output it to buffers
18376 if ($this->tableLevel
) { // *TABLES*
18377 $this->_saveCellTextBuffer($e, $this->HREF
);
18378 $this->cell
[$this->row
][$this->col
]['s'] +
= $objattr['width'] ; // *TABLES*
18381 $this->_saveTextBuffer($e, $this->HREF
);
18384 $this->selectoption
= array();
18385 $this->specialcontent
= '';
18387 if ($this->InlineProperties
[$tag]) { $this
->restoreInlineProperties($this
->InlineProperties
[$tag
]); }
18388 unset($this->InlineProperties
[$tag]);
18391 /*-- END FORMS --*/
18394 // *********** BLOCKS ********************
18396 if($tag=='P' || $tag=='DIV' || $tag=='H1' || $tag=='H2' || $tag=='H3' || $tag=='H4' || $tag=='H5' || $tag=='H6' || $tag=='PRE'
18397 || $tag=='FORM' || $tag=='ADDRESS' || $tag=='BLOCKQUOTE' || $tag=='CENTER' || $tag=='DT' || $tag=='DD' || $tag=='DL'
18398 || $tag=='CAPTION' || $tag=='FIELDSET'
18399 || $tag=='ARTICLE' || $tag=='ASIDE' || $tag=='FIGURE' || $tag=='FIGCAPTION' || $tag=='FOOTER' || $tag=='HEADER' || $tag=='HGROUP'
18400 || $tag=='NAV' || $tag=='SECTION' || $tag=='DETAILS' || $tag=='SUMMARY'
18401 ) { // mPDF 5.5.09 // mPDF 5.5.22
18403 $this->ignorefollowingspaces
= true; //Eliminate exceeding left-side spaces
18404 $this->blockjustfinished
=true;
18406 $this->lastblockbottommargin
= $this->blk
[$this->blklvl
]['margin_bottom'];
18408 if ($this->listlvl
>0) { return; }
18409 /*-- END LISTS --*/
18412 if (preg_match('/^H\d/',$tag) && !$this->tableLevel
&& !$this->writingToC
) { // mPDF 5.6.38
18413 if (isset($this->h2toc
[$tag]) || isset($this->h2bookmarks
[$tag])) {
18415 if (count($this->textbuffer
)==1) { $content
= $this
->textbuffer
[0][0]; }
18417 for ($i=0;$i<count($this->textbuffer
);$i++
) {
18418 if (substr($this->textbuffer
[$i][0],0,3) != "\xbb\xa4\xac") { //inline object
18419 $content .= $this->textbuffer
[$i][0];
18424 if (isset($this->h2toc
[$tag])) {
18425 $objattr = array();
18426 $objattr['type'] = 'toc';
18427 $objattr['toclevel'] = $this->h2toc
[$tag];
18428 $objattr['CONTENT'] = htmlspecialchars($content); // mPDF 5.6.37
18429 $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
18430 array_unshift($this->textbuffer
,array($e));
18433 /*-- BOOKMARKS --*/
18434 if (isset($this->h2bookmarks
[$tag])) {
18435 $objattr = array();
18436 $objattr['type'] = 'bookmark';
18437 $objattr['bklevel'] = $this->h2bookmarks
[$tag];
18438 $objattr['CONTENT'] = $content;
18439 $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
18440 array_unshift($this->textbuffer
,array($e));
18442 /*-- END BOOKMARKS --*/
18447 if($this->tableLevel
) {
18448 if ($this->linebreakjustfinished
) { $this
->blockjustfinished
=false; }
18449 if (isset($this->InlineProperties
['BLOCKINTABLE'])) {
18450 if ($this->InlineProperties
['BLOCKINTABLE']) { $this
->restoreInlineProperties($this
->InlineProperties
['BLOCKINTABLE']); }
18451 unset($this->InlineProperties
['BLOCKINTABLE']);
18453 if($tag=='PRE') { $this
->ispre
=false; }
18456 /*-- END TABLES --*/
18457 $this->lastoptionaltag
= '';
18458 $this->divbegin
=false;
18460 $this->linebreakjustfinished
=false;
18462 $this->x
= $this->lMargin +
$this->blk
[$this->blklvl
]['outer_left_margin'];
18464 /*-- CSS-FLOAT --*/
18465 // If float contained in a float, need to extend bottom to allow for it
18466 $currpos = $this->page
*1000 +
$this->y
;
18467 if (isset($this->blk
[$this->blklvl
]['float_endpos']) && $this->blk
[$this->blklvl
]['float_endpos'] > $currpos) {
18468 $old_page = $this->page
;
18469 $new_page = intval($this->blk
[$this->blklvl
]['float_endpos'] /1000);
18470 if ($old_page != $new_page) {
18471 $s = $this->PrintPageBackgrounds();
18472 // Writes after the marker so not overwritten later by page background etc.
18473 $this->pages
[$this->page
] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages
[$this->page
]);
18474 $this->pageBackgrounds
= array();
18475 $this->page
= $new_page;
18476 $this->ResetMargins();
18478 $this->pageoutput
[$this->page
] = array();
18480 $this->y
= (($this->blk
[$this->blklvl
]['float_endpos'] *1000) %
1000000)/1000; // mod changes operands to integers before processing
18482 /*-- END CSS-FLOAT --*/
18486 if ($this->lastblocklevelchange
== 1) { $blockstate
= 3; } // Top & bottom margins/padding
18487 else if ($this->lastblocklevelchange
== -1) { $blockstate
= 2; } // Bottom margins/padding only
18488 else { $blockstate
= 0; }
18489 // called from after e.g. </table> </div> </div> ... Outputs block margin/border and padding
18490 if (count($this->textbuffer
) && $this->textbuffer
[count($this->textbuffer
)-1]) {
18491 if (substr($this->textbuffer
[count($this->textbuffer
)-1][0],0,3) != "\xbb\xa4\xac") { // not special content
18492 if ($this->usingCoreFont
) {
18493 $this->textbuffer
[count($this->textbuffer
)-1][0] = preg_replace('/[ ]+$/', '', $this->textbuffer
[count($this->textbuffer
)-1][0]);
18496 $this->textbuffer
[count($this->textbuffer
)-1][0] = preg_replace('/[ ]+$/u', '', $this->textbuffer
[count($this->textbuffer
)-1][0]); }
18500 if (count($this->textbuffer
) == 0 && $this->lastblocklevelchange
!= 0) {
18501 //$this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,2,true, $this->blk[$this->blklvl]['direction']);
18502 $this->newFlowingBlock( $this->blk
[$this->blklvl
]['width'],$this->lineheight
,'',false,false,$blockstate,true, $this->blk
[$this->blklvl
]['direction']);
18503 $this->finishFlowingBlock(true); // true = END of flowing block
18504 $this->PaintDivBB('',$blockstate);
18507 $this->printbuffer($this->textbuffer
,$blockstate);
18511 $this->textbuffer
=array();
18513 if ($this->blk
[$this->blklvl
]['keep_block_together']) {
18514 $this->printdivbuffer();
18518 $this->kwt_height
= $this->y
- $this->kwt_y0
;
18521 /*-- CSS-IMAGE-FLOAT --*/
18522 $this->printfloatbuffer();
18523 /*-- END CSS-IMAGE-FLOAT --*/
18525 if($tag=='PRE') { $this
->ispre
=false; }
18527 /*-- CSS-FLOAT --*/
18528 if ($this->blk
[$this->blklvl
]['float'] == 'R') {
18529 // If width not set, here would need to adjust and output buffer
18530 $s = $this->PrintPageBackgrounds();
18531 // Writes after the marker so not overwritten later by page background etc.
18532 $this->pages
[$this->page
] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages
[$this->page
]);
18533 $this->pageBackgrounds
= array();
18535 $this->pageoutput
[$this->page
] = array();
18537 for($i=($this->blklvl
-1); $i >= 0; $i--) {
18538 if (isset($this->blk
[$i]['float_endpos'])) { $this
->blk
[$i
]['float_endpos'] = max($this
->blk
[$i
]['float_endpos'], ($this
->page
*1000 + $this
->y
)); }
18539 else { $this
->blk
[$i
]['float_endpos'] = $this
->page
*1000 + $this
->y
; }
18542 $this->floatDivs
[] = array(
18544 'startpage'=>$this->blk
[$this->blklvl
]['startpage'] ,
18545 'y0'=>$this->blk
[$this->blklvl
]['float_start_y'] ,
18546 'startpos'=> ($this->blk
[$this->blklvl
]['startpage']*1000 +
$this->blk
[$this->blklvl
]['float_start_y']),
18547 'endpage'=>$this->page
,
18549 'endpos'=> ($this->page
*1000 +
$this->y
),
18550 'w'=> $this->blk
[$this->blklvl
]['float_width'],
18551 'blklvl'=>$this->blklvl
,
18552 'blockContext' => $this->blk
[$this->blklvl
-1]['blockContext']
18555 $this->y
= $this->blk
[$this->blklvl
]['float_start_y'] ;
18556 $this->page
= $this->blk
[$this->blklvl
]['startpage'] ;
18557 $this->ResetMargins();
18558 $this->pageoutput
[$this->page
] = array();
18560 if ($this->blk
[$this->blklvl
]['float'] == 'L') {
18561 // If width not set, here would need to adjust and output buffer
18562 $s = $this->PrintPageBackgrounds();
18563 // Writes after the marker so not overwritten later by page background etc.
18564 $this->pages
[$this->page
] = preg_replace('/(___BACKGROUND___PATTERNS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages
[$this->page
]);
18565 $this->pageBackgrounds
= array();
18567 $this->pageoutput
[$this->page
] = array();
18569 for($i=($this->blklvl
-1); $i >= 0; $i--) {
18570 if (isset($this->blk
[$i]['float_endpos'])) { $this
->blk
[$i
]['float_endpos'] = max($this
->blk
[$i
]['float_endpos'], ($this
->page
*1000 + $this
->y
)); }
18571 else { $this
->blk
[$i
]['float_endpos'] = $this
->page
*1000 + $this
->y
; }
18574 $this->floatDivs
[] = array(
18576 'startpage'=>$this->blk
[$this->blklvl
]['startpage'] ,
18577 'y0'=>$this->blk
[$this->blklvl
]['float_start_y'] ,
18578 'startpos'=> ($this->blk
[$this->blklvl
]['startpage']*1000 +
$this->blk
[$this->blklvl
]['float_start_y']),
18579 'endpage'=>$this->page
,
18581 'endpos'=> ($this->page
*1000 +
$this->y
),
18582 'w'=> $this->blk
[$this->blklvl
]['float_width'],
18583 'blklvl'=>$this->blklvl
,
18584 'blockContext' => $this->blk
[$this->blklvl
-1]['blockContext']
18587 $this->y
= $this->blk
[$this->blklvl
]['float_start_y'] ;
18588 $this->page
= $this->blk
[$this->blklvl
]['startpage'] ;
18589 $this->ResetMargins();
18590 $this->pageoutput
[$this->page
] = array();
18592 /*-- END CSS-FLOAT --*/
18594 if (isset($this->blk
[$this->blklvl
]['visibility']) && $this->blk
[$this->blklvl
]['visibility']!='visible') {
18595 $this->SetVisibility('visible');
18598 if (isset($this->blk
[$this->blklvl
]['page_break_after'])) { $page_break_after
= $this
->blk
[$this
->blklvl
]['page_break_after']; }
18599 else { $page_break_after
= ''; }
18604 // mPDF 5.6.01 - LAYERS
18605 if (isset($this->blk
[$this->blklvl
]['z-index']) && $this->blk
[$this->blklvl
]['z-index'] > 0) {
18609 if ($this->blklvl
> 0) { // ==0 SHOULDN'T HAPPEN - NOT XHTML
18610 if ($this->blk
[$this->blklvl
]['tag'] == $tag) {
18611 unset($this->blk
[$this->blklvl
]);
18614 //else { echo $tag; exit; } // debug - forces error if incorrectly nested html tags
18617 $this->lastblocklevelchange
= -1 ;
18618 // Reset Inline-type properties
18619 if (isset($this->blk
[$this->blklvl
]['InlineProperties'])) { $this
->restoreInlineProperties($this
->blk
[$this
->blklvl
]['InlineProperties']); }
18621 $this->x
= $this->lMargin +
$this->blk
[$this->blklvl
]['outer_left_margin'];
18623 if ($page_break_after) {
18624 $save_blklvl = $this->blklvl
;
18625 $save_blk = $this->blk
;
18626 $save_silp = $this->saveInlineProperties();
18627 $save_spanlvl = $this->spanlvl
;
18628 $save_ilp = $this->InlineProperties
;
18629 if ($this->blklvl
>1) {
18630 // Close any open block tags
18631 for ($b= $this->blklvl
;$b>0;$b--) { $this
->CloseTag($this
->blk
[$b
]['tag']); }
18632 // Output any text left in buffer
18633 if (count($this->textbuffer
)) { $this
->printbuffer($this
->textbuffer
); $this
->textbuffer
=array(); }
18636 $save_cols = false;
18637 if ($this->ColActive
) {
18639 $save_nbcol = $this->NbCol
; // other values of gap and vAlign will not change by setting Columns off
18640 $this->SetColumns(0);
18642 /*-- END COLUMNS --*/
18643 if ($page_break_after == 'RIGHT') { $this
->AddPage($this
->CurOrientation
,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel
); }
18644 else if ($page_break_after == 'LEFT') { $this
->AddPage($this
->CurOrientation
,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel
); }
18645 else { $this
->AddPage($this
->CurOrientation
,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel
); }
18646 if (!$this->restoreBlockPagebreaks
) {
18648 $this->lastblocklevelchange
= 0;
18649 $this->blk
= array();
18650 $this->initialiseBlock($this->blk
[0]);
18651 $this->blk
[0]['width'] =& $this->pgwidth
;
18652 $this->blk
[0]['inner_width'] =& $this->pgwidth
;
18653 $this->blk
[0]['blockContext'] = $this->blockContext
;
18654 $properties = $this->cssmgr
->MergeCSS('BLOCK','BODY','');
18655 $this->setCSS($properties,'','BODY');
18657 $currblk =& $this->blk
[$this->blklvl
];
18658 $prevblk =& $this->blk
[$this->blklvl
-1];
18660 $this->initialiseBlock($currblk);
18661 $currblk['tag'] = $tag;
18662 $currblk['attr'] = $attr;
18665 $properties = $this->cssmgr
->MergeCSS('BLOCK',$tag,$attr);
18670 $this->SetColumns($save_nbcol,$this->colvAlign
,$this->ColGap
);
18672 /*-- END COLUMNS --*/
18673 if ($this->restoreBlockPagebreaks
&& !$this->tableLevel
&& !$this->listlvl
) {
18674 $this->blk
= $save_blk;
18675 // Re-open block tags
18676 $t = $this->blk
[0]['tag'];
18677 $a = $this->blk
[0]['attr'];
18679 for ($b=0; $b<=$save_blklvl;$b++
) {
18682 $t = $this->blk
[$b+
1]['tag'];
18683 $a = $this->blk
[$b+
1]['attr'];
18684 unset($this->blk
[$b+
1]);
18685 $this->OpenTag($tc,$ac);
18687 $this->spanlvl
= $save_spanlvl;
18688 $this->InlineProperties
= $save_ilp;
18689 $this->restoreInlineProperties($save_silp);
18698 if($tag=='TH') $this->SetStyle('B',false);
18700 if(($tag=='TH' or $tag=='TD') && $this->tableLevel
) {
18701 $this->lastoptionaltag
= 'TR';
18702 unset($this->cssmgr
->tablecascadeCSS
[$this->cssmgr
->tbCSSlvl
]);
18703 $this->cssmgr
->tbCSSlvl
--;
18704 if (!$this->tdbegin
) { return; }
18705 $this->tdbegin
= false;
18706 // Added for correct calculation of cell column width - otherwise misses the last line if not end </p> etc.
18707 if (!isset($this->cell
[$this->row
][$this->col
]['maxs'])) {
18708 if (!is_array($this->cell
[$this->row
][$this->col
])) { $this
->Error("You may have an error in your HTML code e.g. </td></td>"); }
18709 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
18711 elseif($this->cell
[$this->row
][$this->col
]['maxs'] < $this->cell
[$this->row
][$this->col
]['s']) {
18712 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
18715 // Remove last <br> if at end of cell
18716 if (isset($this->cell
[$this->row
][$this->col
]['textbuffer'])) { $ntb
= count($this
->cell
[$this
->row
][$this
->col
]['textbuffer']); }
18718 if ($ntb>1 && $this->cell
[$this->row
][$this->col
]['textbuffer'][$ntb-1][0] == "\n") {
18719 unset($this->cell
[$this->row
][$this->col
]['textbuffer'][$ntb-1]);
18722 if ($this->cacheTables
) {
18723 $clen = $this->_cacheCell($this->cell
[$this->row
][$this->col
], $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['cache']);
18724 $this->cell
[$this->row
][$this->col
] = $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['ptr'];
18725 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['ptr'] +
= $clen;
18728 if ($this->tablethead
) {
18729 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['is_thead'][$this->row
] = true;
18730 if ($this->tableLevel
==1) { $this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['headernrows'] = max($this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['headernrows'] , ($this
->row+
1)); }
18732 if ($this->tabletfoot
) {
18733 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['is_tfoot'][$this->row
] = true;
18734 if ($this->tableLevel
==1) { $this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['footernrows'] = max($this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['footernrows'] , ($this
->row+
1 - $this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['headernrows'] )); }
18739 if($tag=='TR' && $this->tableLevel
) {
18740 // If Border set on TR - Update right border
18741 if (isset($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['trborder-left'][$this->row
])) {
18742 if ($this->cacheTables
) {
18743 $c = $this->_uncacheCell($this->cell
[$this->row
][$this->col
], $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['cache'], null);
18745 else { $c
=& $this
->cell
[$this
->row
][$this
->col
]; }
18747 if ($this->packTableData
) {
18748 $cell = $this->_unpackCellBorder($c['borderbin'] );
18750 else { $cell
= $c
; }
18751 $cell['border_details']['R'] = $this->border_details($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['trborder-right'][$this->row
]);
18752 $this->setBorder($cell['border'], _BORDER_RIGHT
, $cell['border_details']['R']['s']);
18753 if ($this->packTableData
) {
18754 $c['borderbin'] = $this->_packCellBorder($cell);
18755 unset($c['border']);
18756 unset($c['border_details']);
18758 else { $c
= $cell
; }
18760 if ($this->cacheTables
) {
18761 $fh = fopen($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['cache'], "r+b");
18762 $this->_cacheUpdateBorder($c, $fh, $this->cell
[$this->row
][$this->col
]);
18766 $this->lastoptionaltag
= '';
18767 unset($this->cssmgr
->tablecascadeCSS
[$this->cssmgr
->tbCSSlvl
]);
18768 $this->cssmgr
->tbCSSlvl
--;
18769 $this->trow_text_rotate
= '';
18770 $this->tabletheadjustfinished
= false;
18773 if($tag=='TBODY') {
18774 $this->lastoptionaltag
= '';
18775 unset($this->cssmgr
->tablecascadeCSS
[$this->cssmgr
->tbCSSlvl
]);
18776 $this->cssmgr
->tbCSSlvl
--;
18779 if($tag=='THEAD') {
18780 $this->lastoptionaltag
= '';
18781 unset($this->cssmgr
->tablecascadeCSS
[$this->cssmgr
->tbCSSlvl
]);
18782 $this->cssmgr
->tbCSSlvl
--;
18783 $this->tablethead
= 0;
18784 $this->tabletheadjustfinished
= true;
18785 $this->ResetStyles();
18786 $this->thead_font_weight
= '';
18787 $this->thead_font_style
= '';
18788 $this->thead_font_smCaps
= '';
18790 $this->thead_valign_default
= '';
18791 $this->thead_textalign_default
= '';
18794 if($tag=='TFOOT') {
18795 $this->lastoptionaltag
= '';
18796 unset($this->cssmgr
->tablecascadeCSS
[$this->cssmgr
->tbCSSlvl
]);
18797 $this->cssmgr
->tbCSSlvl
--;
18798 $this->tabletfoot
= 0;
18799 $this->ResetStyles();
18800 $this->tfoot_font_weight
= '';
18801 $this->tfoot_font_style
= '';
18802 $this->tfoot_font_smCaps
= '';
18804 $this->tfoot_valign_default
= '';
18805 $this->tfoot_textalign_default
= '';
18808 if($tag=='TABLE') { // TABLE-END (
18809 if ($this->progressBar
) { $this
->UpdateProgressBar(1,'','TABLE'); } // *PROGRESS-BAR*
18810 if ($this->progressBar
) { $this
->UpdateProgressBar(7,0,''); } // *PROGRESS-BAR*
18811 $this->lastoptionaltag
= '';
18812 unset($this->cssmgr
->tablecascadeCSS
[$this->cssmgr
->tbCSSlvl
]);
18813 $this->cssmgr
->tbCSSlvl
--;
18814 $this->ignorefollowingspaces
= true; //Eliminate exceeding left-side spaces
18815 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['cells'] = $this->cell
;
18816 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['wc'] = array_pad(array(),$this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['nc'],array('miw'=>0,'maw'=>0));
18817 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['hr'] = array_pad(array(),$this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['nr'],0);
18819 // Move table footer <tfoot> row to end of table
18820 if (isset($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['is_tfoot']) && count($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['is_tfoot'])) {
18822 foreach($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['is_tfoot'] AS $r=>$val) {
18823 if ($val) { $tfrows
[] = $r
; }
18827 foreach($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['cells'] AS $k=>$row) {
18828 if (in_array($k,$tfrows)) {
18835 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['is_tfoot'] = array();
18836 for($i=count($temp) ; $i<(count($temp)+
count($temptf)); $i++
) {
18837 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['is_tfoot'][$i] = true;
18839 // Update nestedpos row references
18840 if (count($this->table
[($this->tableLevel+
1)])) {
18841 foreach($this->table
[($this->tableLevel+
1)] AS $nid=>$nested) {
18842 $this->table
[($this->tableLevel+
1)][$nid]['nestedpos'][0] -= count($temptf);
18845 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['cells'] = array_merge($temp, $temptf);
18847 // Update other arays set on row number
18848 // [trbackground-images] [trgradients]
18849 $temptrbgi = array();
18850 $temptrbgg = array();
18851 $temptrbgc = array();
18852 $temptrbgc[-1] = $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['bgcolor'][-1];
18853 for($k=0; $k<$this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['nr']; $k++
) {
18854 if (!in_array($k,$tfrows)) {
18855 $temptrbgi[] = $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['trbackground-images'][$k];
18856 $temptrbgg[] = $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['trgradients'][$k];
18857 $temptrbgc[] = $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['bgcolor'][$k];
18860 for($k=0; $k<$this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['nr']; $k++
) {
18861 if (in_array($k,$tfrows)) {
18862 $temptrbgi[] = $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['trbackground-images'][$k];
18863 $temptrbgg[] = $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['trgradients'][$k];
18864 $temptrbgc[] = $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['bgcolor'][$k];
18867 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['trbackground-images'] = $temptrbgi;
18868 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['trgradients'] = $temptrbgg;
18869 $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['bgcolor'] = $temptrbgc ;
18870 // Should Update all other arays set on row number, but cell properties have been set so not needed
18871 // [bgcolor] [trborder-left] [trborder-right] [trborder-top] [trborder-bottom]
18874 if ($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['direction']=='rtl') {
18875 $this->_reverseTableDir($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]);
18878 // Fix Borders *********************************************
18879 $this->_fixTableBorders($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]);
18881 if ($this->progressBar
) { $this
->UpdateProgressBar(7,10,' '); } // *PROGRESS-BAR*
18883 if ($this->ColActive
) { $this
->table_rotate
= 0; } // *COLUMNS*
18884 if ($this->table_rotate
<> 0) {
18885 $this->tablebuffer
= '';
18886 // Max width for rotated table
18887 $this->tbrot_maxw
= $this->h
- ($this->y +
$this->bMargin +
1);
18888 $this->tbrot_maxh
= $this->blk
[$this->blklvl
]['inner_width'] ; // Max width for rotated table
18889 $this->tbrot_align
= $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['a'] ;
18891 $this->shrin_k
= 1;
18893 if ($this->shrink_tables_to_fit
< 1) { $this
->shrink_tables_to_fit
= 1; }
18894 if (!$this->shrink_this_table_to_fit
) { $this
->shrink_this_table_to_fit
= $this
->shrink_tables_to_fit
; }
18896 if ($this->tableLevel
>1) {
18897 // deal with nested table
18899 $this->_tableColumnWidth($this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]],true);
18901 $tmiw = $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['miw'];
18902 $tmaw = $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['maw'];
18903 $tl = $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['tl'];
18905 // Go down to lower table level
18906 $this->tableLevel
--;
18908 // Reset lower level table
18909 $this->base_table_properties
= $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['baseProperties'];
18910 $this->cell
= $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['cells'];
18912 if (isset($this->cell
['PARENTCELL'])) {
18913 if ($this->cell
['PARENTCELL']) { $this
->restoreInlineProperties($this
->cell
['PARENTCELL']); }
18914 unset($this->cell
['PARENTCELL']);
18916 $this->row
= $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['currrow'];
18917 $this->col
= $this->table
[$this->tableLevel
][$this->tbctr
[$this->tableLevel
]]['currcol'];
18918 $objattr = array();
18919 $objattr['type'] = 'nestedtable';
18920 $objattr['nestedcontent'] = $this->tbctr
[($this->tableLevel+
1)];
18921 $objattr['table'] = $this->tbctr
[$this->tableLevel
];
18922 $objattr['row'] = $this->row
;
18923 $objattr['col'] = $this->col
;
18924 $objattr['level'] = $this->tableLevel
;
18925 $e = "\xbb\xa4\xactype=nestedtable,objattr=".serialize($objattr)."\xbb\xa4\xac";
18926 $this->_saveCellTextBuffer($e);
18927 $this->cell
[$this->row
][$this->col
]['s'] +
= $tl ;
18928 if (!isset($this->cell
[$this->row
][$this->col
]['maxs'])) {
18929 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
18931 elseif($this->cell
[$this->row
][$this->col
]['maxs'] < $this->cell
[$this->row
][$this->col
]['s']) {
18932 $this->cell
[$this->row
][$this->col
]['maxs'] = $this->cell
[$this->row
][$this->col
]['s'];
18934 $this->cell
[$this->row
][$this->col
]['s'] = 0;// reset
18935 if ((isset($this->cell
[$this->row
][$this->col
]['nestedmaw']) && $this->cell
[$this->row
][$this->col
]['nestedmaw'] < $tmaw) || !isset($this->cell
[$this->row
][$this->col
]['nestedmaw'])) { $this
->cell
[$this
->row
][$this
->col
]['nestedmaw'] = $tmaw
; }
18936 if ((isset($this->cell
[$this->row
][$this->col
]['nestedmiw']) && $this->cell
[$this->row
][$this->col
]['nestedmiw'] < $tmiw) || !isset($this->cell
[$this->row
][$this->col
]['nestedmiw'])) { $this
->cell
[$this
->row
][$this
->col
]['nestedmiw'] = $tmiw
; }
18937 $this->tdbegin
= true;
18938 $this->nestedtablejustfinished
= true;
18939 $this->ignorefollowingspaces
= true;
18942 $this->cMarginL
= 0;
18943 $this->cMarginR
= 0;
18944 $this->cMarginT
= 0;
18945 $this->cMarginB
= 0;
18946 $this->cellPaddingL
= 0;
18947 $this->cellPaddingR
= 0;
18948 $this->cellPaddingT
= 0;
18949 $this->cellPaddingB
= 0;
18951 if (isset($this->table
[1][1]['overflow']) && $this->table
[1][1]['overflow']=='visible') {
18952 if ($this->kwt
|| $this->table_rotate
|| $this->table_keep_together
|| $this->ColActive
) {
18953 $this->kwt
= false;
18954 $this->table_rotate
= 0;
18955 $this->table_keep_together
= false;
18956 //die("mPDF Warning: You cannot use CSS overflow:visible together with any of these functions: 'Keep-with-table', rotated tables, page-break-inside:avoid, or columns");
18958 $this->_tableColumnWidth($this->table
[1][1],true);
18959 $this->_tableWidth($this->table
[1][1]);
18962 if (!$this->kwt_saved
) { $this
->kwt_height
= 0; }
18964 list($check,$tablemiw) = $this->_tableColumnWidth($this->table
[1][1],true);
18965 $save_table = $this->table
;
18966 if ($this->cacheTables
) { $this
->_backupCacheFiles(); }
18967 $reset_to_minimum_width = false;
18968 $added_page = false;
18971 if ($check > $this->shrink_this_table_to_fit
&& $this->table_rotate
) {
18972 if ($this->y
!= $this->tMargin
) {
18973 $this->AddPage($this->CurOrientation
);
18974 $this->kwt_moved
= true;
18976 $added_page = true;
18977 $this->tbrot_maxw
= $this->h
- ($this->y +
$this->bMargin +
5) - $this->kwt_height
;
18978 //$check = $tablemiw/$this->tbrot_maxw; // undo any shrink
18979 $check = 1; // undo any shrink
18981 $reset_to_minimum_width = true;
18984 if ($reset_to_minimum_width) {
18986 $this->shrin_k
= $check;
18988 $this->default_font_size
/= $this->shrin_k
;
18989 $this->SetFontSize($this->default_font_size
, false );
18991 $this->shrinkTable($this->table
[1][1],$this->shrin_k
);
18993 $this->_tableColumnWidth($this->table
[1][1],false); // repeat
18995 // Starting at $this->innermostTableLevel
18996 // Shrink table values - and redo columnWidth
18997 for($lvl=2;$lvl<=$this->innermostTableLevel
;$lvl++
) {
18998 for ($nid=1; $nid<=$this->tbctr
[$lvl]; $nid++
) {
18999 $this->shrinkTable($this->table
[$lvl][$nid],$this->shrin_k
);
19000 $this->_tableColumnWidth($this->table
[$lvl][$nid],false);
19005 // Set table cell widths for top level table
19006 // Use $shrin_k to resize but don't change again
19007 $this->SetLineHeight('',$this->table_lineheight
);
19010 $this->_tableWidth($this->table
[1][1]);
19015 // Now work through any nested tables setting child table[w'] = parent cell['w']
19016 // Now do nested tables _tableWidth
19017 for($lvl=2;$lvl<=$this->innermostTableLevel
;$lvl++
) {
19018 for ($nid=1; $nid<=$this->tbctr
[$lvl]; $nid++
) {
19019 // HERE set child table width = cell width
19021 list($parentrow, $parentcol, $parentnid) = $this->table
[$lvl][$nid]['nestedpos'];
19023 if ($this->cacheTables
) {
19024 $c = $this->_uncacheCell($this->table
[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol], $this->table
[($lvl-1)][$parentnid]['cache'], null);
19027 $c =& $this->table
[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol];
19029 if (isset($c['colspan']) && $c['colspan']> 1) {
19031 for($cs=0;$cs<$c['colspan'] ; $cs++
) {
19032 $parentwidth +
= $this->table
[($lvl-1)][$parentnid]['wc'][$parentcol+
$cs];
19035 else { $parentwidth
= $this
->table
[($lvl
-1)][$parentnid
]['wc'][$parentcol
]; }
19038 //$parentwidth -= ALLOW FOR PADDING ETC.in parent cell
19039 if (!$this->simpleTables
){
19040 if ($this->packTableData
) {
19041 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
19044 $br = $c['border_details']['R']['w'];
19045 $bl = $c['border_details']['L']['w'];
19047 if ($this->table
[$lvl-1][$parentnid]['borders_separate']) {
19048 $parentwidth -= $br +
$bl
19049 +
$c['padding']['L']
19050 +
$c['padding']['R']
19051 +
$this->table
[($lvl-1)][$parentnid]['border_spacing_H'];
19054 $parentwidth -= $br/2 +
$bl/2
19055 +
$c['padding']['L']
19056 +
$c['padding']['R'];
19059 else if ($this->simpleTables
){
19060 if ($this->table
[$lvl-1][$parentnid]['borders_separate']) {
19061 $parentwidth -= $this->table
[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19062 +
$this->table
[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']
19063 +
$c['padding']['L']
19064 +
$c['padding']['R']
19065 +
$this->table
[($lvl-1)][$parentnid]['border_spacing_H'];
19068 $parentwidth -= $this->table
[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']/2
19069 +
$this->table
[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']/2
19070 +
$c['padding']['L']
19071 +
$c['padding']['R'];
19074 if (isset($this->table
[$lvl][$nid]['wpercent']) && $this->table
[$lvl][$nid]['wpercent'] && $lvl>1) {
19075 $this->table
[$lvl][$nid]['w'] = $parentwidth;
19077 else if ($parentwidth > $this->table
[$lvl][$nid]['maw']) {
19078 $this->table
[$lvl][$nid]['w'] = $this->table
[$lvl][$nid]['maw'];
19081 $this->table
[$lvl][$nid]['w'] = $parentwidth;
19084 $this->_tableWidth($this->table
[$lvl][$nid]);
19088 // Starting at $this->innermostTableLevel
19089 // Cascade back up nested tables: setting heights back up the tree
19090 for($lvl=$this->innermostTableLevel
;$lvl>0;$lvl--) {
19091 for ($nid=1; $nid<=$this->tbctr
[$lvl]; $nid++
) {
19092 list($tableheight,$maxrowheight,$fullpage,$remainingpage, $maxfirstrowheight) = $this->_tableHeight($this->table
[$lvl][$nid]); }
19094 if ($this->progressBar
) { $this
->UpdateProgressBar(7,20,' '); } // *PROGRESS-BAR*
19095 if ($this->table
[1][1]['overflow']=='visible') {
19096 if ($maxrowheight > $fullpage) { die("mPDF Warning: A Table row is greater than available height. You cannot use CSS overflow:visible"); }
19097 if ($maxfirstrowheight > $remainingpage) { $this
->AddPage($this
->CurOrientation
); }
19098 $r = 0; $c = 0; $p = 0; $y = 0;
19099 while (!$finished) {
19100 list($finished,$r,$c,$p,$y,$y0) = $this->_tableWrite($this->table
[1][1],true,$r,$c,$p,$y);
19102 $this->AddPage($this->CurOrientation
);
19103 // If printed something on first spread, set same y
19104 if ($r==0 && $y0 > -1) { $this
->y
= $y0
; }
19110 $forcerecalc = false;
19111 // RESIZING ALGORITHM
19112 if ($maxrowheight > $fullpage) {
19113 $recalculate = $this->tbsqrt($maxrowheight / $fullpage, 1);
19114 $forcerecalc = true;
19116 else if ($this->table_rotate
) { // NB $remainingpage == $fullpage == the width of the page
19117 if ($tableheight > $remainingpage) {
19118 // If can fit on remainder of page whilst respecting autsize value..
19119 if (($this->shrin_k
* $this->tbsqrt($tableheight / $remainingpage, 1)) <= $this->shrink_this_table_to_fit
) {
19120 $recalculate = $this->tbsqrt($tableheight / $remainingpage, 1);
19122 else if (!$added_page) {
19123 if ($this->y
!= $this->tMargin
) {
19124 $this->AddPage($this->CurOrientation
);
19125 $this->kwt_moved
= true;
19127 $added_page = true;
19128 $this->tbrot_maxw
= $this->h
- ($this->y +
$this->bMargin +
5) - $this->kwt_height
;
19129 // 0.001 to force it to recalculate
19130 $recalculate = (1 / $this->shrin_k
) +
0.001; // undo any shrink
19133 else { $recalculate
= 1; }
19135 else if ($this->table_keep_together
|| ($this->table
[1][1]['nr']==1 && !$this->writingHTMLfooter
)) {
19136 if ($tableheight > $fullpage) {
19137 if (($this->shrin_k
* $this->tbsqrt($tableheight / $fullpage, 1)) <= $this->shrink_this_table_to_fit
) {
19138 $recalculate = $this->tbsqrt($tableheight / $fullpage, 1);
19140 else if ($this->tableMinSizePriority
) {
19141 $this->table_keep_together
= false;
19142 $recalculate = 1.001;
19145 if ($this->y
!= $this->tMargin
) { // mPDF 5.1
19146 $this->AddPage($this->CurOrientation
);
19147 $this->kwt_moved
= true;
19149 $added_page = true;
19150 $this->tbrot_maxw
= $this->h
- ($this->y +
$this->bMargin +
5) - $this->kwt_height
;
19151 $recalculate = $this->tbsqrt($tableheight / $fullpage, 1);
19154 else if ($tableheight > $remainingpage) {
19155 // If can fit on remainder of page whilst respecting autsize value..
19156 if (($this->shrin_k
* $this->tbsqrt($tableheight / $remainingpage, 1)) <= $this->shrink_this_table_to_fit
) {
19157 $recalculate = $this->tbsqrt($tableheight / $remainingpage, 1);
19160 if ($this->y
!= $this->tMargin
) {
19161 $this->AddPage($this->CurOrientation
);
19162 $this->kwt_moved
= true;
19164 $added_page = true;
19165 $this->tbrot_maxw
= $this->h
- ($this->y +
$this->bMargin +
5) - $this->kwt_height
;
19166 $recalculate = 1.001;
19169 else { $recalculate
= 1; }
19171 else { $recalculate
= 1; }
19173 if ($recalculate > $this->shrink_this_table_to_fit
&& !$forcerecalc) { $recalculate
= $this
->shrink_this_table_to_fit
; }
19178 while($recalculate <> 1) {
19179 $this->shrin_k1
= $recalculate ;
19180 $this->shrin_k
*= $recalculate ;
19181 $this->default_font_size
/= ($this->shrin_k1
) ;
19182 $this->SetFontSize($this->default_font_size
, false );
19183 $this->SetLineHeight('',$this->table_lineheight
);
19184 $this->table
= $save_table;
19185 if ($this->cacheTables
) { $this
->_restoreCacheFiles(); }
19186 if ($this->shrin_k
<> 1) { $this
->shrinkTable($this
->table
[1][1],$this
->shrin_k
); }
19187 $this->_tableColumnWidth($this->table
[1][1],false); // repeat
19189 // Starting at $this->innermostTableLevel
19190 // Shrink table values - and redo columnWidth
19191 for($lvl=2;$lvl<=$this->innermostTableLevel
;$lvl++
) {
19192 for ($nid=1; $nid<=$this->tbctr
[$lvl]; $nid++
) {
19193 if ($this->shrin_k
<> 1) { $this
->shrinkTable($this
->table
[$lvl
][$nid
],$this
->shrin_k
); }
19194 $this->_tableColumnWidth($this->table
[$lvl][$nid],false);
19197 // Set table cell widths for top level table
19200 $this->_tableWidth($this->table
[1][1]);
19202 // Now work through any nested tables setting child table[w'] = parent cell['w']
19203 // Now do nested tables _tableWidth
19204 for($lvl=2;$lvl<=$this->innermostTableLevel
;$lvl++
) {
19205 for ($nid=1; $nid<=$this->tbctr
[$lvl]; $nid++
) {
19206 // HERE set child table width = cell width
19208 list($parentrow, $parentcol, $parentnid) = $this->table
[$lvl][$nid]['nestedpos'];
19209 if ($this->cacheTables
) {
19210 $c = $this->_uncacheCell($this->table
[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol], $this->table
[($lvl-1)][$parentnid]['cache'], null);
19213 $c =& $this->table
[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol];
19215 if (isset($c['colspan']) && $c['colspan']> 1) {
19217 for($cs=0;$cs<$c['colspan'] ; $cs++
) {
19218 $parentwidth +
= $this->table
[($lvl-1)][$parentnid]['wc'][$parentcol+
$cs];
19221 else { $parentwidth
= $this
->table
[($lvl
-1)][$parentnid
]['wc'][$parentcol
]; }
19223 //$parentwidth -= ALLOW FOR PADDING ETC.in parent cell
19224 if (!$this->simpleTables
){
19225 if ($this->packTableData
) {
19226 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
19229 $br = $c['border_details']['R']['w'];
19230 $bl = $c['border_details']['L']['w'];
19232 if ($this->table
[$lvl-1][$parentnid]['borders_separate']) {
19233 $parentwidth -= $br +
$bl
19234 +
$c['padding']['L']
19235 +
$c['padding']['R']
19236 +
$this->table
[($lvl-1)][$parentnid]['border_spacing_H'];
19239 $parentwidth -= $br/2 +
$bl/2
19240 +
$c['padding']['L']
19241 +
$c['padding']['R'];
19244 else if ($this->simpleTables
){
19245 if ($this->table
[$lvl-1][$parentnid]['borders_separate']) {
19246 $parentwidth -= $this->table
[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19247 +
$this->table
[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']
19248 +
$c['padding']['L']
19249 +
$c['padding']['R']
19250 +
$this->table
[($lvl-1)][$parentnid]['border_spacing_H'];
19253 $parentwidth -= ($this->table
[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19254 +
$this->table
[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']) /2
19255 +
$c['padding']['L']
19256 +
$c['padding']['R'];
19259 if (isset($this->table
[$lvl][$nid]['wpercent']) && $this->table
[$lvl][$nid]['wpercent'] && $lvl>1) {
19260 $this->table
[$lvl][$nid]['w'] = $parentwidth;
19262 else if ($parentwidth > $this->table
[$lvl][$nid]['maw']) {
19263 $this->table
[$lvl][$nid]['w'] = $this->table
[$lvl][$nid]['maw'] ;
19266 $this->table
[$lvl][$nid]['w'] = $parentwidth;
19269 $this->_tableWidth($this->table
[$lvl][$nid]);
19273 // Starting at $this->innermostTableLevel
19274 // Cascade back up nested tables: setting heights back up the tree
19275 for($lvl=$this->innermostTableLevel
;$lvl>0;$lvl--) {
19276 for ($nid=1; $nid<=$this->tbctr
[$lvl]; $nid++
) {
19277 list($tableheight,$maxrowheight,$fullpage,$remainingpage, $maxfirstrowheight) = $this->_tableHeight($this->table
[$lvl][$nid]); }
19280 // RESIZING ALGORITHM
19282 if ($maxrowheight > $fullpage) { $recalculate
= $this
->tbsqrt($maxrowheight
/ $fullpage
, $iteration
); $iteration++
; }
19283 else if ($this->table_rotate
&& $tableheight > $remainingpage && !$added_page) {
19284 // If can fit on remainder of page whilst respecting autosize value..
19285 if (($this->shrin_k
* $this->tbsqrt($tableheight / $remainingpage, $iteration)) <= $this->shrink_this_table_to_fit
) {
19286 $recalculate = $this->tbsqrt($tableheight / $remainingpage, $iteration); $iteration++
;
19289 if (!$added_page) {
19290 $this->AddPage($this->CurOrientation
);
19291 $added_page = true;
19292 $this->kwt_moved
= true;
19293 $this->tbrot_maxw
= $this->h
- ($this->y +
$this->bMargin +
5) - $this->kwt_height
;
19295 // 0.001 to force it to recalculate
19296 $recalculate = (1 / $this->shrin_k
) +
0.001; // undo any shrink
19299 else if ($this->table_keep_together
|| ($this->table
[1][1]['nr']==1 && !$this->writingHTMLfooter
)) {
19300 if ($tableheight > $fullpage) {
19301 if (($this->shrin_k
* $this->tbsqrt($tableheight / $fullpage, $iteration)) <= $this->shrink_this_table_to_fit
) {
19302 $recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++
;
19304 else if ($this->tableMinSizePriority
) {
19305 $this->table_keep_together
= false;
19306 $recalculate = (1 / $this->shrin_k
) +
0.001;
19309 if (!$added_page && $this->y
!= $this->tMargin
) {
19310 $this->AddPage($this->CurOrientation
);
19311 $added_page = true;
19312 $this->kwt_moved
= true;
19313 $this->tbrot_maxw
= $this->h
- ($this->y +
$this->bMargin +
5) - $this->kwt_height
;
19315 $recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++
;
19318 else if ($tableheight > $remainingpage) {
19319 // If can fit on remainder of page whilst respecting autosize value..
19320 if (($this->shrin_k
* $this->tbsqrt($tableheight / $remainingpage, $iteration)) <= $this->shrink_this_table_to_fit
) {
19321 $recalculate = $this->tbsqrt($tableheight / $remainingpage, $iteration); $iteration++
;
19324 if (!$added_page) {
19325 $this->AddPage($this->CurOrientation
);
19326 $added_page = true;
19327 $this->kwt_moved
= true;
19328 $this->tbrot_maxw
= $this->h
- ($this->y +
$this->bMargin +
5) - $this->kwt_height
;
19331 //$recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
19332 $recalculate = (1 / $this->shrin_k
) +
0.001; // undo any shrink
19335 else { $recalculate
= 1; }
19337 else { $recalculate
= 1; }
19341 if ($maxfirstrowheight > $remainingpage && !$added_page && !$this->table_rotate
&& !$this->ColActive
&& !$this->table_keep_together
&& !$this->writingHTMLheader
&& !$this->writingHTMLfooter
) {
19342 $this->AddPage($this->CurOrientation
);
19343 $this->kwt_moved
= true;
19346 // keep-with-table: if page has advanced, print out buffer now, else done in fn. _Tablewrite()
19347 if ($this->kwt_saved
&& $this->kwt_moved
) {
19348 $this->printkwtbuffer();
19349 $this->kwt_moved
= false;
19350 $this->kwt_saved
= false;
19353 if ($this->progressBar
) { $this
->UpdateProgressBar(7,30,' '); } // *PROGRESS-BAR*
19354 // Recursively writes all tables starting at top level
19355 $this->_tableWrite($this->table
[1][1]);
19357 if ($this->table_rotate
&& $this->tablebuffer
) {
19358 $this->PageBreakTrigger
=$this->h
-$this->bMargin
;
19359 $save_tr = $this->table_rotate
;
19360 $save_y = $this->y
;
19361 $this->table_rotate
= 0;
19362 $this->y
= $this->tbrot_y0
;
19363 $h = $this->tbrot_w
;
19364 $this->DivLn($h,$this->blklvl
,true);
19366 $this->table_rotate
= $save_tr;
19367 $this->y
= $save_y;
19369 $this->printtablebuffer();
19371 $this->table_rotate
= 0;
19375 $this->x
= $this->lMargin +
$this->blk
[$this->blklvl
]['outer_left_margin'];
19377 $this->maxPosR
= max($this->maxPosR
, ($this->x +
$this->table
[1][1]['w']));
19379 $this->blockjustfinished
=true;
19380 $this->lastblockbottommargin
= $this->table
[1][1]['margin']['B'];
19383 if (isset($this->table
[1][1]['page_break_after'])) { $page_break_after
= $this
->table
[1][1]['page_break_after']; }
19384 else { $page_break_after
= ''; }
19387 $this->kwt
= false;
19390 $this->kwt_height
= 0;
19391 $this->kwt_buffer
= array();
19392 $this->kwt_Links
= array();
19393 $this->kwt_Annots
= array();
19394 $this->kwt_moved
= false;
19395 $this->kwt_saved
= false;
19397 $this->kwt_Reference
= array();
19398 $this->kwt_BMoutlines
= array();
19399 $this->kwt_toc
= array();
19401 $this->shrin_k
= 1;
19402 $this->shrink_this_table_to_fit
= 0;
19404 unset($this->table
);
19405 $this->table
=array(); //array
19406 $this->tableLevel
=0;
19407 $this->tbctr
=array();
19408 $this->innermostTableLevel
=0;
19409 $this->cssmgr
->tbCSSlvl
= 0;
19410 $this->cssmgr
->tablecascadeCSS
= array();
19412 unset($this->cell
);
19413 $this->cell
=array(); //array
19415 $this->col
=-1; //int
19416 $this->row
=-1; //int
19419 $this->cellPaddingL
= 0;
19420 $this->cellPaddingT
= 0;
19421 $this->cellPaddingR
= 0;
19422 $this->cellPaddingB
= 0;
19423 $this->cMarginL
= 0;
19424 $this->cMarginT
= 0;
19425 $this->cMarginR
= 0;
19426 $this->cMarginB
= 0;
19427 $this->default_font_size
= $this->original_default_font_size
;
19428 $this->default_font
= $this->original_default_font
;
19429 $this->SetFontSize($this->default_font_size
, false);
19430 $this->SetFont($this->default_font
,'',0,false);
19431 $this->SetLineHeight();
19432 if (isset($this->blk
[$this->blklvl
]['InlineProperties'])) { $this
->restoreInlineProperties($this
->blk
[$this
->blklvl
]['InlineProperties']);}
19433 if ($this->progressBar
) { $this
->UpdateProgressBar(7,100,' '); } // *PROGRESS-BAR*
19435 if ($page_break_after) {
19436 $save_blklvl = $this->blklvl
;
19437 $save_blk = $this->blk
;
19438 $save_silp = $this->saveInlineProperties();
19439 $save_spanlvl = $this->spanlvl
;
19440 $save_ilp = $this->InlineProperties
;
19441 if ($this->blklvl
>1) {
19442 // Close any open block tags
19443 for ($b= $this->blklvl
;$b>0;$b--) { $this
->CloseTag($this
->blk
[$b
]['tag']); }
19444 // Output any text left in buffer
19445 if (count($this->textbuffer
)) { $this
->printbuffer($this
->textbuffer
); $this
->textbuffer
=array(); }
19448 $save_cols = false;
19449 if ($this->ColActive
) {
19451 $save_nbcol = $this->NbCol
; // other values of gap and vAlign will not change by setting Columns off
19452 $this->SetColumns(0);
19454 /*-- END COLUMNS --*/
19455 if ($page_break_after == 'RIGHT') { $this
->AddPage($this
->CurOrientation
,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel
); }
19456 else if ($page_break_after == 'LEFT') { $this
->AddPage($this
->CurOrientation
,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel
); }
19457 else { $this
->AddPage($this
->CurOrientation
,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel
); }
19458 if (!$this->restoreBlockPagebreaks
) {
19460 $this->lastblocklevelchange
= 0;
19461 $this->blk
= array();
19462 $this->initialiseBlock($this->blk
[0]);
19463 $this->blk
[0]['width'] =& $this->pgwidth
;
19464 $this->blk
[0]['inner_width'] =& $this->pgwidth
;
19465 $this->blk
[0]['blockContext'] = $this->blockContext
;
19466 $properties = $this->cssmgr
->MergeCSS('BLOCK','BODY','');
19467 $this->setCSS($properties,'','BODY');
19473 $this->SetColumns($save_nbcol,$this->colvAlign
,$this->ColGap
);
19475 /*-- END COLUMNS --*/
19476 if ($this->restoreBlockPagebreaks
) {
19477 $this->blk
= $save_blk;
19478 // Re-open block tags
19479 $t = $this->blk
[0]['tag'];
19480 $a = $this->blk
[0]['attr'];
19482 for ($b=0; $b<=$save_blklvl;$b++
) {
19485 $t = $this->blk
[$b+
1]['tag'];
19486 $a = $this->blk
[$b+
1]['attr'];
19487 unset($this->blk
[$b+
1]);
19488 $this->OpenTag($tc,$ac);
19490 $this->spanlvl
= $save_spanlvl;
19491 $this->InlineProperties
= $save_ilp;
19492 $this->restoreInlineProperties($save_silp);
19497 /*-- END TABLES --*/
19500 // *********** LISTS ********************
19503 $this->lastoptionaltag
= '';
19504 unset($this->cssmgr
->listcascadeCSS
[$this->cssmgr
->listCSSlvl
]);
19505 $this->cssmgr
->listCSSlvl
--;
19506 if (isset($this->listoccur
[$this->listlvl
]) && isset($this->InlineProperties
['LIST'][$this->listlvl
][$this->listoccur
[$this->listlvl
]])) { $this
->restoreInlineProperties($this
->InlineProperties
['LIST'][$this
->listlvl
][$this
->listoccur
[$this
->listlvl
]]); }
19510 if(($tag=='UL') or ($tag=='OL')) {
19511 $this->ignorefollowingspaces
= true; //Eliminate exceeding left-side spaces
19512 unset($this->cssmgr
->listcascadeCSS
[$this->cssmgr
->listCSSlvl
]);
19513 $this->cssmgr
->listCSSlvl
--;
19515 $this->lastoptionaltag
= '';
19517 // A simple list for inside a table
19518 if($this->tableLevel
) {
19519 $this->listlist
[$this->listlvl
]['MAXNUM'] = $this->listnum
; //save previous lvl's maxnum
19520 unset($this->listlist
[$this->listlvl
]);
19522 if (isset($this->listlist
[$this->listlvl
]['MAXNUM'])) { $this
->listnum
= $this
->listlist
[$this
->listlvl
]['MAXNUM']; } // restore previous levels
19523 if ($this->listlvl
== 0) { $this
->listjustfinished
= true; }
19526 /*-- END TABLES --*/
19528 if ($this->listlvl
> 1) { // returning one level
19529 $this->listjustfinished
=true;
19530 if (!empty($this->textbuffer
)) {
19531 $this->listitem
[] = array($this->listlvl
,$this->listnum
,$this->textbuffer
,$this->listoccur
[$this->listlvl
],$this->listitemtype
);
19537 $this->textbuffer
= array();
19538 $occur = $this->listoccur
[$this->listlvl
];
19539 $this->listlist
[$this->listlvl
][$occur]['MAXNUM'] = $this->listnum
; //save previous lvl's maxnum
19541 $occur = $this->listoccur
[$this->listlvl
];
19542 $this->listnum
= $this->listlist
[$this->listlvl
][$occur]['MAXNUM']; // recover previous level's number
19543 $this->listtype
= $this->listlist
[$this->listlvl
][$occur]['TYPE']; // recover previous level's type
19544 if ($this->InlineProperties
['LIST'][$this->listlvl
][$occur]) { $this
->restoreInlineProperties($this
->InlineProperties
['LIST'][$this
->listlvl
][$occur
]); }
19547 else { // We are closing the last OL/UL tag
19548 if (!empty($this->textbuffer
)) {
19549 $this->listitem
[] = array($this->listlvl
,$this->listnum
,$this->textbuffer
,$this->listoccur
[$this->listlvl
],$this->listitemtype
);
19555 $occur = $this->listoccur
[$this->listlvl
];
19556 $this->listlist
[$this->listlvl
][$occur]['MAXNUM'] = $this->listnum
;
19557 $this->textbuffer
= array();
19560 $this->printlistbuffer();
19561 unset($this->InlineProperties
['LIST']);
19562 // SPACING AFTER LIST (Top level only)
19564 if ($this->list_margin_bottom
) {
19565 $this->DivLn($this->list_margin_bottom
,$this->blklvl
,true,1); // collapsible
19567 if (isset($this->blk
[$this->blklvl
]['InlineProperties'])) { $this
->restoreInlineProperties($this
->blk
[$this
->blklvl
]['InlineProperties']);}
19568 $this->listjustfinished
= true;
19569 $this->cssmgr
->listCSSlvl
= 0;
19570 $this->cssmgr
->listcascadeCSS
= array();
19571 $this->blockjustfinished
=true;
19572 $this->lastblockbottommargin
= $this->list_margin_bottom
;
19575 /*-- END LISTS --*/
19582 // This function determines the shrink factor when resizing tables
19583 // val is the table_height / page_height_available
19584 // returns a scaling factor used as $shrin_k to resize the table
19585 // Overcompensating will be quicker but may unnecessarily shrink table too much
19586 // Undercompensating means it will reiterate more times (taking more processing time)
19587 function tbsqrt($val, $iteration=3) {
19588 $k = 4; // Alters number of iterations until it returns $val itself - Must be > 2
19589 // Probably best guess and most accurate
19590 if ($iteration==1) return sqrt($val);
19591 // Faster than using sqrt (because it won't undercompensate), and gives reasonable results
19592 //return 1+(($val-1)/2);
19593 $x = 2-(($iteration-2)/($k-2));
19594 if ($x == 0) { $ret
= $val+
0.00001; }
19595 else if ($x < 0) { $ret
= 1 +
( pow(2, ($iteration
-2-$k
))/1000 ); }
19596 else { $ret
= 1+
(($val
-1)/$x
); }
19599 /*-- END TABLES --*/
19603 function printlistbuffer() {
19604 //Save x coordinate
19605 $x = $this->lMargin +
$this->blk
[$this->blklvl
]['outer_left_margin'];
19606 $this->cMarginL
= 0;
19607 $this->cMarginR
= 0;
19608 $currIndentLvl = -1;
19609 $lastIndent = array();
19610 $bak_page = $this->page
;
19612 foreach($this->listitem
as $item)
19615 $oldcolumn = $this->CurrCol
;
19617 $this->bulletarray
= array();
19618 //Get list's buffered data
19619 $this->listlvl
= $lvl = $item[0];
19621 $this->textbuffer
= $item[2];
19623 if ($item[4]) { $type
= $item
[4]; } // listitemtype
19624 else { $type
= $this
->listlist
[$lvl
][$occur
]['TYPE']; }
19625 $maxnum = $this->listlist
[$lvl][$occur]['MAXNUM'];
19626 $this->restoreInlineProperties($this->InlineProperties
['LIST'][$lvl][$occur]);
19627 $this->SetFont($this->FontFamily
,$this->FontStyle
,$this->FontSizePt
,true,true); // force to write
19628 $clh = $this->FontSize
;
19630 $this->SetLineHeight($this->FontSizePt
,$this->list_lineheight
[$lvl][$occur]);
19631 $this->listOcc
= $occur;
19632 $this->listnum
= $num;
19634 if (isset($this->list_align
[$this->listlvl
][$occur])) { $this
->divalign
= $this
->list_align
[$this
->listlvl
][$occur
]; }
19636 if (isset($this->blk
[$this->blklvl
]['direction']) && $this->blk
[$this->blklvl
]['direction']=='rtl') { $this
->divalign
= 'R'; }
19637 else { $this
->divalign
= 'L'; }
19640 // Set the bullet fontsize
19641 $bullfs = $this->InlineProperties
['LISTITEM'][$lvl][$occur][$num]['size'];
19643 $space_width = $this->GetCharWidth(' ',false) * 1.5;
19645 //Set default width & height values
19646 $this->divwidth
= $this->blk
[$this->blklvl
]['inner_width'];
19647 $this->divheight
= $this->lineheight
;
19648 $typefont = $this->FontFamily
;
19649 if (preg_match('/U\+([a-fA-F0-9]+)/i',$type,$m)) {
19650 if ($this->_charDefined($this->CurrentFont
['cw'],hexdec($m[1]))) { $list_item_marker
= codeHex2utf($m
[1]); }
19651 else { $list_item_marker
= '-'; }
19652 $blt_width = $this->GetStringWidth($list_item_marker);
19654 if (preg_match('/rgb\(.*?\)/',$type,$m)) {
19655 $list_item_color = $this->ConvertColor($m[0]);
19659 $list_item_color = false;
19661 switch($type) //Format type
19664 if ($this->listDir
== 'rtl') { $list_item_marker
= $this
->list_number_suffix
. $num
; }
19665 else { $list_item_marker
= $num
. $this
->list_number_suffix
; }
19666 $blt_width = $this->GetStringWidth(str_repeat('5',strlen($maxnum)).$this->list_number_suffix
);
19669 $list_item_marker = '';
19673 $anum = $this->dec2alpha($num,true);
19674 $maxnum = $this->dec2alpha($maxnum,true);
19675 if ($this->listDir
== 'rtl') { $list_item_marker
= $this
->list_number_suffix
. $anum
; }
19676 else { $list_item_marker
= $anum
. $this
->list_number_suffix
; }
19677 $blt_width = $this->GetStringWidth(str_repeat('W',strlen($maxnum)).$this->list_number_suffix
);
19680 $anum = $this->dec2alpha($num,false);
19681 $maxnum = $this->dec2alpha($maxnum,false);
19682 if ($this->listDir
== 'rtl') { $list_item_marker
= $this
->list_number_suffix
. $anum
; }
19683 else { $list_item_marker
= $anum
. $this
->list_number_suffix
; }
19684 $blt_width = $this->GetStringWidth(str_repeat('m',strlen($maxnum)).$this->list_number_suffix
);
19687 $anum = $this->dec2roman($num,true);
19688 if ($this->listDir
== 'rtl') { $list_item_marker
= $this
->list_number_suffix
. $anum
; }
19689 else { $list_item_marker
= $anum
. $this
->list_number_suffix
; }
19691 if ($maxnum>87) { $bbit
= 87; }
19692 else if ($maxnum>86) { $bbit
= 86; }
19693 else if ($maxnum>37) { $bbit
= 38; }
19694 else if ($maxnum>36) { $bbit
= 37; }
19695 else if ($maxnum>27) { $bbit
= 28; }
19696 else if ($maxnum>26) { $bbit
= 27; }
19697 else if ($maxnum>17) { $bbit
= 18; }
19698 else if ($maxnum>16) { $bbit
= 17; }
19699 else if ($maxnum>7) { $bbit
= 8; }
19700 else if ($maxnum>6) { $bbit
= 7; }
19701 else if ($maxnum>3) { $bbit
= 4; }
19702 else { $bbit
= $maxnum
; }
19703 $maxlnum = $this->dec2roman($bbit,true);
19704 $blt_width = $this->GetStringWidth($maxlnum.$this->list_number_suffix
);
19707 $anum = $this->dec2roman($num,false);
19708 if ($this->listDir
== 'rtl') { $list_item_marker
= $this
->list_number_suffix
. $anum
; }
19709 else { $list_item_marker
= $anum
. $this
->list_number_suffix
; }
19711 if ($maxnum>87) { $bbit
= 87; }
19712 else if ($maxnum>86) { $bbit
= 86; }
19713 else if ($maxnum>37) { $bbit
= 38; }
19714 else if ($maxnum>36) { $bbit
= 37; }
19715 else if ($maxnum>27) { $bbit
= 28; }
19716 else if ($maxnum>26) { $bbit
= 27; }
19717 else if ($maxnum>17) { $bbit
= 18; }
19718 else if ($maxnum>16) { $bbit
= 17; }
19719 else if ($maxnum>7) { $bbit
= 8; }
19720 else if ($maxnum>6) { $bbit
= 7; }
19721 else if ($maxnum>3) { $bbit
= 4; }
19722 else { $bbit
= $maxnum
; }
19723 $maxlnum = $this->dec2roman($bbit,false);
19725 $blt_width = $this->GetStringWidth($maxlnum.$this->list_number_suffix
);
19728 if ($this->PDFA
|| $this->PDFX
) {
19729 if ($this->_charDefined($this->CurrentFont
['cw'],8226)) { $list_item_marker
= "\xe2\x80\xa2"; } // •
19730 else { $list_item_marker
= '-'; }
19731 $blt_width = $this->GetCharWidth($list_item_marker);
19734 $list_item_marker = chr(108); // bullet disc in Zapfdingbats 'l'
19735 $typefont = 'czapfdingbats';
19736 $blt_width = (0.791 * $this->FontSize
/2.5);
19739 if ($this->PDFA
|| $this->PDFX
) {
19740 if ($this->_charDefined($this->CurrentFont
['cw'],9900)) { $list_item_marker
= "\xe2\x9a\xac"; } // ⚬
19741 else { $list_item_marker
= '-'; }
19742 $blt_width = $this->GetCharWidth($list_item_marker);
19745 $list_item_marker = chr(109); // circle in Zapfdingbats 'm'
19746 $typefont = 'czapfdingbats';
19747 $blt_width = (0.873 * $this->FontSize
/2.5);
19750 if ($this->PDFA
|| $this->PDFX
) {
19751 if ($this->_charDefined($this->CurrentFont
['cw'],9642)) { $list_item_marker
= "\xe2\x96\xaa"; } // ▪
19752 else { $list_item_marker
= '-'; }
19753 $blt_width = $this->GetCharWidth($list_item_marker);
19756 $list_item_marker = chr(110); //black square in Zapfdingbats font 'n'
19757 $typefont = 'czapfdingbats';
19758 $blt_width = (0.761 * $this->FontSize
/2.5);
19761 /* CSS3 list-styles numeric + I added tamil
19762 arabic-indic | bengali | cambodian | devanagari | gujarati | gurmukhi | kannada | khmer | lao | malayalam | mongolian | myanmar | oriya | persian | telugu | tibetan | thai | urdu
19764 case 'arabic-indic':
19766 $rnum = $this->dec2other($num, $cp);
19767 $list_item_marker = $this->list_number_suffix
. $rnum; // RTL
19768 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix
);
19773 $rnum = $this->dec2other($num, $cp);
19774 $list_item_marker = $this->list_number_suffix
. $rnum; // RTL
19775 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix
);
19779 $rnum = $this->dec2other($num, $cp);
19780 $list_item_marker = $rnum . $this->list_number_suffix
;
19781 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix
);
19785 $rnum = $this->dec2other($num, $cp);
19786 $list_item_marker = $rnum . $this->list_number_suffix
;
19787 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix
);
19791 $rnum = $this->dec2other($num, $cp);
19792 $list_item_marker = $rnum . $this->list_number_suffix
;
19793 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix
);
19797 $rnum = $this->dec2other($num, $cp);
19798 $list_item_marker = $rnum . $this->list_number_suffix
;
19799 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix
);
19803 $rnum = $this->dec2other($num, $cp);
19804 $list_item_marker = $rnum . $this->list_number_suffix
;
19805 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix
);
19809 $rnum = $this->dec2other($num, $cp);
19810 $list_item_marker = $rnum . $this->list_number_suffix
;
19811 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(6, $cp),strlen($maxnum)).$this->list_number_suffix
);
19815 $rnum = $this->dec2other($num, $cp);
19816 $list_item_marker = $rnum . $this->list_number_suffix
;
19817 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix
);
19821 $rnum = $this->dec2other($num, $cp);
19822 $list_item_marker = $rnum . $this->list_number_suffix
;
19823 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix
);
19827 $rnum = $this->dec2other($num, $cp);
19828 $list_item_marker = $rnum . $this->list_number_suffix
;
19829 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(9, $cp),strlen($maxnum)).$this->list_number_suffix
);
19833 $rnum = $this->dec2other($num, $cp);
19834 $list_item_marker = $rnum . $this->list_number_suffix
;
19835 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(5, $cp),strlen($maxnum)).$this->list_number_suffix
);
19838 if ($this->listDir
== 'rtl') { $list_item_marker
= $this
->list_number_suffix
. $num
; }
19839 else { $list_item_marker
= $num
. $this
->list_number_suffix
; }
19840 $blt_width = $this->GetStringWidth(str_repeat('5',strlen($maxnum)).$this->list_number_suffix
);
19845 if (isset($item[5]) && $item[5]) { $list_item_marker
= ''; }
19847 if ($currIndentLvl < $lvl) {
19848 if ($lvl > 1 || $this->list_indent_first_level
) {
19849 $indent +
= $this->list_indent
[$lvl][$occur];
19850 $lastIndent[$lvl] = $this->list_indent
[$lvl][$occur];
19853 else if ($currIndentLvl > $lvl) {
19854 while ($currIndentLvl > $lvl) {
19855 $indent -= $lastIndent[$currIndentLvl];
19859 $currIndentLvl = $lvl;
19864 if ($this->listDir
== 'rtl') {
19865 // list_align_style Determines alignment of numbers in numbered lists
19866 if ($this->list_align_style
== 'L') { $lalign
= 'R'; }
19867 else { $lalign
= 'L'; }
19868 $this->divwidth
= $this->blk
[$this->blklvl
]['width'] - ($indent +
$blt_width +
$space_width) ;
19869 $xb = $this->blk
[$this->blklvl
]['inner_width'] +
$this->blk
[$this->blklvl
]['border_left']['w'] +
$this->blk
[$this->blklvl
]['padding_left'] - $indent - $blt_width; //Bullet position (relative)
19871 $this->bulletarray
= array('w'=>$blt_width,'h'=>$clh,'txt'=>$list_item_marker,'x'=>$xb,'align'=>$lalign,'font'=>$typefont,'level'=>$lvl, 'occur'=>$occur, 'num'=>$num, 'fontsize'=>$bullfs, 'col'=>$list_item_color );
19877 if ($this->list_align_style
== 'L') { $lalign
= 'L'; }
19878 else { $lalign
= 'R'; }
19879 $this->divwidth
= $this->blk
[$this->blklvl
]['width'] - ($indent +
$blt_width +
$space_width) ;
19880 $xb = $this->blk
[$this->blklvl
]['padding_left'] +
$this->blk
[$this->blklvl
]['border_left']['w'] - $blt_width - $space_width;
19882 $this->bulletarray
= array('w'=>$blt_width,'h'=>$clh,'txt'=>$list_item_marker,'x'=>$xb,'align'=>$lalign,'font'=>$typefont,'level'=>$lvl, 'occur'=>$occur, 'num'=>$num, 'fontsize'=>$bullfs, 'col'=>$list_item_color );
19883 $this->x
= $x +
$indent +
$blt_width +
$space_width;
19887 $this->printbuffer($this->textbuffer
,'',false,true);
19888 $this->textbuffer
=array();
19890 // Added to correct for OddEven Margins
19891 if ($this->page
!= $bak_page) {
19892 if (($this->page
-$bak_page) %
2 == 1) {
19893 $x +
= $this->MarginCorrection
;
19895 $bak_page = $this->page
;
19898 // OR COLUMN CHANGE
19899 if ($this->CurrCol
!= $oldcolumn) {
19900 if ($this->directionality
== 'rtl') { // *RTL*
19901 $x -= ($this->CurrCol
- $oldcolumn) * ($this->ColWidth+
$this->ColGap
); // *RTL*
19904 $x +
= ($this->CurrCol
- $oldcolumn) * ($this->ColWidth+
$this->ColGap
);
19906 $oldcolumn = $this->CurrCol
;
19908 /*-- END COLUMNS --*/
19912 //Reset all used values
19913 $this->listoccur
= array();
19914 $this->listitem
= array();
19915 $this->listlist
= array();
19916 $this->listlvl
= 0;
19917 $this->listnum
= 0;
19918 $this->listtype
= '';
19919 $this->textbuffer
= array();
19920 $this->divwidth
= 0;
19921 $this->divheight
= 0;
19922 $this->x
= $this->lMargin +
$this->blk
[$this->blklvl
]['outer_left_margin'];
19924 /*-- END LISTS --*/
19926 function _saveTextBuffer($t, $link = '', $intlink = '') {
19927 // $this->textbuffer[] = array($t,$link,$this->currentfontstyle,$this->colorarray,$this->currentfontfamily,$this->SUP,$this->SUB,$intlink,$this->strike,$this->textparam,$this->spanbgcolorarray,$this->currentfontsize,$this->ReqFontStyle,$this->kerning,$this->lSpacingCSS,$this->wSpacingCSS,$this->spanborddet, $this->textshadow);
19931 if (isset($link) && $link) $arr[1] = $link;
19932 $arr[2] = $this->currentfontstyle
;
19933 if (isset($this->colorarray
) && $this->colorarray
) $arr[3] = $this->colorarray
;
19934 $arr[4] = $this->currentfontfamily
;
19935 if (isset($this->SUP
) && $this->SUP
) $arr[5] = $this->SUP
;
19936 if (isset($this->SUB
) && $this->SUB
) $arr[6] = $this->SUB
;
19937 if (isset($intlink) && $intlink) $arr[7] = $intlink;
19938 if (isset($this->strike
) && $this->strike
) $arr[8] = $this->strike
;
19939 if (isset($this->textparam
) && $this->textparam
) $arr[9] = $this->textparam
;
19940 if (isset($this->spanbgcolorarray
) && $this->spanbgcolorarray
) $arr[10] = $this->spanbgcolorarray
;
19941 $arr[11] = $this->currentfontsize
;
19942 if (isset($this->ReqFontStyle
) && $this->ReqFontStyle
) $arr[12] = $this->ReqFontStyle
;
19943 if (isset($this->kerning
) && $this->kerning
) $arr[13] = $this->kerning
;
19944 if (isset($this->lSpacingCSS
) && $this->lSpacingCSS
) $arr[14] = $this->lSpacingCSS
;
19945 if (isset($this->wSpacingCSS
) && $this->wSpacingCSS
) $arr[15] = $this->wSpacingCSS
;
19946 if (isset($this->spanborddet
) && $this->spanborddet
) $arr[16] = $this->spanborddet
;
19947 if (isset($this->textshadow
) && $this->textshadow
) $arr[17] = $this->textshadow
;
19948 $this->textbuffer
[] = $arr;
19951 function _saveCellTextBuffer($t, $link = '', $intlink = '') {
19952 // $this->cell[$this->row][$this->col]['textbuffer'][] = array($t,$link,$this->currentfontstyle,$this->colorarray,$this->currentfontfamily,$this->SUP,$this->SUB,$intlink,$this->strike,$this->textparam,$this->spanbgcolorarray,$this->currentfontsize,$this->ReqFontStyle,$this->kerning,$this->lSpacingCSS,$this->wSpacingCSS,$this->spanborddet, $this->textshadow);
19956 if (isset($link) && $link) $arr[1] = $link;
19957 $arr[2] = $this->currentfontstyle
;
19958 if (isset($this->colorarray
) && $this->colorarray
) $arr[3] = $this->colorarray
;
19959 $arr[4] = $this->currentfontfamily
;
19960 if (isset($this->SUP
) && $this->SUP
) $arr[5] = $this->SUP
;
19961 if (isset($this->SUB
) && $this->SUB
) $arr[6] = $this->SUB
;
19962 if (isset($intlink) && $intlink) $arr[7] = $intlink;
19963 if (isset($this->strike
) && $this->strike
) $arr[8] = $this->strike
;
19964 if (isset($this->textparam
) && $this->textparam
) $arr[9] = $this->textparam
;
19965 if (isset($this->spanbgcolorarray
) && $this->spanbgcolorarray
) $arr[10] = $this->spanbgcolorarray
;
19966 $arr[11] = $this->currentfontsize
;
19967 if (isset($this->ReqFontStyle
) && $this->ReqFontStyle
) $arr[12] = $this->ReqFontStyle
;
19968 if (isset($this->kerning
) && $this->kerning
) $arr[13] = $this->kerning
;
19969 if (isset($this->lSpacingCSS
) && $this->lSpacingCSS
) $arr[14] = $this->lSpacingCSS
;
19970 if (isset($this->wSpacingCSS
) && $this->wSpacingCSS
) $arr[15] = $this->wSpacingCSS
;
19971 if (isset($this->spanborddet
) && $this->spanborddet
) $arr[16] = $this->spanborddet
;
19972 if (isset($this->textshadow
) && $this->textshadow
) $arr[17] = $this->textshadow
;
19973 $this->cell
[$this->row
][$this->col
]['textbuffer'][] = $arr;
19977 function printbuffer($arrayaux,$blockstate=0,$is_table=false,$is_list=false)
19979 // $blockstate = 0; // NO margins/padding
19980 // $blockstate = 1; // Top margins/padding only
19981 // $blockstate = 2; // Bottom margins/padding only
19982 // $blockstate = 3; // Top & bottom margins/padding
19983 $this->spanbgcolorarray
= '';
19984 $this->spanbgcolor
= false;
19985 $this->spanborder
= false;
19986 $this->spanborddet
= array();
19987 $paint_ht_corr = 0;
19989 /*-- CSS-FLOAT --*/
19990 if (count($this->floatDivs
)) {
19991 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl
);
19992 if (($this->blk
[$this->blklvl
]['inner_width']-$l_width-$r_width) < (2*$this->GetCharWidth('W',false))) {
19993 // Too narrow to fit - try to move down past L or R float
19994 if ($l_max < $r_max && ($this->blk
[$this->blklvl
]['inner_width']-$r_width) > (2*$this->GetCharWidth('W',false))) {
19995 $this->ClearFloats('LEFT', $this->blklvl
);
19997 else if ($r_max < $l_max && ($this->blk
[$this->blklvl
]['inner_width']-$l_width) > (2*$this->GetCharWidth('W',false))) {
19998 $this->ClearFloats('RIGHT', $this->blklvl
);
20000 else { $this
->ClearFloats('BOTH', $this
->blklvl
); }
20003 /*-- END CSS-FLOAT --*/
20007 if (!$is_table && !$is_list) {
20008 if (isset($this->blk
[$this->blklvl
]['align']) && $this->blk
[$this->blklvl
]['align']) { $align
= $this
->blk
[$this
->blklvl
]['align']; }
20009 // Block-align is set by e.g. <.. align="center"> Takes priority for this block but not inherited
20010 if (isset($this->blk
[$this->blklvl
]['block-align']) && $this->blk
[$this->blklvl
]['block-align']) { $align
= $this
->blk
[$this
->blklvl
]['block-align']; }
20011 if (isset($this->blk
[$this->blklvl
]['direction'])) $blockdir = $this->blk
[$this->blklvl
]['direction'];
20012 else $blockdir = "";
20013 $this->divwidth
= $this->blk
[$this->blklvl
]['width'];
20016 $align = $this->divalign
;
20017 if ($is_table) { $blockdir
= $this
->table
[$this
->tableLevel
][$this
->tbctr
[$this
->tableLevel
]]['direction']; }
20018 else { $blockdir
= $this
->listDir
; }
20020 $oldpage = $this->page
;
20022 // ADDED for Out of Block now done as Flowing Block
20023 if ($this->divwidth
== 0) {
20024 $this->divwidth
= $this->pgwidth
;
20027 if (!$is_table && !$is_list) { $this
->SetLineHeight($this
->FontSizePt
,$this
->blk
[$this
->blklvl
]['line_height']); }
20028 $this->divheight
= $this->lineheight
;
20029 $old_height = $this->divheight
;
20031 // As a failsafe - if font has been set but not output to page
20032 $this->SetFont($this->default_font
,'',$this->default_font_size
,true,true); // force output to page
20034 $array_size = count($arrayaux);
20035 $this->newFlowingBlock( $this->divwidth
,$this->divheight
,$align,$is_table,$is_list,$blockstate,true,$blockdir);
20037 // Added - Otherwise <div><div><p> did not output top margins/padding for 1st/2nd div
20038 if ($array_size == 0) { $this
->finishFlowingBlock(true); } // true = END of flowing block
20040 for($i=0;$i < $array_size; $i++
)
20043 $oldcolumn = $this->CurrCol
;
20045 $vetor = $arrayaux[$i];
20046 if ($i == 0 and $vetor[0] != "\n" and !$this->ispre
) {
20047 $vetor[0] = ltrim($vetor[0]);
20050 // FIXED TO ALLOW IT TO SHOW '0'
20051 if (empty($vetor[0]) && !($vetor[0]==='0') && empty($vetor[7])) { //Ignore empty text and not carrying an internal link
20052 //Check if it is the last element. If so then finish printing the block
20053 if ($i == ($array_size-1)) { $this
->finishFlowingBlock(true); } // true = END of flowing block
20058 //Activating buffer properties
20059 if(isset($vetor[11]) and $vetor[11] != '') { // Font Size
20060 if ($is_table && $this->shrin_k
) {
20061 $this->SetFontSize($vetor[11]/$this->shrin_k
,false);
20064 $this->SetFontSize($vetor[11],false);
20068 if(isset($vetor[17]) && !empty($vetor[17])) { //TextShadow
20069 $this->textshadow
= $vetor[17];
20071 if(isset($vetor[16]) && !empty($vetor[16])) { //Border
20072 $this->spanborddet
= $vetor[16];
20073 $this->spanborder
= true;
20076 if(isset($vetor[15])) { // Word spacing
20077 $this->wSpacingCSS
= $vetor[15];
20078 if ($this->wSpacingCSS
&& strtoupper($this->wSpacingCSS
) != 'NORMAL') {
20079 $this->minwSpacing
= $this->ConvertSize($this->wSpacingCSS
,$this->FontSize
);
20082 if(isset($vetor[14])) { // Letter spacing
20083 $this->lSpacingCSS
= $vetor[14];
20084 if (($this->lSpacingCSS
|| $this->lSpacingCSS
==='0') && strtoupper($this->lSpacingCSS
) != 'NORMAL') {
20085 $this->fixedlSpacing
= $this->ConvertSize($this->lSpacingCSS
,$this->FontSize
);
20088 if(isset($vetor[13])) { // Font Kerning
20089 $this->kerning
= $vetor[13];
20093 if(isset($vetor[10]) and !empty($vetor[10])) //Background color
20095 $this->spanbgcolorarray
= $vetor[10];
20096 $this->spanbgcolor
= true;
20098 if(isset($vetor[9]) and !empty($vetor[9])) // Text parameters - Outline + hyphens
20100 $this->textparam
= $vetor[9] ; // mPDF 5.6.14
20101 $this->SetTextOutline($this->textparam
); // mPDF 5.6.07
20103 if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text
20105 $this->strike
= true;
20107 if(isset($vetor[7]) and $vetor[7] != '') // internal target: <a name="anyvalue">
20110 if ($this->keep_block_together
) { $this
->internallink
[$vetor
[7]] = array("Y"=>$ily
,"PAGE"=>$this
->page
, "kt"=>true ); }
20111 else if ($this->table_rotate
) { $this
->internallink
[$vetor
[7]] = array("Y"=>$ily
,"PAGE"=>$this
->page
, "tbrot"=>true ); }
20112 else if ($this->kwt
) { $this
->internallink
[$vetor
[7]] = array("Y"=>$ily
,"PAGE"=>$this
->page
, "kwt"=>true ); }
20113 else if ($this->ColActive
) { $this
->internallink
[$vetor
[7]] = array("Y"=>$ily
,"PAGE"=>$this
->page
, "col"=>$this
->CurrCol
); }
20115 $this->internallink
[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page
);
20116 if (empty($vetor[0])) { //Ignore empty text
20117 //Check if it is the last element. If so then finish printing the block
20118 if ($i == ($array_size-1)) { $this
->finishFlowingBlock(true); } // true = END of flowing block
20122 if(isset($vetor[6]) and $vetor[6] === true) // Subscript
20126 if(isset($vetor[5]) and $vetor[5] === true) // Superscript
20130 if(isset($vetor[4]) and $vetor[4] != '') { // Font Family
20131 $font = $this->SetFont($vetor[4],$this->FontStyle
,0,false);
20133 if (!empty($vetor[3])) //Font Color
20136 $this->SetTColor($cor);
20138 if(isset($vetor[2]) and $vetor[2] != '') //Bold,Italic,Underline styles
20140 $this->SetStyles($vetor[2]);
20143 if(isset($vetor[12]) and $vetor[12] != '') { //Requested Bold,Italic,Underline
20144 $this->ReqFontStyle
= $vetor[12];
20146 if(isset($vetor[1]) and $vetor[1] != '') //LINK
20148 if (strpos($vetor[1],".") === false && strpos($vetor[1],"@") !== 0) //assuming every external link has a dot indicating extension (e.g: .html .txt .zip www.somewhere.com etc.)
20150 //Repeated reference to same anchor?
20151 while(array_key_exists($vetor[1],$this->internallink
)) $vetor[1]="#".$vetor[1];
20152 $this->internallink
[$vetor[1]] = $this->AddLink();
20153 $vetor[1] = $this->internallink
[$vetor[1]];
20155 $this->HREF
= $vetor[1]; // HREF link style set here ******
20158 // SPECIAL CONTENT - IMAGES & FORM OBJECTS
20159 //Print-out special content
20161 if (substr($vetor[0],0,3) == "\xbb\xa4\xac") { //identifier has been identified!
20163 $objattr = $this->_getObjAttr($vetor[0]);
20166 if ($objattr['type'] == 'nestedtable') {
20167 if ($objattr['nestedcontent']) {
20168 $level = $objattr['level'];
20169 $table = &$this->table
[$level][$objattr['table']];
20170 if ($this->cacheTables
) {
20171 $fh = fopen($table['cache'], "r+b");
20172 $cell = $this->_uncacheCell($table['cells'][$objattr['row']][$objattr['col']], '', $fh);
20176 $cell = &$table['cells'][$objattr['row']][$objattr['col']];
20178 $this->finishFlowingBlock(false,'nestedtable');
20179 $save_dw = $this->divwidth
;
20180 $save_buffer = $this->cellBorderBuffer
;
20181 $this->cellBorderBuffer
= array();
20183 list($dummyx,$w) = $this->_tableGetWidth($table, $objattr['row'], $objattr['col'], $fh);
20184 $ntw = $this->table
[($level+
1)][$objattr['nestedcontent']]['w']; // nested table width
20185 if (!$this->simpleTables
){
20186 if ($this->packTableData
) {
20187 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cell['borderbin']);
20190 $br = $cell['border_details']['R']['w'];
20191 $bl = $cell['border_details']['L']['w'];
20193 if ($table['borders_separate']) {
20194 $innerw = $w - $bl - $br - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
20197 $innerw = $w - $bl/2 - $br/2 - $cell['padding']['L'] - $cell['padding']['R'];
20200 else if ($this->simpleTables
){
20201 if ($table['borders_separate']) {
20202 $innerw = $w - $table['simple']['border_details']['L']['w'] - $table['simple']['border_details']['R']['w'] - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
20205 $innerw = $w - $table['simple']['border_details']['L']['w']/2 - $table['simple']['border_details']['R']['w']/2 - $cell['padding']['L'] - $cell['padding']['R'];
20208 if ($cell['a']=='C' || $this->table
[($level+
1)][$objattr['nestedcontent']]['a']=='C') {
20209 $ncx +
= ($innerw-$ntw)/2;
20211 elseif ($cell['a']=='R' || $this->table
[($level+
1)][$objattr['nestedcontent']]['a']=='R') {
20212 $ncx +
= $innerw- $ntw;
20215 if ($this->cacheTables
) { fclose($fh
); }
20217 $this->_tableWrite($this->table
[($level+
1)][$objattr['nestedcontent']]);
20218 $this->cellBorderBuffer
= $save_buffer;
20219 $this->x
= $bak_x ;
20220 $this->divwidth
= $save_dw;
20221 $this->newFlowingBlock( $this->divwidth
,$this->divheight
,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20225 /*-- END TABLES --*/
20226 if ($is_table) { // *TABLES*
20227 $maxWidth = $this->divwidth
; // *TABLES*
20230 $maxWidth = $this->divwidth
- ($this->blk
[$this->blklvl
]['padding_left'] +
$this->blk
[$this->blklvl
]['border_left']['w'] +
$this->blk
[$this->blklvl
]['padding_right'] +
$this->blk
[$this->blklvl
]['border_right']['w']);
20233 /*-- CSS-IMAGE-FLOAT --*/
20234 // If float (already) exists at this level
20235 if (isset($this->floatmargins
['R']) && $this->y
<= $this->floatmargins
['R']['y1'] && $this->y
>= $this->floatmargins
['R']['y0']) { $maxWidth
-= $this
->floatmargins
['R']['w']; }
20236 if (isset($this->floatmargins
['L']) && $this->y
<= $this->floatmargins
['L']['y1'] && $this->y
>= $this->floatmargins
['L']['y0']) { $maxWidth
-= $this
->floatmargins
['L']['w']; }
20237 /*-- END CSS-IMAGE-FLOAT --*/
20239 list($skipln) = $this->inlineObject($objattr['type'], '', $this->y
, $objattr,$this->lMargin
, ($this->flowingBlockAttr
['contentWidth']/_MPDFK
), $maxWidth, $this->flowingBlockAttr
['height'], false, $is_table);
20240 // 1 -> New line needed because of width
20241 // -1 -> Will fit width on line but NEW PAGE REQUIRED because of height
20242 // -2 -> Will not fit on line therefore needs new line but thus NEW PAGE REQUIRED
20244 $oldpage = $this->page
;
20245 $oldcol = $this->CurrCol
;
20246 if (($skipln == 1 || $skipln == -2) && !isset($objattr['float'])) {
20247 $this->finishFlowingBlock(false,$objattr['type']);
20248 $this->newFlowingBlock( $this->divwidth
,$this->divheight
,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20250 $thispage = $this->page
;
20251 if ($this->CurrCol
!=$oldcol) { $changedcol
= true; }
20252 else { $changedcol
=false; }
20254 // the previous lines can already have triggered page break or column change
20255 if (!$changedcol && $skipln <0 && $this->AcceptPageBreak() && $thispage==$oldpage) {
20257 $this->AddPage($this->CurOrientation
);
20259 // Added to correct Images already set on line before page advanced
20260 // i.e. if second inline image on line is higher than first and forces new page
20261 if (count($this->objectbuffer
)) {
20262 $yadj = $iby - $this->y
;
20263 foreach($this->objectbuffer
AS $ib=>$val) {
20264 if ($this->objectbuffer
[$ib]['OUTER-Y'] ) $this->objectbuffer
[$ib]['OUTER-Y'] -= $yadj;
20265 if ($this->objectbuffer
[$ib]['BORDER-Y']) $this->objectbuffer
[$ib]['BORDER-Y'] -= $yadj;
20266 if ($this->objectbuffer
[$ib]['INNER-Y']) $this->objectbuffer
[$ib]['INNER-Y'] -= $yadj;
20271 // Added to correct for OddEven Margins
20272 if ($this->page
!= $oldpage) {
20273 if (($this->page
-$oldpage) %
2 == 1) {
20274 $bak_x +
= $this->MarginCorrection
;
20276 $oldpage = $this->page
;
20277 $y = $this->tMargin
- $paint_ht_corr ;
20278 $this->oldy
= $this->tMargin
- $paint_ht_corr ;
20284 // OR COLUMN CHANGE
20285 if ($this->CurrCol
!= $oldcolumn) {
20286 if ($this->directionality
== 'rtl') { // *RTL*
20287 $bak_x -= ($this->CurrCol
- $oldcolumn) * ($this->ColWidth+
$this->ColGap
); // *RTL*
20290 $bak_x +
= ($this->CurrCol
- $oldcolumn) * ($this->ColWidth+
$this->ColGap
);
20293 $oldcolumn = $this->CurrCol
;
20294 $y = $this->y0
- $paint_ht_corr ;
20295 $this->oldy
= $this->y0
- $paint_ht_corr ;
20298 /*-- END COLUMNS --*/
20300 /*-- CSS-IMAGE-FLOAT --*/
20301 if ($objattr['type'] == 'image' && isset($objattr['float'])) {
20304 // DIV TOP MARGIN/BORDER/PADDING
20305 if ($this->flowingBlockAttr
['newblock'] && ($this->flowingBlockAttr
['blockstate']==1 || $this->flowingBlockAttr
['blockstate']==3) && $this->flowingBlockAttr
['lineCount']== 0) {
20306 $fy +
= $this->blk
[$this->blklvl
]['margin_top'] +
$this->blk
[$this->blklvl
]['padding_top'] +
$this->blk
[$this->blklvl
]['border_top']['w'];
20309 if ($objattr['float']=='R') {
20310 $fx = $this->w
- $this->rMargin
- $objattr['width'] - ($this->blk
[$this->blklvl
]['outer_right_margin'] +
$this->blk
[$this->blklvl
]['border_right']['w'] +
$this->blk
[$this->blklvl
]['padding_right']);
20314 else if ($objattr['float']=='L') {
20315 $fx = $this->lMargin +
($this->blk
[$this->blklvl
]['outer_left_margin'] +
$this->blk
[$this->blklvl
]['border_left']['w'] +
$this->blk
[$this->blklvl
]['padding_left']);
20317 $w = $objattr['width'];
20318 $h = abs($objattr['height']);
20320 $widthLeft = $maxWidth - ($this->flowingBlockAttr
['contentWidth']/_MPDFK
);
20321 $maxHeight = $this->h
- ($this->tMargin +
$this->margin_header +
$this->bMargin +
10) ;
20323 $extraWidth = ($objattr['border_left']['w'] +
$objattr['border_right']['w'] +
$objattr['margin_left']+
$objattr['margin_right']);
20324 $extraHeight = ($objattr['border_top']['w'] +
$objattr['border_bottom']['w'] +
$objattr['margin_top']+
$objattr['margin_bottom']);
20326 if ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg') {
20327 $file = $objattr['file'];
20328 $info=$this->formobjects
[$file];
20331 $file = $objattr['file'];
20332 $info=$this->images
[$file];
20334 $img_w = $w - $extraWidth ;
20335 $img_h = $h - $extraHeight ;
20336 if ($objattr['border_left']['w']) {
20337 $objattr['BORDER-WIDTH'] = $img_w +
(($objattr['border_left']['w'] +
$objattr['border_right']['w'])/2) ;
20338 $objattr['BORDER-HEIGHT'] = $img_h +
(($objattr['border_top']['w'] +
$objattr['border_bottom']['w'])/2) ;
20339 $objattr['BORDER-X'] = $fx +
$objattr['margin_left'] +
(($objattr['border_left']['w'])/2) ;
20340 $objattr['BORDER-Y'] = $fy +
$objattr['margin_top'] +
(($objattr['border_top']['w'])/2) ;
20342 $objattr['INNER-WIDTH'] = $img_w;
20343 $objattr['INNER-HEIGHT'] = $img_h;
20344 $objattr['INNER-X'] = $fx +
$objattr['margin_left'] +
($objattr['border_left']['w']);
20345 $objattr['INNER-Y'] = $fy +
$objattr['margin_top'] +
($objattr['border_top']['w']) ;
20346 $objattr['ID'] = $info['i'];
20347 $objattr['OUTER-WIDTH'] = $w;
20348 $objattr['OUTER-HEIGHT'] = $h;
20349 $objattr['OUTER-X'] = $fx;
20350 $objattr['OUTER-Y'] = $fy;
20351 if ($objattr['float']=='R') {
20352 // If R float already exists at this level
20353 $this->floatmargins
['R']['skipline'] = false;
20354 if (isset($this->floatmargins
['R']['y1']) && $this->floatmargins
['R']['y1'] > 0 && $fy < $this->floatmargins
['R']['y1']) {
20355 $this->WriteFlowingBlock($vetor[0]);
20357 // If L float already exists at this level
20358 else if (isset($this->floatmargins
['L']['y1']) && $this->floatmargins
['L']['y1'] > 0 && $fy < $this->floatmargins
['L']['y1']) {
20359 // Final check distance between floats is not now too narrow to fit text
20360 $mw = 2*$this->GetCharWidth('W',false);
20361 if (($this->blk
[$this->blklvl
]['inner_width'] - $w - $this->floatmargins
['L']['w']) < $mw) {
20362 $this->WriteFlowingBlock($vetor[0]);
20365 $this->floatmargins
['R']['x'] = $fx;
20366 $this->floatmargins
['R']['w'] = $w;
20367 $this->floatmargins
['R']['y0'] = $fy;
20368 $this->floatmargins
['R']['y1'] = $fy +
$h;
20369 if ($skipln == 1) {
20370 $this->floatmargins
['R']['skipline'] = true;
20371 $this->floatmargins
['R']['id'] = count($this->floatbuffer
)+
0;
20372 $objattr['skipline'] = true;
20374 $this->floatbuffer
[] = $objattr;
20378 $this->floatmargins
['R']['x'] = $fx;
20379 $this->floatmargins
['R']['w'] = $w;
20380 $this->floatmargins
['R']['y0'] = $fy;
20381 $this->floatmargins
['R']['y1'] = $fy +
$h;
20382 if ($skipln == 1) {
20383 $this->floatmargins
['R']['skipline'] = true;
20384 $this->floatmargins
['R']['id'] = count($this->floatbuffer
)+
0;
20385 $objattr['skipline'] = true;
20387 $this->floatbuffer
[] = $objattr;
20390 else if ($objattr['float']=='L') {
20391 // If L float already exists at this level
20392 $this->floatmargins
['L']['skipline'] = false;
20393 if (isset($this->floatmargins
['L']['y1']) && $this->floatmargins
['L']['y1'] > 0 && $fy < $this->floatmargins
['L']['y1']) {
20394 $this->floatmargins
['L']['skipline'] = false;
20395 $this->WriteFlowingBlock($vetor[0]);
20397 // If R float already exists at this level
20398 else if (isset($this->floatmargins
['R']['y1']) && $this->floatmargins
['R']['y1'] > 0 && $fy < $this->floatmargins
['R']['y1']) {
20399 // Final check distance between floats is not now too narrow to fit text
20400 $mw = 2*$this->GetCharWidth('W',false);
20401 if (($this->blk
[$this->blklvl
]['inner_width'] - $w - $this->floatmargins
['R']['w']) < $mw) {
20402 $this->WriteFlowingBlock($vetor[0]);
20405 $this->floatmargins
['L']['x'] = $fx +
$w;
20406 $this->floatmargins
['L']['w'] = $w;
20407 $this->floatmargins
['L']['y0'] = $fy;
20408 $this->floatmargins
['L']['y1'] = $fy +
$h;
20409 if ($skipln == 1) {
20410 $this->floatmargins
['L']['skipline'] = true;
20411 $this->floatmargins
['L']['id'] = count($this->floatbuffer
)+
0;
20412 $objattr['skipline'] = true;
20414 $this->floatbuffer
[] = $objattr;
20418 $this->floatmargins
['L']['x'] = $fx +
$w;
20419 $this->floatmargins
['L']['w'] = $w;
20420 $this->floatmargins
['L']['y0'] = $fy;
20421 $this->floatmargins
['L']['y1'] = $fy +
$h;
20422 if ($skipln == 1) {
20423 $this->floatmargins
['L']['skipline'] = true;
20424 $this->floatmargins
['L']['id'] = count($this->floatbuffer
)+
0;
20425 $objattr['skipline'] = true;
20427 $this->floatbuffer
[] = $objattr;
20432 /*-- END CSS-IMAGE-FLOAT --*/
20433 $this->WriteFlowingBlock($vetor[0]);
20434 /*-- CSS-IMAGE-FLOAT --*/
20436 /*-- END CSS-IMAGE-FLOAT --*/
20439 } // END If special content
20441 if ($this->tableLevel
) { $paint_ht_corr
= 0; } // To move the y up when new column/page started if div border needed
20442 else { $paint_ht_corr
= $this
->blk
[$this
->blklvl
]['border_top']['w']; }
20444 if ($vetor[0] == "\n") { //We are reading a <BR> now turned into newline ("\n")
20445 if ($this->flowingBlockAttr
['content']) {
20446 $this->finishFlowingBlock(false,'br');
20448 else if ($is_table) {
20449 $this->y+
= $this->_computeLineheight($this->table_lineheight
);
20451 else if (!$is_table) {
20452 $this->DivLn($this->lineheight
);
20453 if ($this->ColActive
) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
20455 // Added to correct for OddEven Margins
20456 if ($this->page
!= $oldpage) {
20457 if (($this->page
-$oldpage) %
2 == 1) {
20458 $bak_x +
= $this->MarginCorrection
;
20460 $oldpage = $this->page
;
20461 $y = $this->tMargin
- $paint_ht_corr ;
20462 $this->oldy
= $this->tMargin
- $paint_ht_corr ;
20468 // OR COLUMN CHANGE
20469 if ($this->CurrCol
!= $oldcolumn) {
20470 if ($this->directionality
== 'rtl') { // *RTL*
20471 $bak_x -= ($this->CurrCol
- $oldcolumn) * ($this->ColWidth+
$this->ColGap
); // *RTL*
20474 $bak_x +
= ($this->CurrCol
- $oldcolumn) * ($this->ColWidth+
$this->ColGap
);
20477 $oldcolumn = $this->CurrCol
;
20478 $y = $this->y0
- $paint_ht_corr ;
20479 $this->oldy
= $this->y0
- $paint_ht_corr ;
20482 /*-- END COLUMNS --*/
20483 $this->newFlowingBlock( $this->divwidth
,$this->divheight
,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20486 $this->WriteFlowingBlock( $vetor[0]);
20488 // Added to correct for OddEven Margins
20489 if ($this->page
!= $oldpage) {
20490 if (($this->page
-$oldpage) %
2 == 1) {
20491 $bak_x +
= $this->MarginCorrection
;
20494 $oldpage = $this->page
;
20495 $y = $this->tMargin
- $paint_ht_corr ;
20496 $this->oldy
= $this->tMargin
- $paint_ht_corr ;
20501 // OR COLUMN CHANGE
20502 if ($this->CurrCol
!= $oldcolumn) {
20503 if ($this->directionality
== 'rtl') { // *RTL*
20504 $bak_x -= ($this->CurrCol
- $oldcolumn) * ($this->ColWidth+
$this->ColGap
); // *RTL*
20507 $bak_x +
= ($this->CurrCol
- $oldcolumn) * ($this->ColWidth+
$this->ColGap
);
20510 $oldcolumn = $this->CurrCol
;
20511 $y = $this->y0
- $paint_ht_corr ;
20512 $this->oldy
= $this->y0
- $paint_ht_corr ;
20515 /*-- END COLUMNS --*/
20521 //Check if it is the last element. If so then finish printing the block
20522 if ($i == ($array_size-1)) {
20523 $this->finishFlowingBlock(true); // true = END of flowing block
20524 // Added to correct for OddEven Margins
20525 if ($this->page
!= $oldpage) {
20526 if (($this->page
-$oldpage) %
2 == 1) {
20527 $bak_x +
= $this->MarginCorrection
;
20530 $oldpage = $this->page
;
20531 $y = $this->tMargin
- $paint_ht_corr ;
20532 $this->oldy
= $this->tMargin
- $paint_ht_corr ;
20538 // OR COLUMN CHANGE
20539 if ($this->CurrCol
!= $oldcolumn) {
20540 if ($this->directionality
== 'rtl') { // *RTL*
20541 $bak_x -= ($this->CurrCol
- $oldcolumn) * ($this->ColWidth+
$this->ColGap
); // *RTL*
20544 $bak_x +
= ($this->CurrCol
- $oldcolumn) * ($this->ColWidth+
$this->ColGap
);
20547 $oldcolumn = $this->CurrCol
;
20548 $y = $this->y0
- $paint_ht_corr ;
20549 $this->oldy
= $this->y0
- $paint_ht_corr ;
20552 /*-- END COLUMNS --*/
20556 // RESETTING VALUES
20557 $this->SetTColor($this->ConvertColor(0));
20558 $this->SetDColor($this->ConvertColor(0));
20559 $this->SetFColor($this->ConvertColor(255));
20560 $this->colorarray
= '';
20561 $this->spanbgcolorarray
= '';
20562 $this->spanbgcolor
= false;
20563 $this->spanborder
= false;
20564 $this->spanborddet
= array();
20566 $this->textparam
= array();
20567 $this->SetTextOutline();
20568 $this->SUP
= false;
20569 $this->SUB
= false;
20571 $this->strike
= false;
20572 $this->textshadow
= '';
20574 $this->currentfontfamily
= '';
20575 $this->currentfontsize
= '';
20576 $this->currentfontstyle
= '';
20578 if ($this->tableLevel
) {
20579 $this->SetLineHeight('',$this->table_lineheight
); // *TABLES*
20582 /*-- END TABLES --*/
20584 if ($is_list && $this->list_lineheight
[$this->listlvl
][$this->listOcc
]) {
20585 $this->SetLineHeight('',$this->list_lineheight
[$this->listlvl
][$this->listOcc
]); // sets default line height
20588 /*-- END LISTS --*/
20589 if (isset($this->blk
[$this->blklvl
]['line_height']) && $this->blk
[$this->blklvl
]['line_height']) {
20590 $this->SetLineHeight('',$this->blk
[$this->blklvl
]['line_height']); // sets default line height
20592 $this->ResetStyles();
20593 $this->toupper
= false;
20594 $this->tolower
= false;
20595 $this->capitalize
= false;
20596 $this->kerning
= false;
20597 $this->lSpacingCSS
= '';
20598 $this->wSpacingCSS
= '';
20599 $this->fixedlSpacing
= false;
20600 $this->minwSpacing
= 0;
20602 $this->dash_on
= false;
20603 $this->dotted_on
= false;
20605 }//end of for(i=0;i<arraysize;i++)
20608 // PAINT DIV BORDER // DISABLED IN COLUMNS AS DOESN'T WORK WHEN BROKEN ACROSS COLS??
20609 if ((isset($this->blk
[$this->blklvl
]['border']) || isset($this->blk
[$this->blklvl
]['bgcolor']) || isset($this->blk
[$this->blklvl
]['box_shadow'])) && $blockstate && ($this->y
!= $this->oldy
)) {
20610 $bottom_y = $this->y
; // Does not include Bottom Margin
20611 if (isset($this->blk
[$this->blklvl
]['startpage']) && $this->blk
[$this->blklvl
]['startpage'] != $this->page
&& $blockstate != 1) {
20612 $this->PaintDivBB('pagetop',$blockstate);
20615 else if ($blockstate != 1) {
20616 $this->PaintDivBB('',$blockstate);
20618 $this->y
= $bottom_y;
20623 $this->SetFontSize($this->default_font_size
,false);
20628 function _setDashBorder($style, $div, $cp, $side) {
20629 if ($style == 'dashed' && (($side=='L' || $side=='R') || ($side=='T' && $div != 'pagetop' && !$cp) || ($side=='B' && $div!='pagebottom') )) {
20630 $dashsize = 2; // final dash will be this + 1*linewidth
20631 $dashsizek = 1.5; // ratio of Dash/Blank
20632 $this->SetDash($dashsize,($dashsize/$dashsizek)+
($this->LineWidth
*2));
20634 else if ($style == 'dotted' || ($side=='T' && ($div == 'pagetop' || $cp)) || ($side=='B' && $div == 'pagebottom')) {
20635 //Round join and cap
20636 $this->SetLineJoin(1);
20637 $this->SetLineCap(1);
20638 $this->SetDash(0.001,($this->LineWidth
*3));
20642 function _setBorderLine($b, $k=1) {
20643 $this->SetLineWidth($b['w']/$k);
20644 $this->SetDColor($b['c']);
20645 if ($b['c'][0]==5) { // RGBa
20646 $this->SetAlpha($b['c'][4], 'Normal', false, 'S')."\n";
20648 else if ($b['c'][0]==6) { // CMYKa
20649 $this->SetAlpha($b['c'][5], 'Normal', false, 'S')."\n";
20654 function PaintDivBB($divider='',$blockstate=0,$blvl=0) {
20655 // Borders & backgrounds are done elsewhere for columns - messes up the repositioning in printcolumnbuffer
20656 if ($this->ColActive
) { return ; } // *COLUMNS*
20657 $save_y = $this->y
;
20658 if (!$blvl) { $blvl
= $this
->blklvl
; }
20659 $x0 = $x1 = $y0 = $y1 = 0;
20661 // Added mPDF 3.0 Float DIV
20662 if (isset($this->blk
[$blvl]['bb_painted'][$this->page
]) && $this->blk
[$blvl]['bb_painted'][$this->page
]) { return; } // *CSS-FLOAT*
20664 if (isset($this->blk
[$blvl]['x0'])) { $x0
= $this
->blk
[$blvl
]['x0']; } // left
20665 if (isset($this->blk
[$blvl]['y1'])) { $y1
= $this
->blk
[$blvl
]['y1']; } // bottom
20667 // Added mPDF 3.0 Float DIV - ensures backgrounds/borders are drawn to bottom of page
20669 if ($divider=='pagebottom') { $y1
= $this
->h
-$this
->bMargin
; }
20670 else { $y1
= $this
->y
; }
20673 if (isset($this->blk
[$blvl]['startpage']) && $this->blk
[$blvl]['startpage'] != $this->page
) { $continuingpage
= true; } else { $continuingpage
= false; }
20675 if (isset($this->blk
[$blvl]['y0'])) { $y0
= $this
->blk
[$blvl
]['y0']; }
20677 $w = $this->blk
[$blvl]['width'];
20680 // Set border-widths as used here
20681 $border_top = $this->blk
[$blvl]['border_top']['w'];
20682 $border_bottom = $this->blk
[$blvl]['border_bottom']['w'];
20683 $border_left = $this->blk
[$blvl]['border_left']['w'];
20684 $border_right = $this->blk
[$blvl]['border_right']['w'];
20685 if (!$this->blk
[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
20688 if (!$this->blk
[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') {
20689 $border_bottom = 0;
20702 /*-- BORDER-RADIUS --*/
20703 if (isset($this->blk
[$blvl]['border_radius_TL_H'])) { $brTL_H
= $this
->blk
[$blvl
]['border_radius_TL_H']; $brset
= true; }
20704 if (isset($this->blk
[$blvl]['border_radius_TL_V'])) { $brTL_V
= $this
->blk
[$blvl
]['border_radius_TL_V']; $brset
= true; }
20705 if (isset($this->blk
[$blvl]['border_radius_TR_H'])) { $brTR_H
= $this
->blk
[$blvl
]['border_radius_TR_H']; $brset
= true; }
20706 if (isset($this->blk
[$blvl]['border_radius_TR_V'])) { $brTR_V
= $this
->blk
[$blvl
]['border_radius_TR_V']; $brset
= true; }
20707 if (isset($this->blk
[$blvl]['border_radius_BR_H'])) { $brBR_H
= $this
->blk
[$blvl
]['border_radius_BR_H']; $brset
= true; }
20708 if (isset($this->blk
[$blvl]['border_radius_BR_V'])) { $brBR_V
= $this
->blk
[$blvl
]['border_radius_BR_V']; $brset
= true; }
20709 if (isset($this->blk
[$blvl]['border_radius_BL_H'])) { $brBL_H
= $this
->blk
[$blvl
]['border_radius_BL_H']; $brset
= true; }
20710 if (isset($this->blk
[$blvl]['border_radius_BL_V'])) { $brBL_V
= $this
->blk
[$blvl
]['border_radius_BL_V']; $brset
= true; }
20713 //if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage || $this->keep_block_together) {
20714 if (!$this->blk
[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
20721 //if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom' || $this->keep_block_together) {
20722 if (!$this->blk
[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') {
20729 // Disallow border-radius if it is smaller than the border width.
20730 if ($brTL_H < min($border_left, $border_top)) { $brTL_H
= $brTL_V
= 0; }
20731 if ($brTL_V < min($border_left, $border_top)) { $brTL_V
= $brTL_H
= 0; }
20732 if ($brTR_H < min($border_right, $border_top)) { $brTR_H
= $brTR_V
= 0; }
20733 if ($brTR_V < min($border_right, $border_top)) { $brTR_V
= $brTR_H
= 0; }
20734 if ($brBL_H < min($border_left, $border_bottom)) { $brBL_H
= $brBL_V
= 0; }
20735 if ($brBL_V < min($border_left, $border_bottom)) { $brBL_V
= $brBL_H
= 0; }
20736 if ($brBR_H < min($border_right, $border_bottom)) { $brBR_H
= $brBR_V
= 0; }
20737 if ($brBR_V < min($border_right, $border_bottom)) { $brBR_V
= $brBR_H
= 0; }
20739 // CHECK FOR radii that sum to > width or height of div ********
20740 $f = min($h/($brTL_V +
$brBL_V +
0.001), $h/($brTR_V +
$brBR_V +
0.001), $w/($brTL_H +
$brTR_H +
0.001), $w/($brBL_H +
$brBR_H +
0.001));
20751 /*-- END BORDER-RADIUS --*/
20753 $tbcol = $this->ConvertColor(255);
20754 for($l=0; $l <= $blvl; $l++
) {
20755 if ($this->blk
[$l]['bgcolor']) {
20756 $tbcol = $this->blk
[$l]['bgcolorarray'];
20761 if (isset($this->blk
[$blvl]['y0']) && $this->blk
[$blvl]['y0']) { $y0
= $this
->blk
[$blvl
]['y0']; }
20763 $w = $this->blk
[$blvl]['width'];
20765 //if ($this->blk[$blvl]['border_top']) {
20766 // Reinstate line above for dotted line divider when block border crosses a page
20767 if ($this->blk
[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
20768 $tbd = $this->blk
[$blvl]['border_top'];
20772 if (isset($this->blk
[$blvl]['border_legend']) && $this->blk
[$blvl]['border_legend']) {
20773 $legend = $this->blk
[$blvl]['border_legend']; // Same structure array as textbuffer
20774 $txt = ltrim($legend[0]);
20776 //Set font, size, style, color
20777 $this->SetFont($legend[4],$legend[2],$legend[11]);
20780 $this->SetTColor($cor);
20782 $stringWidth = $this->GetStringWidth($txt );
20783 $save_x = $this->x
;
20784 $save_y = $this->y
;
20785 $save_currentfontfamily = $this->FontFamily
;
20786 $save_currentfontsize = $this->FontSizePt
;
20787 $save_currentfontstyle = $this->FontStyle
.($this->U
? 'U' : '').($this->S
? 'S' : '');
20788 $this->y
= $y0 - $this->FontSize
/2 +
$this->blk
[$blvl]['border_top']['w']/2;
20789 $this->x
= $x0 +
$this->blk
[$blvl]['padding_left'] +
$this->blk
[$blvl]['border_left']['w'];
20791 // Set the distance from the border line to the text ? make configurable variable
20792 $gap = 0.2 * $this->FontSize
;
20794 $legbreakL = $this->x
- $gap;
20795 $legbreakR = $this->x +
$stringWidth +
$gap;
20797 $this->Cell( $stringWidth, $this->FontSize
, $txt , '', 0, 'C', $fill, '', 0, 0,0,'M', $fill);
20799 $this->x
= $save_x;
20800 $this->y
= $save_y;
20801 $this->SetFont($save_currentfontfamily,$save_currentfontstyle,$save_currentfontsize);
20802 $this->SetTColor($this->ConvertColor(0));
20805 if (isset($tbd['s']) && $tbd['s']) {
20806 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
20808 $this->SetLineWidth(0);
20809 $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK
, ($this->h
-($y0))*_MPDFK
));
20810 $this->_out(sprintf('%.3F %.3F l ',($x0 +
$border_left)*_MPDFK
, ($this->h
-($y0 +
$border_top))*_MPDFK
));
20811 $this->_out(sprintf('%.3F %.3F l ',($x0 +
$w - $border_right)*_MPDFK
, ($this->h
-($y0 +
$border_top))*_MPDFK
));
20812 $this->_out(sprintf('%.3F %.3F l ',($x0 +
$w)*_MPDFK
, ($this->h
-($y0))*_MPDFK
));
20813 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
20816 $this->_setBorderLine($tbd);
20817 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
20818 $legbreakL -= $border_top/2; // because line cap different
20819 $legbreakR +
= $border_top/2;
20820 $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'T');
20822 /*-- BORDER-RADIUS --*/
20823 else if (($brTL_V && $brTL_H) || ($brTR_V && $brTR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
20824 $this->SetLineJoin(0);
20825 $this->SetLineCap(0);
20828 if ($brTR_H && $brTR_V) {
20829 $s .= ($this->_EllipseArc($x0 +
$w - $brTR_H, $y0 +
$brTR_V, $brTR_H - $border_top/2 , $brTR_V - $border_top/2 , 1, 2, true))."\n";
20832 /*-- END BORDER-RADIUS --*/
20833 if ($tbd['style']=='solid' || $tbd['style']=='double') {
20834 $s .= (sprintf('%.3F %.3F m ',($x0 +
$w)*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
))."\n";
20837 $s .= (sprintf('%.3F %.3F m ',($x0 +
$w - ($border_top/2))*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
))."\n";
20839 /*-- BORDER-RADIUS --*/
20840 if ($brTL_H && $brTL_V ) {
20843 if ($legbreakR < ($x0 +
$w - $brTR_H)) {
20844 $s .= (sprintf('%.3F %.3F l ', $legbreakR*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
))."\n";
20846 if ($legbreakL > ($x0 +
$brTL_H )) {
20847 $s .= (sprintf('%.3F %.3F m ',$legbreakL*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
))."\n";
20848 $s .= (sprintf('%.3F %.3F l ',($x0 +
$brTL_H )*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
)."\n");
20851 $s .= (sprintf('%.3F %.3F m ',($x0 +
$brTL_H )*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
))."\n";
20855 $s .= (sprintf('%.3F %.3F l ',($x0 +
$brTL_H )*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
))."\n";
20857 $s .= ($this->_EllipseArc($x0 +
$brTL_H, $y0 +
$brTL_V, $brTL_H - $border_top/2 , $brTL_V - $border_top/2 , 2, 1))."\n";
20860 /*-- END BORDER-RADIUS --*/
20863 if ($legbreakR < ($x0 +
$w)) {
20864 $s .= (sprintf('%.3F %.3F l ',$legbreakR*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
))."\n";
20866 if ($legbreakL > ($x0)) {
20867 $s .= (sprintf('%.3F %.3F m ',$legbreakL*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
))."\n";
20868 if ($tbd['style']=='solid' || $tbd['style']=='double') {
20869 $s .= (sprintf('%.3F %.3F l ',($x0)*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
))."\n";
20872 $s .= (sprintf('%.3F %.3F l ',($x0 +
($border_top/2))*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
))."\n";
20875 else if ($tbd['style']=='solid' || $tbd['style']=='double') {
20876 $s .= (sprintf('%.3F %.3F m ', ($x0)*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
))."\n";
20879 $s .= (sprintf('%.3F %.3F m ', ($x0 +
$border_top/2)*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
))."\n";
20882 else if ($tbd['style']=='solid' || $tbd['style']=='double') {
20883 $s .= (sprintf('%.3F %.3F l ',($x0)*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
))."\n";
20886 $s .= (sprintf('%.3F %.3F l ',($x0 +
($border_top/2))*_MPDFK
, ($this->h
-($y0 +
($border_top/2)))*_MPDFK
))."\n";
20888 /*-- BORDER-RADIUS --*/
20890 /*-- END BORDER-RADIUS --*/
20894 if ($tbd['style']=='double') {
20895 $this->SetLineWidth($tbd['w']/3);
20896 $this->SetDColor($tbcol);
20899 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this
->_out('Q'); }
20901 // Reset Corners and Dash off
20902 $this->SetLineWidth(0.1); // mPDF 5.6.57
20903 $this->SetDColor($this->ConvertColor(0));
20904 $this->SetLineJoin(2);
20905 $this->SetLineCap(2);
20909 //if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1) {
20910 // Reinstate line above for dotted line divider when block border crosses a page
20911 if ($this->blk
[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
20912 $tbd = $this->blk
[$blvl]['border_bottom'];
20913 if (isset($tbd['s']) && $tbd['s']) {
20914 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
20916 $this->SetLineWidth(0);
20917 $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK
, ($this->h
-($y0 +
$h))*_MPDFK
));
20918 $this->_out(sprintf('%.3F %.3F l ',($x0 +
$border_left)*_MPDFK
, ($this->h
-($y0 +
$h - $border_bottom))*_MPDFK
));
20919 $this->_out(sprintf('%.3F %.3F l ',($x0 +
$w - $border_right)*_MPDFK
, ($this->h
-($y0 +
$h - $border_bottom))*_MPDFK
));
20920 $this->_out(sprintf('%.3F %.3F l ',($x0 +
$w)*_MPDFK
, ($this->h
-($y0 +
$h))*_MPDFK
));
20921 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
20924 $this->_setBorderLine($tbd);
20925 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this
->_setDashBorder($tbd
['style'],$divider
,$continuingpage
,'B'); }
20926 /*-- BORDER-RADIUS --*/
20927 else if (($brBL_V && $brBL_H) || ($brBR_V && $brBR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
20928 $this->SetLineJoin(0);
20929 $this->SetLineCap(0);
20932 if ($brBL_H && $brBL_V) {
20933 $s .= ($this->_EllipseArc($x0 +
$brBL_H, $y0 +
$h - $brBL_V, $brBL_H - $border_bottom/2 , $brBL_V - $border_bottom/2 , 3, 2, true))."\n";
20936 /*-- END BORDER-RADIUS --*/
20937 if ($tbd['style']=='solid' || $tbd['style']=='double') {
20938 $s .= (sprintf('%.3F %.3F m ',($x0)*_MPDFK
, ($this->h
-($y0 +
$h - ($border_bottom/2)))*_MPDFK
))."\n";
20941 $s .= (sprintf('%.3F %.3F m ',($x0 +
($border_bottom/2))*_MPDFK
, ($this->h
-($y0 +
$h - ($border_bottom/2)))*_MPDFK
))."\n";
20943 /*-- BORDER-RADIUS --*/
20944 if ($brBR_H && $brBR_V ) {
20945 $s .= (sprintf('%.3F %.3F l ',($x0 +
$w - ($border_bottom/2) - $brBR_H )*_MPDFK
, ($this->h
-($y0 +
$h - ($border_bottom/2)))*_MPDFK
))."\n";
20946 $s .= ($this->_EllipseArc($x0 +
$w - $brBR_H, $y0 +
$h - $brBR_V, $brBR_H - $border_bottom/2 , $brBR_V - $border_bottom/2 , 4, 1))."\n";
20949 /*-- END BORDER-RADIUS --*/
20950 if ($tbd['style']=='solid' || $tbd['style']=='double') {
20951 $s .= (sprintf('%.3F %.3F l ',($x0 +
$w)*_MPDFK
, ($this->h
-($y0 +
$h - ($border_bottom/2)))*_MPDFK
))."\n";
20954 $s .= (sprintf('%.3F %.3F l ',($x0 +
$w - ($border_bottom/2))*_MPDFK
, ($this->h
-($y0 +
$h - ($border_bottom/2)))*_MPDFK
))."\n";
20959 if ($tbd['style']=='double') {
20960 $this->SetLineWidth($tbd['w']/3);
20961 $this->SetDColor($tbcol);
20964 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this
->_out('Q'); }
20967 // Reset Corners and Dash off
20968 $this->SetLineWidth(0.1); // mPDF 5.6.57
20969 $this->SetDColor($this->ConvertColor(0));
20970 $this->SetLineJoin(2);
20971 $this->SetLineCap(2);
20975 if ($this->blk
[$blvl]['border_left']) {
20976 $tbd = $this->blk
[$blvl]['border_left'];
20977 if (isset($tbd['s']) && $tbd['s']) {
20978 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
20980 $this->SetLineWidth(0);
20981 $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK
, ($this->h
-($y0))*_MPDFK
));
20982 $this->_out(sprintf('%.3F %.3F l ',($x0 +
$border_left)*_MPDFK
, ($this->h
-($y0+
$border_top))*_MPDFK
));
20983 $this->_out(sprintf('%.3F %.3F l ',($x0 +
$border_left)*_MPDFK
, ($this->h
-($y0 +
$h - $border_bottom))*_MPDFK
));
20984 $this->_out(sprintf('%.3F %.3F l ',($x0)*_MPDFK
, ($this->h
-($y0 +
$h))*_MPDFK
));
20985 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
20988 $this->_setBorderLine($tbd);
20989 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this
->_setDashBorder($tbd
['style'],$divider
,$continuingpage
,'L'); }
20990 /*-- BORDER-RADIUS --*/
20991 else if (($brTL_V && $brTL_H) || ($brBL_V && $brBL_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
20992 $this->SetLineJoin(0);
20993 $this->SetLineCap(0);
20996 if ($brTL_V && $brTL_H) {
20997 $s .= ($this->_EllipseArc($x0 +
$brTL_H, $y0 +
$brTL_V, $brTL_H - $border_left/2 , $brTL_V - $border_left/2, 2, 2, true))."\n";
21000 /*-- END BORDER-RADIUS --*/
21001 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21002 $s .= (sprintf('%.3F %.3F m ',($x0 +
($border_left/2))*_MPDFK
, ($this->h
-($y0))*_MPDFK
))."\n";
21005 $s .= (sprintf('%.3F %.3F m ',($x0 +
($border_left/2))*_MPDFK
, ($this->h
-($y0 +
($border_left/2)))*_MPDFK
))."\n";
21007 /*-- BORDER-RADIUS --*/
21008 if ($brBL_V && $brBL_H ) {
21009 $s .= (sprintf('%.3F %.3F l ',($x0 +
($border_left/2))*_MPDFK
, ($this->h
-($y0 +
$h - ($border_left/2)- $brBL_V) )*_MPDFK
))."\n";
21010 $s .= ($this->_EllipseArc($x0 +
$brBL_H, $y0 +
$h - $brBL_V, $brBL_H - $border_left/2 , $brBL_V - $border_left/2, 3, 1))."\n";
21013 /*-- END BORDER-RADIUS --*/
21014 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21015 $s .= (sprintf('%.3F %.3F l ',($x0 +
($border_left/2))*_MPDFK
, ($this->h
-($y0 +
$h) )*_MPDFK
))."\n";
21018 $s .= (sprintf('%.3F %.3F l ',($x0 +
($border_left/2))*_MPDFK
, ($this->h
-($y0 +
$h - ($border_left/2)) )*_MPDFK
))."\n";
21023 if ($tbd['style']=='double') {
21024 $this->SetLineWidth($tbd['w']/3);
21025 $this->SetDColor($tbcol);
21028 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this
->_out('Q'); }
21030 // Reset Corners and Dash off
21031 $this->SetLineWidth(0.1); // mPDF 5.6.57
21032 $this->SetDColor($this->ConvertColor(0));
21033 $this->SetLineJoin(2);
21034 $this->SetLineCap(2);
21038 if ($this->blk
[$blvl]['border_right']) {
21039 $tbd = $this->blk
[$blvl]['border_right'];
21040 if (isset($tbd['s']) && $tbd['s']) {
21041 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
21043 $this->SetLineWidth(0);
21044 $this->_out(sprintf('%.3F %.3F m ',($x0 +
$w)*_MPDFK
, ($this->h
-($y0))*_MPDFK
));
21045 $this->_out(sprintf('%.3F %.3F l ',($x0 +
$w - $border_right)*_MPDFK
, ($this->h
-($y0+
$border_top))*_MPDFK
));
21046 $this->_out(sprintf('%.3F %.3F l ',($x0 +
$w - $border_right)*_MPDFK
, ($this->h
-($y0 +
$h - $border_bottom))*_MPDFK
));
21047 $this->_out(sprintf('%.3F %.3F l ',($x0 +
$w)*_MPDFK
, ($this->h
-($y0 +
$h))*_MPDFK
));
21048 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
21051 $this->_setBorderLine($tbd);
21052 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this
->_setDashBorder($tbd
['style'],$divider
,$continuingpage
,'R'); }
21053 /*-- BORDER-RADIUS --*/
21054 else if (($brTR_V && $brTR_H) || ($brBR_V && $brBR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
21055 $this->SetLineJoin(0);
21056 $this->SetLineCap(0);
21059 if ($brBR_V && $brBR_H) {
21060 $s .= ($this->_EllipseArc($x0 +
$w - $brBR_H, $y0 +
$h - $brBR_V, $brBR_H - $border_right/2 , $brBR_V - $border_right/2, 4, 2, true))."\n";
21063 /*-- END BORDER-RADIUS --*/
21064 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21065 $s .= (sprintf('%.3F %.3F m ',($x0 +
$w - ($border_right/2))*_MPDFK
, ($this->h
-($y0 +
$h))*_MPDFK
))."\n";
21068 $s .= (sprintf('%.3F %.3F m ',($x0 +
$w - ($border_right/2))*_MPDFK
, ($this->h
-($y0 +
$h - ($border_right/2)))*_MPDFK
))."\n";
21070 /*-- BORDER-RADIUS --*/
21071 if ($brTR_V && $brTR_H ) {
21072 $s .= (sprintf('%.3F %.3F l ',($x0 +
$w - ($border_right/2))*_MPDFK
, ($this->h
-($y0 +
($border_right/2) +
$brTR_V) )*_MPDFK
))."\n";
21073 $s .= ($this->_EllipseArc($x0 +
$w - $brTR_H, $y0 +
$brTR_V, $brTR_H - $border_right/2 , $brTR_V - $border_right/2, 1, 1))."\n";
21076 /*-- END BORDER-RADIUS --*/
21077 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21078 $s .= (sprintf('%.3F %.3F l ',($x0 +
$w - ($border_right/2))*_MPDFK
, ($this->h
-($y0) )*_MPDFK
))."\n";
21081 $s .= (sprintf('%.3F %.3F l ',($x0 +
$w - ($border_right/2))*_MPDFK
, ($this->h
-($y0 +
($border_right/2)) )*_MPDFK
))."\n";
21086 if ($tbd['style']=='double') {
21087 $this->SetLineWidth($tbd['w']/3);
21088 $this->SetDColor($tbcol);
21091 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this
->_out('Q'); }
21093 // Reset Corners and Dash off
21094 $this->SetLineWidth(0.1); // mPDF 5.6.57
21095 $this->SetDColor($this->ConvertColor(0));
21096 $this->SetLineJoin(2);
21097 $this->SetLineCap(2);
21104 $this->y
= $save_y;
21107 // BACKGROUNDS are disabled in columns/kbt/headers - messes up the repositioning in printcolumnbuffer
21108 if ($this->ColActive
|| $this->kwt
|| $this->keep_block_together
) { return ; }
21116 // Defined br values represent the radius of the outer curve - need to take border-width/2 from each radius for drawing the borders
21117 if (isset($this->blk
[$blvl]['background_clip']) && $this->blk
[$blvl]['background_clip'] == 'padding-box') {
21118 $brbgTL_H = max(0, $brTL_H - $this->blk
[$blvl]['border_left']['w']);
21119 $brbgTL_V = max(0, $brTL_V - $this->blk
[$blvl]['border_top']['w']);
21120 $brbgTR_H = max(0, $brTR_H - $this->blk
[$blvl]['border_right']['w']);
21121 $brbgTR_V = max(0, $brTR_V - $this->blk
[$blvl]['border_top']['w']);
21122 $brbgBL_H = max(0, $brBL_H - $this->blk
[$blvl]['border_left']['w']);
21123 $brbgBL_V = max(0, $brBL_V - $this->blk
[$blvl]['border_bottom']['w']);
21124 $brbgBR_H = max(0, $brBR_H - $this->blk
[$blvl]['border_right']['w']);
21125 $brbgBR_V = max(0, $brBR_V - $this->blk
[$blvl]['border_bottom']['w']);
21126 $bgx0 +
= $this->blk
[$blvl]['border_left']['w'];
21127 $bgx1 -= $this->blk
[$blvl]['border_right']['w'];
21128 if ($this->blk
[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21129 $bgy0 +
= $this->blk
[$blvl]['border_top']['w'];
21131 if ($this->blk
[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21132 $bgy1 -= $this->blk
[$blvl]['border_bottom']['w'];
21136 else if (isset($this->blk
[$blvl]['background_clip']) && $this->blk
[$blvl]['background_clip'] == 'content-box') {
21137 $brbgTL_H = max(0, $brTL_H - $this->blk
[$blvl]['border_left']['w'] - $this->blk
[$blvl]['padding_left']);
21138 $brbgTL_V = max(0, $brTL_V - $this->blk
[$blvl]['border_top']['w'] - $this->blk
[$blvl]['padding_top']);
21139 $brbgTR_H = max(0, $brTR_H - $this->blk
[$blvl]['border_right']['w'] - $this->blk
[$blvl]['padding_right']);
21140 $brbgTR_V = max(0, $brTR_V - $this->blk
[$blvl]['border_top']['w'] - $this->blk
[$blvl]['padding_top']);
21141 $brbgBL_H = max(0, $brBL_H - $this->blk
[$blvl]['border_left']['w'] - $this->blk
[$blvl]['padding_left']);
21142 $brbgBL_V = max(0, $brBL_V - $this->blk
[$blvl]['border_bottom']['w'] - $this->blk
[$blvl]['padding_bottom']);
21143 $brbgBR_H = max(0, $brBR_H - $this->blk
[$blvl]['border_right']['w'] - $this->blk
[$blvl]['padding_right']);
21144 $brbgBR_V = max(0, $brBR_V - $this->blk
[$blvl]['border_bottom']['w'] - $this->blk
[$blvl]['padding_bottom']);
21145 $bgx0 +
= $this->blk
[$blvl]['border_left']['w'] +
$this->blk
[$blvl]['padding_left'];
21146 $bgx1 -= $this->blk
[$blvl]['border_right']['w'] +
$this->blk
[$blvl]['padding_right'];
21147 if (($this->blk
[$blvl]['border_top']['w'] || $this->blk
[$blvl]['padding_top']) && $divider != 'pagetop' && !$continuingpage) {
21148 $bgy0 +
= $this->blk
[$blvl]['border_top']['w'] +
$this->blk
[$blvl]['padding_top'];
21150 if (($this->blk
[$blvl]['border_bottom']['w'] || $this->blk
[$blvl]['padding_bottom']) && $blockstate != 1 && $divider != 'pagebottom') {
21151 $bgy1 -= $this->blk
[$blvl]['border_bottom']['w'] +
$this->blk
[$blvl]['padding_bottom'];
21155 $brbgTL_H = $brTL_H;
21156 $brbgTL_V = $brTL_V;
21157 $brbgTR_H = $brTR_H;
21158 $brbgTR_V = $brTR_V;
21159 $brbgBL_H = $brBL_H;
21160 $brbgBL_V = $brBL_V;
21161 $brbgBR_H = $brBR_H;
21162 $brbgBR_V = $brBR_V;
21165 // Set clipping path
21166 $s = ' q 0 w '; // Line width=0
21167 $s .= sprintf('%.3F %.3F m ', ($bgx0+
$brbgTL_H )*_MPDFK
, ($this->h
-$bgy0)*_MPDFK
); // start point TL before the arc
21168 /*-- BORDER-RADIUS --*/
21169 if ($brbgTL_H || $brbgTL_V) {
21170 $s .= $this->_EllipseArc($bgx0+
$brbgTL_H, $bgy0+
$brbgTL_V, $brbgTL_H , $brbgTL_V , 2); // segment 2 TL
21172 /*-- END BORDER-RADIUS --*/
21173 $s .= sprintf('%.3F %.3F l ', ($bgx0)*_MPDFK
, ($this->h
-($bgy1-$brbgBL_V ))*_MPDFK
); // line to BL
21174 /*-- BORDER-RADIUS --*/
21175 if ($brbgBL_H || $brbgBL_V) {
21176 $s .= $this->_EllipseArc($bgx0+
$brbgBL_H, $bgy1-$brbgBL_V, $brbgBL_H , $brbgBL_V , 3); // segment 3 BL
21178 /*-- END BORDER-RADIUS --*/
21179 $s .= sprintf('%.3F %.3F l ', ($bgx1-$brbgBR_H )*_MPDFK
, ($this->h
-($bgy1))*_MPDFK
); // line to BR
21180 /*-- BORDER-RADIUS --*/
21181 if ($brbgBR_H || $brbgBR_V) {
21182 $s .= $this->_EllipseArc($bgx1-$brbgBR_H, $bgy1-$brbgBR_V, $brbgBR_H , $brbgBR_V , 4); // segment 4 BR
21184 /*-- END BORDER-RADIUS --*/
21185 $s .= sprintf('%.3F %.3F l ', ($bgx1)*_MPDFK
, ($this->h
-($bgy0+
$brbgTR_V))*_MPDFK
); // line to TR
21186 /*-- BORDER-RADIUS --*/
21187 if ($brbgTR_H || $brbgTR_V) {
21188 $s .= $this->_EllipseArc($bgx1-$brbgTR_H, $bgy0+
$brbgTR_V, $brbgTR_H , $brbgTR_V , 1); // segment 1 TR
21190 /*-- END BORDER-RADIUS --*/
21191 $s .= sprintf('%.3F %.3F l ', ($bgx0+
$brbgTL_H )*_MPDFK
, ($this->h
-$bgy0)*_MPDFK
); // line to TL
21196 if (isset($this->blk
[$blvl]['box_shadow']) && $this->blk
[$blvl]['box_shadow'] && $h > 0) {
21197 foreach($this->blk
[$blvl]['box_shadow'] AS $sh) {
21199 if ($sh['col']{0}==1) {
21200 $colspace = 'Gray';
21201 if ($sh['col']{2}==1) { $col1
= '1'.$sh
['col'][1].'1'.$sh
['col'][3]; }
21202 else { $col1
= '1'.$sh
['col'][1].'1'.chr(100); }
21203 $col2 = '1'.$sh['col'][1].'1'.chr(0);
21205 else if ($sh['col']{0}==4) { // CMYK
21206 $colspace = 'CMYK';
21207 $col1 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(100);
21208 $col2 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(0);
21210 else if ($sh['col']{0}==5) { // RGBa
21212 $col1 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4];
21213 $col2 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(0);
21215 else if ($sh['col']{0}==6) { // CMYKa
21216 $colspace = 'CMYK';
21217 $col1 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].$sh['col'][5];
21218 $col2 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(0);
21222 $col1 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(100);
21223 $col2 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(0);
21226 // Use clipping path as set above (and rectangle around page) to clip area outside box
21227 $shadow .= $s; // Use the clipping path with W*
21228 $shadow .= sprintf('0 %.3F m %.3F %.3F l ', $this->h
*_MPDFK
, $this->w
*_MPDFK
, $this->h
*_MPDFK
);
21229 $shadow .= sprintf('%.3F 0 l 0 0 l 0 %.3F l ', $this->w
*_MPDFK
, $this->h
*_MPDFK
);
21230 $shadow .= 'W n'."\n";
21232 $sh['blur'] = abs($sh['blur']); // cannot have negative blur value
21233 // Ensure spread/blur do not make effective shadow width/height < 0
21234 // Could do more complex things but this just adjusts spread value
21235 if (-$sh['spread'] +
$sh['blur']/2 > min($w/2, $h/2)) {
21236 $sh['spread'] = $sh['blur']/2 - min($w/2, $h/2) +
0.01;
21239 if ($sh['x'] || $sh['y']) $shadow .= sprintf(' q 1 0 0 1 %.4F %.4F cm', $sh['x']*_MPDFK
, -$sh['y']*_MPDFK
)."\n";
21241 // Set path for INNER shadow
21242 $shadow .= ' q 0 w ';
21243 $shadow .= $this->SetFColor($col1, true)."\n";
21244 if ($col1{0}==5 && ord($col1{4})<100) { // RGBa
21245 $shadow .= $this->SetAlpha(ord($col1{4})/100, 'Normal', true, 'F')."\n";
21247 else if ($col1{0}==6 && ord($col1{5})<100) { // CMYKa
21248 $shadow .= $this->SetAlpha(ord($col1{5})/100, 'Normal', true, 'F')."\n";
21250 else if ($col1{0}==1 && $col1{2}==1 && ord($col1{3})<100) { // Gray
21251 $shadow .= $this->SetAlpha(ord($col1{3})/100, 'Normal', true, 'F')."\n";
21255 $mag = 0.551784; // Bezier Control magic number for 4-part spline for circle/ellipse
21256 $mag2 = 0.551784; // Bezier Control magic number to fill in edge of blurred rectangle
21257 $d1 = $sh['spread']+
$sh['blur']/2;
21258 $d2 = $sh['spread']-$sh['blur']/2;
21265 // If any border-radius is greater width-negative spread(inner edge), ignore radii for shadow or screws up
21267 if (max($brbgTR_H, $brbgTL_H, $brbgBR_H, $brbgBL_H) >= $w+
$d2) { $flatten
= true; }
21268 if (max($brbgTR_V, $brbgTL_V, $brbgBR_V, $brbgBL_V) >= $h+
$d2) { $flatten
= true; }
21271 // TOP RIGHT corner
21272 $p1x = $x00+
$w00-$d1-$brbgTR_H; $p1c2x = $p1x +
($d2+
$brbgTR_H)*$mag;
21274 $p2x = $x00+
$w00-$d1-$brbgTR_H; $p2c2x = $p2x +
($d1+
$brbgTR_H)*$mag;
21275 $p2y = $y00; $p2c1y = $p2y +
$bl/2;
21276 $p3x = $x00+
$w00; $p3c2x = $p3x - $bl/2;
21277 $p3y = $y00+
$d1+
$brbgTR_V; $p3c1y = $p3y - ($d1+
$brbgTR_V)*$mag;
21278 $p4x = $x00+
$w00-$bl;
21279 $p4y = $y00+
$d1+
$brbgTR_V; $p4c2y = $p4y - ($d2+
$brbgTR_V)*$mag;
21280 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21281 $p1x = $x00+
$w00-$bl; $p1c2x = $p1x;
21282 $p2x = $x00+
$w00-$bl; $p2c2x = $p2x +
$bl*$mag2;
21283 $p3y = $y00+
$bl; $p3c1y = $p3y - $bl*$mag2;
21284 $p4y = $y00+
$bl; $p4c2y = $p4y ;
21287 $shadow .= sprintf('%.3F %.3F m ', ($p1x )*_MPDFK
, ($this->h
-($p1y ))*_MPDFK
);
21288 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1c2x)*_MPDFK
, ($this->h
-($p1y))*_MPDFK
, ($p4x)*_MPDFK
, ($this->h
-($p4c2y))*_MPDFK
, ($p4x)*_MPDFK
, ($this->h
-($p4y))*_MPDFK
);
21289 $patch_array[0]['f']=0;
21290 $patch_array[0]['points']=array($p1x,$p1y, $p1x,$p1y,
21291 $p2x,$p2c1y, $p2x,$p2y, $p2c2x,$p2y,
21292 $p3x,$p3c1y, $p3x,$p3y, $p3c2x,$p3y,
21293 $p4x,$p4y, $p4x,$p4y, $p4x,$p4c2y,
21295 $patch_array[0]['colors'] = array($col1,$col2,$col2,$col1);
21299 $p1x = $x00+
$w00; // control point only matches p3 preceding
21300 $p1y = $y00+
$d1+
$brbgTR_V;
21301 $p2x = $x00+
$w00-$bl; // control point only matches p4 preceding
21302 $p2y = $y00+
$d1+
$brbgTR_V;
21303 $p3x = $x00+
$w00-$bl;
21304 $p3y = $y00+
$h00-$d1-$brbgBR_V;
21305 $p4x = $x00+
$w00; $p4c1x = $p4x-$bl/2;
21306 $p4y = $y00+
$h00-$d1-$brbgBR_V;
21307 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21311 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21312 $p3y = $y00+
$h00-$bl;
21313 $p4y = $y00+
$h00-$bl;
21316 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK
, ($this->h
-($p3y ))*_MPDFK
);
21317 $patch_array[1]['f']=2;
21318 $patch_array[1]['points']=array($p2x,$p2y,
21319 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21320 $p4c1x,$p4y, $p4x,$p4y, $p4x,$p4y,
21322 $patch_array[1]['colors'] = array($col1,$col2);
21325 // BOTTOM RIGHT corner
21326 $p1x = $x00+
$w00-$bl; // control points only matches p3 preceding
21327 $p1y = $y00+
$h00-$d1-$brbgBR_V; $p1c2y = $p1y +
($d2+
$brbgBR_V)*$mag;
21328 $p2x = $x00+
$w00; // control point only matches p4 preceding
21329 $p2y = $y00+
$h00-$d1-$brbgBR_V; $p2c2y = $p2y +
($d1+
$brbgBR_V)*$mag;
21330 $p3x = $x00+
$w00-$d1-$brbgBR_H; $p3c1x = $p3x +
($d1+
$brbgBR_H)*$mag;
21331 $p3y = $y00+
$h00; $p3c2y = $p3y - $bl/2;
21332 $p4x = $x00+
$w00-$d1-$brbgBR_H; $p4c2x = $p4x +
($d2+
$brbgBR_H)*$mag;
21333 $p4y = $y00+
$h00-$bl;
21335 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21336 $p1y = $y00+
$h00-$bl; $p1c2y = $p1y;
21337 $p2y = $y00+
$h00-$bl; $p2c2y = $p2y +
$bl*$mag2;
21338 $p3x = $x00+
$w00-$bl; $p3c1x = $p3x +
$bl*$mag2;
21339 $p4x = $x00+
$w00-$bl; $p4c2x = $p4x;
21342 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1x)*_MPDFK
, ($this->h
-($p1c2y))*_MPDFK
, ($p4c2x)*_MPDFK
, ($this->h
-($p4y))*_MPDFK
, ($p4x)*_MPDFK
, ($this->h
-($p4y))*_MPDFK
);
21343 $patch_array[2]['f']=2;
21344 $patch_array[2]['points']=array($p2x,$p2c2y,
21345 $p3c1x,$p3y, $p3x,$p3y, $p3x,$p3c2y,
21346 $p4x,$p4y, $p4x,$p4y, $p4c2x,$p4y,
21348 $patch_array[2]['colors'] = array($col2,$col1);
21353 $p1x = $x00+
$w00-$d1-$brbgBR_H; // control point only matches p3 preceding
21355 $p2x = $x00+
$w00-$d1-$brbgBR_H; // control point only matches p4 preceding
21356 $p2y = $y00+
$h00-$bl;
21357 $p3x = $x00+
$d1+
$brbgBL_H;
21358 $p3y = $y00+
$h00-$bl;
21359 $p4x = $x00+
$d1+
$brbgBL_H;
21360 $p4y = $y00+
$h00; $p4c1y = $p4y - $bl/2;
21362 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21363 $p1x = $x00+
$w00-$bl;
21364 $p2x = $x00+
$w00-$bl;
21366 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21371 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK
, ($this->h
-($p3y ))*_MPDFK
);
21372 $patch_array[3]['f']=2;
21373 $patch_array[3]['points']=array($p2x,$p2y,
21374 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21375 $p4x,$p4c1y, $p4x,$p4y, $p4x,$p4y,
21377 $patch_array[3]['colors'] = array($col1,$col2);
21379 // BOTTOM LEFT corner
21380 $p1x = $x00+
$d1+
$brbgBL_H; $p1c2x = $p1x - ($d2+
$brbgBL_H)*$mag; // control points only matches p3 preceding
21381 $p1y = $y00+
$h00-$bl;
21382 $p2x = $x00+
$d1+
$brbgBL_H; $p2c2x = $p2x - ($d1+
$brbgBL_H)*$mag; // control point only matches p4 preceding
21384 $p3x = $x00; $p3c2x = $p3x +
$bl/2;
21385 $p3y = $y00+
$h00-$d1-$brbgBL_V; $p3c1y = $p3y +
($d1+
$brbgBL_V)*$mag;
21387 $p4y = $y00+
$h00-$d1-$brbgBL_V; $p4c2y = $p4y +
($d2+
$brbgBL_V)*$mag;
21388 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21389 $p1x = $x00+
$bl; $p1c2x = $p1x;
21390 $p2x = $x00+
$bl; $p2c2x = $p2x - $bl*$mag2;
21391 $p3y = $y00+
$h00-$bl; $p3c1y = $p3y +
$bl*$mag2;
21392 $p4y = $y00+
$h00-$bl; $p4c2y = $p4y;
21395 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1c2x)*_MPDFK
, ($this->h
-($p1y))*_MPDFK
, ($p4x)*_MPDFK
, ($this->h
-($p4c2y))*_MPDFK
, ($p4x)*_MPDFK
, ($this->h
-($p4y))*_MPDFK
);
21396 $patch_array[4]['f']=2;
21397 $patch_array[4]['points']=array($p2c2x,$p2y,
21398 $p3x,$p3c1y, $p3x,$p3y, $p3c2x,$p3y,
21399 $p4x,$p4y, $p4x,$p4y, $p4x,$p4c2y,
21401 $patch_array[4]['colors'] = array($col2,$col1);
21404 // LEFT - joins on the right (C3-C4 of previous): f = 2
21405 $p1x = $x00; // control point only matches p3 preceding
21406 $p1y = $y00+
$h00-$d1-$brbgBL_V;
21407 $p2x = $x00+
$bl; // control point only matches p4 preceding
21408 $p2y = $y00+
$h00-$d1-$brbgBL_V;
21410 $p3y = $y00+
$d1+
$brbgTL_V;
21411 $p4x = $x00; $p4c1x = $p4x +
$bl/2;
21412 $p4y = $y00+
$d1+
$brbgTL_V;
21413 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21414 $p1y = $y00+
$h00-$bl;
21415 $p2y = $y00+
$h00-$bl;
21417 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21422 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK
, ($this->h
-($p3y ))*_MPDFK
);
21423 $patch_array[5]['f']=2;
21424 $patch_array[5]['points']=array($p2x,$p2y,
21425 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21426 $p4c1x,$p4y, $p4x,$p4y, $p4x,$p4y,
21428 $patch_array[5]['colors'] = array($col1,$col2);
21431 $p1x = $x00+
$bl; // control points only matches p3 preceding
21432 $p1y = $y00+
$d1+
$brbgTL_V; $p1c2y = $p1y - ($d2+
$brbgTL_V)*$mag;
21433 $p2x = $x00; // control point only matches p4 preceding
21434 $p2y = $y00+
$d1+
$brbgTL_V; $p2c2y = $p2y - ($d1+
$brbgTL_V)*$mag;
21435 $p3x = $x00+
$d1+
$brbgTL_H; $p3c1x = $p3x - ($d1+
$brbgTL_H)*$mag;
21436 $p3y = $y00; $p3c2y = $p3y +
$bl/2;
21437 $p4x = $x00+
$d1+
$brbgTL_H; $p4c2x = $p4x - ($d2+
$brbgTL_H)*$mag;
21440 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21441 $p1y = $y00+
$bl; $p1c2y = $p1y;
21442 $p2y = $y00+
$bl; $p2c2y = $p2y - $bl*$mag2;
21443 $p3x = $x00+
$bl; $p3c1x = $p3x - $bl*$mag2;
21444 $p4x = $x00+
$bl; $p4c2x = $p4x ;
21447 $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1x)*_MPDFK
, ($this->h
-($p1c2y))*_MPDFK
, ($p4c2x)*_MPDFK
, ($this->h
-($p4y))*_MPDFK
, ($p4x)*_MPDFK
, ($this->h
-($p4y))*_MPDFK
);
21448 $patch_array[6]['f']=2;
21449 $patch_array[6]['points']=array($p2x,$p2c2y,
21450 $p3c1x,$p3y, $p3x,$p3y, $p3x,$p3c2y,
21451 $p4x,$p4y, $p4x,$p4y, $p4c2x,$p4y,
21453 $patch_array[6]['colors'] = array($col2,$col1);
21456 // TOP - joins on the right (C3-C4 of previous): f = 2
21457 $p1x = $x00+
$d1+
$brbgTL_H; // control point only matches p3 preceding
21459 $p2x = $x00+
$d1+
$brbgTL_H; // control point only matches p4 preceding
21461 $p3x = $x00+
$w00-$d1-$brbgTR_H;
21463 $p4x = $x00+
$w00-$d1-$brbgTR_H;
21464 $p4y = $y00; $p4c1y = $p4y +
$bl/2;
21465 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21469 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21470 $p3x = $x00+
$w00-$bl;
21471 $p4x = $x00+
$w00-$bl;
21474 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK
, ($this->h
-($p3y ))*_MPDFK
);
21475 $patch_array[7]['f']=2;
21476 $patch_array[7]['points']=array($p2x,$p2y,
21477 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21478 $p4x,$p4c1y, $p4x,$p4y, $p4x,$p4y,
21480 $patch_array[7]['colors'] = array($col1,$col2);
21482 $shadow .= ' h f Q '."\n"; // Close path and Fill the inner solid shadow
21484 if ($bl) $shadow .= $this->grad
->CoonsPatchMesh($x00,$y00,$w00,$h00,$patch_array,$x00,$x00+
$w00,$y00,$y00+
$h00, $colspace, true);
21486 if ($sh['x'] || $sh['y']) $shadow .= ' Q'."\n"; // Shadow Offset
21487 $shadow .= ' Q'."\n"; // Ends path no-op & Sets the clipping path
21492 $s .= ' W n '; // Ends path no-op & Sets the clipping path
21494 if ($this->blk
[$blvl]['bgcolor']) {
21495 $this->pageBackgrounds
[$blvl][] = array('x'=>$x0, 'y'=>$y0, 'w'=>$w, 'h'=>$h, 'col'=>$this->blk
[$blvl]['bgcolorarray'], 'clippath'=>$s, 'visibility'=>$this->visibility
, 'shadow'=>$shadow, 'z-index'=>$this->current_layer
); // mPDF 5.6.01
21497 else if ($shadow) {
21498 $this->pageBackgrounds
[$blvl][] = array('shadowonly'=>true, 'col'=>'', 'clippath'=>'', 'visibility'=>$this->visibility
, 'shadow'=>$shadow, 'z-index'=>$this->current_layer
); // mPDF 5.6.01
21501 /*-- BACKGROUNDS --*/
21502 if (isset($this->blk
[$blvl]['gradient'])) {
21503 $g = $this->grad
->parseBackgroundGradient($this->blk
[$blvl]['gradient']);
21507 $this->pageBackgrounds
[$blvl][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$w, 'h'=>$h, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s, 'visibility'=>$this->visibility
, 'z-index'=>$this->current_layer
); // mPDF 5.6.01
21510 if (isset($this->blk
[$blvl]['background-image'])) {
21511 if ($this->blk
[$blvl]['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->blk
[$blvl]['background-image']['gradient'] )) {
21512 $g = $this->grad
->parseMozGradient( $this->blk
[$blvl]['background-image']['gradient'] );
21517 // origin specifies the background-positioning-area (bpa)
21518 if ($this->blk
[$blvl]['background-image']['origin'] == 'padding-box') {
21519 $gx +
= $this->blk
[$blvl]['border_left']['w'];
21520 $w -= ($this->blk
[$blvl]['border_left']['w'] +
$this->blk
[$blvl]['border_right']['w']);
21521 if ($this->blk
[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21522 $gy +
= $this->blk
[$blvl]['border_top']['w'];
21524 if ($this->blk
[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21525 $gy1 = $y1 - $this->blk
[$blvl]['border_bottom']['w'];
21527 else { $gy1
= $y1
; }
21530 else if ($this->blk
[$blvl]['background-image']['origin'] == 'content-box') {
21531 $gx +
= $this->blk
[$blvl]['border_left']['w'] +
$this->blk
[$blvl]['padding_left'];
21532 $w -= ($this->blk
[$blvl]['border_left']['w'] +
$this->blk
[$blvl]['padding_left'] +
$this->blk
[$blvl]['border_right']['w'] +
$this->blk
[$blvl]['padding_right']);
21533 if ($this->blk
[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21534 $gy +
= $this->blk
[$blvl]['border_top']['w'] +
$this->blk
[$blvl]['padding_top'];
21536 if ($this->blk
[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21537 $gy1 = $y1 - ($this->blk
[$blvl]['border_bottom']['w'] +
$this->blk
[$blvl]['padding_bottom']);
21539 else { $gy1
= $y1
- $this
->blk
[$blvl
]['padding_bottom']; }
21543 if (isset($this->blk
[$blvl]['background-image']['size']['w']) && $this->blk
[$blvl]['background-image']['size']['w']) {
21544 $size = $this->blk
[$blvl]['background-image']['size'];
21545 if ($size['w']!='contain' && $size['w']!='cover') {
21546 if (stristr($size['w'] ,'%')) {
21551 else if ($size['w']!='auto') {
21554 if (stristr($size['h'] ,'%')) {
21559 else if ($size['h']!='auto') {
21564 $this->pageBackgrounds
[$blvl][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$w, 'h'=>$h, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s, 'visibility'=>$this->visibility
, 'z-index'=>$this->current_layer
); // mPDF 5.6.01
21568 $image_id = $this->blk
[$blvl]['background-image']['image_id'];
21569 $orig_w = $this->blk
[$blvl]['background-image']['orig_w'];
21570 $orig_h = $this->blk
[$blvl]['background-image']['orig_h'];
21571 $x_pos = $this->blk
[$blvl]['background-image']['x_pos'];
21572 $y_pos = $this->blk
[$blvl]['background-image']['y_pos'];
21573 $x_repeat = $this->blk
[$blvl]['background-image']['x_repeat'];
21574 $y_repeat = $this->blk
[$blvl]['background-image']['y_repeat'];
21575 $resize = $this->blk
[$blvl]['background-image']['resize'];
21576 $opacity = $this->blk
[$blvl]['background-image']['opacity'];
21577 $itype = $this->blk
[$blvl]['background-image']['itype'];
21578 $size = $this->blk
[$blvl]['background-image']['size']; // mPDF 5.6.10
21580 // origin specifies the background-positioning-area (bpa)
21581 $bpa = array('x'=>$x0, 'y'=>$y0, 'w'=>$w, 'h'=>$h);
21582 if ($this->blk
[$blvl]['background-image']['origin'] == 'padding-box') {
21583 $bpa['x'] = $x0 +
$this->blk
[$blvl]['border_left']['w'];
21584 $bpa['w'] = $w - ($this->blk
[$blvl]['border_left']['w'] +
$this->blk
[$blvl]['border_right']['w']);
21585 if ($this->blk
[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21586 $bpa['y'] = $y0 +
$this->blk
[$blvl]['border_top']['w'];
21588 else { $bpa
['y'] = $y0
; }
21589 if ($this->blk
[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21590 $bpay = $y1 - $this->blk
[$blvl]['border_bottom']['w'];
21592 else { $bpay
= $y1
; }
21593 $bpa['h'] = $bpay - $bpa['y'];
21596 else if ($this->blk
[$blvl]['background-image']['origin'] == 'content-box') {
21597 $bpa['x'] = $x0 +
$this->blk
[$blvl]['border_left']['w'] +
$this->blk
[$blvl]['padding_left'];
21598 $bpa['w'] = $w - ($this->blk
[$blvl]['border_left']['w'] +
$this->blk
[$blvl]['padding_left'] +
$this->blk
[$blvl]['border_right']['w'] +
$this->blk
[$blvl]['padding_right']);
21599 if ($this->blk
[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21600 $bpa['y'] = $y0 +
$this->blk
[$blvl]['border_top']['w'] +
$this->blk
[$blvl]['padding_top'];
21602 else { $bpa
['y'] = $y0 + $this
->blk
[$blvl
]['padding_top']; }
21603 if ($this->blk
[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21604 $bpay = $y1 - ($this->blk
[$blvl]['border_bottom']['w'] +
$this->blk
[$blvl]['padding_bottom']);
21606 else { $bpay
= $y1
- $this
->blk
[$blvl
]['padding_bottom']; }
21607 $bpa['h'] = $bpay - $bpa['y'];
21609 $this->pageBackgrounds
[$blvl][] = array('x'=>$x0, 'y'=>$y0, 'w'=>$w, 'h'=>$h, 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>$s, 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype, 'visibility'=>$this->visibility
, 'z-index'=>$this->current_layer
, 'size'=>$size, 'bpa'=>$bpa ); // mPDF 5.6.01 5.6.10
21612 /*-- END BACKGROUNDS --*/
21615 $this->blk
[$blvl]['bb_painted'][$this->page
] = true;
21619 /*-- BORDER-RADIUS --*/
21621 function _EllipseArc($x0, $y0, $rx, $ry, $seg = 1, $part=false, $start=false) { // Anticlockwise segment 1-4 TR-TL-BL-BR (part=1 or 2)
21623 if ($rx<0) { $rx
= 0; }
21624 if ($ry<0) { $ry
= 0; }
21628 if ($seg == 1) { // Top Right
21632 else if ($seg == 2) { // Top Left
21636 else if ($seg == 3) { // Bottom Left
21640 else { // Bottom Right
21644 $astart = deg2rad((float) $astart);
21645 $afinish = deg2rad((float) $afinish);
21646 $totalAngle = $afinish - $astart;
21647 $dt = $totalAngle / $nSeg; // segment angle
21650 $y0 = ($this->h
- $y0) * _MPDFK
;
21652 $a0 = $x0 +
($rx * cos($t1));
21653 $b0 = $y0 +
($ry * sin($t1));
21654 $c0 = -$rx * sin($t1);
21655 $d0 = $ry * cos($t1);
21657 for ($i = 1; $i <= $nSeg; $i++
) {
21658 // Draw this bit of the total curve
21659 $t1 = ($i * $dt) +
$astart;
21660 $a1 = $x0 +
($rx * cos($t1));
21661 $b1 = $y0 +
($ry * sin($t1));
21662 $c1 = -$rx * sin($t1);
21663 $d1 = $ry * cos($t1);
21664 if ($i>($nSeg-4) && (!$part || ($part == 1 && $i<=$nSeg-2) || ($part == 2 && $i>$nSeg-2))) {
21665 if ($start && !$op) {
21666 $s .= sprintf('%.3F %.3F m ', $a0, $b0);
21668 $s .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($a0 +
($c0 * $dtm)), ($b0 +
($d0 * $dtm)), ($a1 - ($c1 * $dtm)) , ($b1 - ($d1 * $dtm)), $a1 , $b1 );
21678 /*-- END BORDER-RADIUS --*/
21682 function PaintDivLnBorder($state=0,$blvl=0,$h) {
21683 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
21684 $this->ColDetails
[$this->CurrCol
]['bottom_margin'] = $this->y +
$h;
21686 $save_y = $this->y
;
21688 $w = $this->blk
[$blvl]['width'];
21689 $x0 = $this->x
; // left
21690 $y0 = $this->y
; // top
21691 $x1 = $this->x +
$w; // bottom
21692 $y1 = $this->y +
$h; // bottom
21694 if ($this->blk
[$blvl]['border_top'] && ($state==1 || $state==3)) {
21695 $tbd = $this->blk
[$blvl]['border_top'];
21696 if (isset($tbd['s']) && $tbd['s']) {
21697 $this->_setBorderLine($tbd);
21698 $this->y
= $y0 +
($tbd['w']/2);
21700 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
21701 $this->_setDashBorder($tbd['style'],'',$continuingpage,'T');
21702 $this->Line($x0 +
($tbd['w']/2) , $this->y
, $x0 +
$w - ($tbd['w']/2), $this->y
);
21705 $this->SetLineJoin(0);
21706 $this->SetLineCap(0);
21707 $this->Line($x0, $this->y
, $x0 +
$w, $this->y
);
21709 $this->y +
= $tbd['w'];
21710 // Reset Corners and Dash off
21711 $this->SetLineJoin(2);
21712 $this->SetLineCap(2);
21716 if ($this->blk
[$blvl]['border_left']) {
21717 $tbd = $this->blk
[$blvl]['border_left'];
21718 if (isset($tbd['s']) && $tbd['s']) {
21719 $this->_setBorderLine($tbd);
21721 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
21722 $this->y
= $y0 +
($tbd['w']/2);
21723 $this->_setDashBorder($tbd['style'],'',$continuingpage,'L');
21724 $this->Line($x0 +
($tbd['w']/2), $this->y
, $x0 +
($tbd['w']/2), $y0 +
$h -($tbd['w']/2));
21728 $this->SetLineJoin(0);
21729 $this->SetLineCap(0);
21730 $this->Line($x0 +
($tbd['w']/2), $this->y
, $x0 +
($tbd['w']/2), $y0 +
$h);
21732 $this->y +
= $tbd['w'];
21733 // Reset Corners and Dash off
21734 $this->SetLineJoin(2);
21735 $this->SetLineCap(2);
21739 if ($this->blk
[$blvl]['border_right']) {
21740 $tbd = $this->blk
[$blvl]['border_right'];
21741 if (isset($tbd['s']) && $tbd['s']) {
21742 $this->_setBorderLine($tbd);
21744 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
21745 $this->y
= $y0 +
($tbd['w']/2);
21746 $this->_setDashBorder($tbd['style'],'',$continuingpage,'R');
21747 $this->Line($x0 +
$w - ($tbd['w']/2), $this->y
, $x0 +
$w - ($tbd['w']/2), $y0 +
$h - ($tbd['w']/2));
21751 $this->SetLineJoin(0);
21752 $this->SetLineCap(0);
21753 $this->Line($x0 +
$w - ($tbd['w']/2), $this->y
, $x0 +
$w - ($tbd['w']/2), $y0 +
$h);
21755 $this->y +
= $tbd['w'];
21756 // Reset Corners and Dash off
21757 $this->SetLineJoin(2);
21758 $this->SetLineCap(2);
21762 if ($this->blk
[$blvl]['border_bottom'] && $state > 1) {
21763 $tbd = $this->blk
[$blvl]['border_bottom'];
21764 if (isset($tbd['s']) && $tbd['s']) {
21765 $this->_setBorderLine($tbd);
21766 $this->y
= $y0 +
$h - ($tbd['w']/2);
21768 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
21769 $this->_setDashBorder($tbd['style'],'',$continuingpage,'B');
21770 $this->Line($x0 +
($tbd['w']/2) , $this->y
, $x0 +
$w - ($tbd['w']/2), $this->y
);
21773 $this->SetLineJoin(0);
21774 $this->SetLineCap(0);
21775 $this->Line($x0, $this->y
, $x0 +
$w, $this->y
);
21777 $this->y +
= $tbd['w'];
21778 // Reset Corners and Dash off
21779 $this->SetLineJoin(2);
21780 $this->SetLineCap(2);
21785 $this->y
= $save_y;
21789 function PaintImgBorder($objattr,$is_table) {
21790 // Borders are disabled in columns - messes up the repositioning in printcolumnbuffer
21791 if ($this->ColActive
) { return ; } // *COLUMNS*
21792 if ($is_table) { $k
= $this
->shrin_k
; } else { $k
= 1; }
21793 $h = (isset($objattr['BORDER-HEIGHT']) ? $objattr['BORDER-HEIGHT'] : 0);
21794 $w = (isset($objattr['BORDER-WIDTH']) ? $objattr['BORDER-WIDTH'] : 0);
21795 $x0 = (isset($objattr['BORDER-X']) ? $objattr['BORDER-X'] : 0);
21796 $y0 = (isset($objattr['BORDER-Y']) ? $objattr['BORDER-Y'] : 0);
21799 if ($objattr['border_top']) {
21800 $tbd = $objattr['border_top'];
21801 if (!empty($tbd['s'])) {
21802 $this->_setBorderLine($tbd,$k);
21803 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this
->_setDashBorder($tbd
['style'],'','','T'); }
21804 $this->Line($x0, $y0, $x0 +
$w, $y0);
21805 // Reset Corners and Dash off
21806 $this->SetLineJoin(2);
21807 $this->SetLineCap(2);
21811 if ($objattr['border_left']) {
21812 $tbd = $objattr['border_left'];
21813 if (!empty($tbd['s'])) {
21814 $this->_setBorderLine($tbd,$k);
21815 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this
->_setDashBorder($tbd
['style'],'','','L'); }
21816 $this->Line($x0, $y0, $x0, $y0 +
$h);
21817 // Reset Corners and Dash off
21818 $this->SetLineJoin(2);
21819 $this->SetLineCap(2);
21823 if ($objattr['border_right']) {
21824 $tbd = $objattr['border_right'];
21825 if (!empty($tbd['s'])) {
21826 $this->_setBorderLine($tbd,$k);
21827 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this
->_setDashBorder($tbd
['style'],'','','R'); }
21828 $this->Line($x0 +
$w, $y0, $x0 +
$w, $y0 +
$h);
21829 // Reset Corners and Dash off
21830 $this->SetLineJoin(2);
21831 $this->SetLineCap(2);
21835 if ($objattr['border_bottom']) {
21836 $tbd = $objattr['border_bottom'];
21837 if (!empty($tbd['s'])) {
21838 $this->_setBorderLine($tbd,$k);
21839 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this
->_setDashBorder($tbd
['style'],'','','B'); }
21840 $this->Line($x0, $y0 +
$h, $x0 +
$w, $y0 +
$h);
21841 // Reset Corners and Dash off
21842 $this->SetLineJoin(2);
21843 $this->SetLineCap(2);
21848 $this->SetAlpha(1);
21851 /*-- END HTML-CSS --*/
21857 $this->SetTColor($this->ConvertColor(0));
21858 $this->SetDColor($this->ConvertColor(0));
21859 $this->SetFColor($this->ConvertColor(255));
21860 $this->SetAlpha(1);
21861 $this->colorarray
= '';
21863 $this->spanbgcolorarray
= '';
21864 $this->spanbgcolor
= false;
21865 $this->spanborder
= false;
21866 $this->spanborddet
= array();
21868 $this->ResetStyles();
21871 $this->textparam
= array();
21872 $this->SetTextOutline();
21874 $this->SUP
= false;
21875 $this->SUB
= false;
21876 $this->strike
= false;
21877 $this->textshadow
= '';
21879 $this->SetFont($this->default_font
,'',0,false);
21880 $this->SetFontSize($this->default_font_size
,false);
21882 $this->currentfontfamily
= '';
21883 $this->currentfontsize
= '';
21886 if ($this->tableLevel
) {
21887 $this->SetLineHeight('',$this->table_lineheight
); // *TABLES*
21890 /*-- END TABLES --*/
21893 if ($this->listlvl
&& $this->list_lineheight
[$this->listlvl
][$this->bulletarray
['occur']]) {
21894 $this->SetLineHeight('',$this->list_lineheight
[$this->listlvl
][$this->bulletarray
['occur']]); // sets default line height
21897 /*-- END LISTS --*/
21898 if (isset($this->blk
[$this->blklvl
]['line_height']) && $this->blk
[$this->blklvl
]['line_height']) {
21899 $this->SetLineHeight('',$this->blk
[$this->blklvl
]['line_height']); // sets default line height
21902 $this->toupper
= false;
21903 $this->tolower
= false;
21904 $this->kerning
= false;
21905 $this->lSpacingCSS
= '';
21906 $this->wSpacingCSS
= '';
21907 $this->fixedlSpacing
= false;
21908 $this->minwSpacing
= 0;
21909 $this->capitalize
= false;
21910 $this->SetDash(); //restore to no dash
21911 $this->dash_on
= false;
21912 $this->dotted_on
= false;
21913 $this->divwidth
= 0;
21914 $this->divheight
= 0;
21915 $this->divalign
= '';
21916 $this->divrevert
= false;
21919 $bodystyle = array();
21920 if (isset($this->cssmgr
->CSS
['BODY']['FONT-STYLE'])) { $bodystyle
['FONT-STYLE'] = $this
->cssmgr
->CSS
['BODY']['FONT-STYLE']; }
21921 if (isset($this->cssmgr
->CSS
['BODY']['FONT-WEIGHT'])) { $bodystyle
['FONT-WEIGHT'] = $this
->cssmgr
->CSS
['BODY']['FONT-WEIGHT']; }
21922 if (isset($this->cssmgr
->CSS
['BODY']['COLOR'])) { $bodystyle
['COLOR'] = $this
->cssmgr
->CSS
['BODY']['COLOR']; }
21923 if (isset($bodystyle)) { $this
->setCSS($bodystyle
,'BLOCK','BODY'); }
21928 function ReadMetaTags($html) {
21929 // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)
21930 $regexp = '/ (\\w+?)=([^\\s>"]+)/si';
21931 $html = preg_replace($regexp," \$1=\"\$2\"",$html);
21932 if (preg_match('/<title>(.*?)<\/title>/si',$html,$m)) {
21933 $this->SetTitle($m[1]);
21935 preg_match_all('/<meta [^>]*?(name|content)="([^>]*?)" [^>]*?(name|content)="([^>]*?)".*?>/si',$html,$aux);
21936 $firstattr = $aux[1];
21937 $secondattr = $aux[3];
21938 for( $i = 0 ; $i < count($aux[0]) ; $i++
) {
21940 $name = ( strtoupper($firstattr[$i]) == "NAME" )? strtoupper($aux[2][$i]) : strtoupper($aux[4][$i]);
21941 $content = ( strtoupper($firstattr[$i]) == "CONTENT" )? $aux[2][$i] : $aux[4][$i];
21943 case "KEYWORDS": $this->SetKeywords($content); break;
21944 case "AUTHOR": $this->SetAuthor($content); break;
21945 case "DESCRIPTION": $this->SetSubject($content); break;
21951 function ReadCharset($html) {
21952 // Charset conversion
21953 if ($this->allow_charset_conversion
) {
21954 if (preg_match('/<head.*charset=([^\'\"\s]*).*<\/head>/si',$html,$m)) {
21955 if (strtoupper($m[1]) != 'UTF-8') {
21956 $this->charset_in
= strtoupper($m[1]);
21962 function setCSS($arrayaux,$type='',$tag='') { // type= INLINE | BLOCK | LIST // tag= BODY
21963 if (!is_array($arrayaux)) return; //Removes PHP Warning
21964 // Set font size first so that e.g. MARGIN 0.83em works on font size for this element
21965 if (isset($arrayaux['FONT-SIZE'])) {
21966 $v = $arrayaux['FONT-SIZE'];
21967 if(is_numeric($v[0])) {
21968 if ($type == 'BLOCK' && $this->blklvl
>0 && isset($this->blk
[$this->blklvl
-1]['InlineProperties']) && isset($this->blk
[$this->blklvl
-1]['InlineProperties']['size'])) {
21969 $mmsize = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['InlineProperties']['size']);
21972 $mmsize = $this->ConvertSize($v,$this->FontSize
);
21974 $this->SetFontSize( $mmsize*(_MPDFK
),false ); //Get size in points (pt)
21977 $v = strtoupper($v);
21978 if (isset($this->fontsizes
[$v])) {
21979 $this->SetFontSize( $this->fontsizes
[$v]* $this->default_font_size
,false);
21982 if ($tag == 'BODY') { $this
->SetDefaultFontSize($this
->FontSizePt
); }
21986 if ($this->useLang
&& !$this->usingCoreFont
) {
21987 if (isset($arrayaux['LANG']) && $arrayaux['LANG'] && $arrayaux['LANG'] != $this->default_lang
&& ((strlen($arrayaux['LANG']) == 5 && $arrayaux['LANG'] != 'UTF-8') || strlen($arrayaux['LANG']) == 2)) {
21988 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($arrayaux['LANG'], $this->useAdobeCJK
);
21989 if ($mpdf_pdf_unifonts) { $this
->RestrictUnicodeFonts($mpdf_pdf_unifonts
); }
21990 else { $this
->RestrictUnicodeFonts($this
->default_available_fonts
); }
21991 if ($tag == 'BODY') {
21992 $this->currentLang
= $arrayaux['LANG'];
21993 $this->default_lang
= $arrayaux['LANG'];
21994 if ($mpdf_pdf_unifonts) { $this
->default_available_fonts
= $mpdf_pdf_unifonts
; }
21998 $this->RestrictUnicodeFonts($this->default_available_fonts
);
22002 // FOR INLINE and BLOCK OR 'BODY'
22003 if (isset($arrayaux['FONT-FAMILY'])) {
22004 $v = $arrayaux['FONT-FAMILY'];
22005 //If it is a font list, get all font types
22006 $aux_fontlist = explode(",",$v);
22008 foreach($aux_fontlist AS $f) {
22009 $fonttype = trim($f);
22010 $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype);
22011 $fonttype = preg_replace('/ /','',$fonttype);
22012 $v = strtolower(trim($fonttype));
22013 if (isset($this->fonttrans
[$v]) && $this->fonttrans
[$v]) { $v
= $this
->fonttrans
[$v
]; }
22014 if ((!$this->onlyCoreFonts
&& in_array($v,$this->available_unifonts
)) ||
22015 in_array($v,array('ccourier','ctimes','chelvetica')) ||
22016 ($this->onlyCoreFonts
&& in_array($v,array('courier','times','helvetica','arial'))) ||
22017 in_array($v, array('sjis','uhc','big5','gb'))) {
22024 foreach($aux_fontlist AS $f) {
22025 $fonttype = trim($f);
22026 $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype);
22027 $fonttype = preg_replace('/ /','',$fonttype);
22028 $v = strtolower(trim($fonttype));
22029 if (isset($this->fonttrans
[$v]) && $this->fonttrans
[$v]) { $v
= $this
->fonttrans
[$v
]; }
22030 if (in_array($v,$this->sans_fonts
) || in_array($v,$this->serif_fonts
) || in_array($v,$this->mono_fonts
) ) {
22037 if ($tag == 'BODY') {
22038 $this->SetDefaultFont($fonttype);
22040 $this->SetFont($fonttype,$this->currentfontstyle
,0,false);
22043 $this->SetFont($this->currentfontfamily
,$this->currentfontstyle
,0,false);
22046 foreach($arrayaux as $k => $v) {
22047 if ($type != 'INLINE' && $tag != 'BODY' && $type != 'LIST') {
22051 $this->blk
[$this->blklvl
]['border_top'] = $this->border_details($v);
22052 if ($this->blk
[$this->blklvl
]['border_top']['s']) { $this
->blk
[$this
->blklvl
]['border'] = 1; }
22054 case 'BORDER-BOTTOM':
22055 $this->blk
[$this->blklvl
]['border_bottom'] = $this->border_details($v);
22056 if ($this->blk
[$this->blklvl
]['border_bottom']['s']) { $this
->blk
[$this
->blklvl
]['border'] = 1; }
22058 case 'BORDER-LEFT':
22059 $this->blk
[$this->blklvl
]['border_left'] = $this->border_details($v);
22060 if ($this->blk
[$this->blklvl
]['border_left']['s']) { $this
->blk
[$this
->blklvl
]['border'] = 1; }
22062 case 'BORDER-RIGHT':
22063 $this->blk
[$this->blklvl
]['border_right'] = $this->border_details($v);
22064 if ($this->blk
[$this->blklvl
]['border_right']['s']) { $this
->blk
[$this
->blklvl
]['border'] = 1; }
22068 case 'PADDING-TOP':
22069 $this->blk
[$this->blklvl
]['padding_top'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22071 case 'PADDING-BOTTOM':
22072 $this->blk
[$this->blklvl
]['padding_bottom'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22074 case 'PADDING-LEFT':
22075 $this->blk
[$this->blklvl
]['padding_left'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22077 case 'PADDING-RIGHT':
22078 $this->blk
[$this->blklvl
]['padding_right'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22083 $tmp = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22084 if (isset($this->blk
[$this->blklvl
]['lastbottommargin'])) {
22085 if ($tmp > $this->blk
[$this->blklvl
]['lastbottommargin']) {
22086 $tmp -= $this->blk
[$this->blklvl
]['lastbottommargin'];
22092 $this->blk
[$this->blklvl
]['margin_top'] = $tmp;
22094 case 'MARGIN-BOTTOM':
22095 $this->blk
[$this->blklvl
]['margin_bottom'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22097 case 'MARGIN-LEFT':
22098 $this->blk
[$this->blklvl
]['margin_left'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22100 case 'MARGIN-RIGHT':
22101 $this->blk
[$this->blklvl
]['margin_right'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22104 /*-- BORDER-RADIUS --*/
22105 case 'BORDER-TOP-LEFT-RADIUS-H':
22106 $this->blk
[$this->blklvl
]['border_radius_TL_H'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22108 case 'BORDER-TOP-LEFT-RADIUS-V':
22109 $this->blk
[$this->blklvl
]['border_radius_TL_V'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22111 case 'BORDER-TOP-RIGHT-RADIUS-H':
22112 $this->blk
[$this->blklvl
]['border_radius_TR_H'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22114 case 'BORDER-TOP-RIGHT-RADIUS-V':
22115 $this->blk
[$this->blklvl
]['border_radius_TR_V'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22117 case 'BORDER-BOTTOM-LEFT-RADIUS-H':
22118 $this->blk
[$this->blklvl
]['border_radius_BL_H'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22120 case 'BORDER-BOTTOM-LEFT-RADIUS-V':
22121 $this->blk
[$this->blklvl
]['border_radius_BL_V'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22123 case 'BORDER-BOTTOM-RIGHT-RADIUS-H':
22124 $this->blk
[$this->blklvl
]['border_radius_BR_H'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22126 case 'BORDER-BOTTOM-RIGHT-RADIUS-V':
22127 $this->blk
[$this->blklvl
]['border_radius_BR_V'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22129 /*-- END BORDER-RADIUS --*/
22132 $bs = $this->cssmgr
->setCSSboxshadow($v);
22133 if ($bs) { $this
->blk
[$this
->blklvl
]['box_shadow'] = $bs
; }
22136 case 'BACKGROUND-CLIP':
22137 if (strtoupper($v) == 'PADDING-BOX') { $this
->blk
[$this
->blklvl
]['background_clip'] = 'padding-box'; }
22138 else if (strtoupper($v) == 'CONTENT-BOX') { $this
->blk
[$this
->blklvl
]['background_clip'] = 'content-box'; } // mPDF 5.6.09
22141 case 'PAGE-BREAK-AFTER':
22142 if (strtoupper($v) == 'AVOID') { $this
->blk
[$this
->blklvl
]['page_break_after_avoid'] = true; }
22143 else if (strtoupper($v) == 'ALWAYS' || strtoupper($v) == 'LEFT' || strtoupper($v) == 'RIGHT') { $this
->blk
[$this
->blklvl
]['page_break_after'] = strtoupper($v
) ; }
22147 if (strtoupper($v) != 'AUTO') {
22148 $this->blk
[$this->blklvl
]['css_set_width'] = $this->ConvertSize($v,$this->blk
[$this->blklvl
-1]['inner_width'],$this->FontSize
,false);
22152 case 'TEXT-INDENT':
22153 // Left as raw value (may include 1% or 2em)
22154 $this->blk
[$this->blklvl
]['text_indent'] = $v;
22157 }//end of switch($k)
22161 if ($type != 'INLINE' && $type != 'LIST') { // includes BODY tag
22164 case 'MARGIN-COLLAPSE': // Custom tag to collapse margins at top and bottom of page
22165 if (strtoupper($v) == 'COLLAPSE') { $this
->blk
[$this
->blklvl
]['margin_collapse'] = true; }
22168 case 'LINE-HEIGHT':
22169 $this->blk
[$this->blklvl
]['line_height'] = $this->fixLineheight($v);
22170 if (!$this->blk
[$this->blklvl
]['line_height'] ) { $this
->blk
[$this
->blklvl
]['line_height'] = $this
->normalLineheight
; }
22173 case 'TEXT-ALIGN': //left right center justify
22174 switch (strtoupper($v)) {
22176 $this->blk
[$this->blklvl
]['align']="L";
22179 $this->blk
[$this->blklvl
]['align']="C";
22182 $this->blk
[$this->blklvl
]['align']="R";
22185 $this->blk
[$this->blklvl
]['align']="J";
22190 /*-- BACKGROUNDS --*/
22191 case 'BACKGROUND-GRADIENT':
22192 if ($type == 'BLOCK') {
22193 $this->blk
[$this->blklvl
]['gradient'] = $v;
22196 /*-- END BACKGROUNDS --*/
22199 if ($v) { $this
->blk
[$this
->blklvl
]['direction'] = strtolower($v
); }
22202 }//end of switch($k)
22206 if ($type == 'INLINE' || $type == 'LIST') {
22208 case 'DISPLAY': // Custom tag to collapse margins at top and bottom of page
22209 if (strtoupper($v) == 'NONE') { $this
->inlineDisplayOff
= true; }
22213 }//end of switch($k)
22216 if ($type == 'INLINE') {
22220 $this->spanborddet
['T'] = $this->border_details($v);
22221 $this->spanborder
= true;
22223 case 'BORDER-BOTTOM':
22224 $this->spanborddet
['B'] = $this->border_details($v);
22225 $this->spanborder
= true;
22227 case 'BORDER-LEFT':
22228 $this->spanborddet
['L'] = $this->border_details($v);
22229 $this->spanborder
= true;
22231 case 'BORDER-RIGHT':
22232 $this->spanborddet
['R'] = $this->border_details($v);
22233 $this->spanborder
= true;
22236 case 'VISIBILITY': // block is set in OpenTag
22237 $v = strtolower($v);
22238 if ($v == 'visible' || $v == 'hidden' || $v == 'printonly' || $v == 'screenonly') {
22239 $this->textparam
['visibility'] = $v;
22242 }//end of switch($k)
22246 // FOR INLINE and BLOCK
22248 case 'TEXT-ALIGN': //left right center justify
22249 if (strtoupper($v) == 'NOJUSTIFY' && $this->blk
[$this->blklvl
]['align']=="J") {
22250 $this->blk
[$this->blklvl
]['align']="";
22253 // bgcolor only - to stay consistent with original html2fpdf
22255 case 'BACKGROUND-COLOR':
22256 $cor = $this->ConvertColor($v);
22258 if ($tag == 'BODY') {
22259 $this->bodyBackgroundColor
= $cor;
22261 else if ($type == 'INLINE' || $type == 'LIST') {
22262 $this->spanbgcolorarray
= $cor;
22263 $this->spanbgcolor
= true;
22266 $this->blk
[$this->blklvl
]['bgcolorarray'] = $cor;
22267 $this->blk
[$this->blklvl
]['bgcolor'] = true;
22270 else if ($type != 'INLINE' && $type != 'LIST') {
22271 if ($this->ColActive
|| $this->keep_block_together
) {
22272 $this->blk
[$this->blklvl
]['bgcolorarray'] = $this->blk
[$this->blklvl
-1]['bgcolorarray'] ;
22273 $this->blk
[$this->blklvl
]['bgcolor'] = $this->blk
[$this->blklvl
-1]['bgcolor'] ;
22278 // auto | normal | none
22279 case 'FONT-KERNING':
22280 if ((strtoupper($v) == 'NORMAL' || strtoupper($v) == 'AUTO') && $this->useKerning
) { $this
->kerning
= true; }
22281 else if (strtoupper($v) == 'NONE') { $this
->kerning
= false; }
22285 // normal | <length>
22286 case 'LETTER-SPACING':
22287 $this->lSpacingCSS
= $v;
22288 if (($this->lSpacingCSS
|| $this->lSpacingCSS
==='0') && strtoupper($this->lSpacingCSS
) != 'NORMAL') {
22289 $this->fixedlSpacing
= $this->ConvertSize($this->lSpacingCSS
,$this->FontSize
);
22293 // normal | <length>
22294 case 'WORD-SPACING':
22295 $this->wSpacingCSS
= $v;
22296 if ($this->wSpacingCSS
&& strtoupper($this->wSpacingCSS
) != 'NORMAL') {
22297 $this->minwSpacing
= $this->ConvertSize($this->wSpacingCSS
,$this->FontSize
);
22301 case 'FONT-STYLE': // italic normal oblique
22302 switch (strtoupper($v)) {
22305 $this->SetStyle('I',true);
22308 $this->SetStyle('I',false);
22313 case 'FONT-WEIGHT': // normal bold //Does not support: bolder, lighter, 100..900(step value=100)
22314 switch (strtoupper($v)) {
22316 $this->SetStyle('B',true);
22319 $this->SetStyle('B',false);
22324 case 'VERTICAL-ALIGN': //super and sub only dealt with here e.g. <SUB> and <SUP>
22325 switch (strtoupper($v)) {
22328 $this->SUB
=false; // mPDF 5.6.07
22332 $this->SUP
=false; // mPDF 5.6.07
22334 case 'BASELINE': // mPDF 5.6.07
22341 case 'TEXT-DECORATION': // none underline line-through (strikeout) //Does not support: overline, blink
22342 if (stristr($v,'LINE-THROUGH')) {
22343 $this->strike
= true;
22345 else if (stristr($v,'UNDERLINE')) {
22346 $this->SetStyle('U',true);
22348 else if (stristr($v,'NONE')) {
22349 $this->SetStyle('U',false);
22350 $this->strike
= false; // mPDF 5.6.07
22354 case 'FONT-VARIANT':
22355 switch (strtoupper($v)) {
22357 $this->SetStyle('S',true);
22360 $this->SetStyle('S',false);
22365 case 'TEXT-TRANSFORM': // none uppercase lowercase //Does support: capitalize
22366 switch (strtoupper($v)) { //Not working 100%
22368 $this->capitalize
=true;
22371 $this->toupper
=true;
22374 $this->tolower
=true;
22376 case 'NONE': break;
22380 case 'TEXT-SHADOW':
22381 $ts = $this->cssmgr
->setCSStextshadow($v);
22382 if ($ts) { $this
->textshadow
= $ts
; }
22385 case 'HYPHENS': // mPDF 5.6.08
22386 if (strtoupper($v)=='NONE') {
22387 $this->textparam
['hyphens'] = 2;
22389 else if (strtoupper($v)=='AUTO') {
22390 $this->textparam
['hyphens'] = 1;
22392 else if (strtoupper($v)=='MANUAL') {
22393 $this->textparam
['hyphens'] = 0;
22397 case 'TEXT-OUTLINE': // mPDF 5.6.07
22398 if (strtoupper($v)=='NONE') {
22399 $this->textparam
['outline-s'] = false;
22403 case 'TEXT-OUTLINE-WIDTH': // mPDF 5.6.07
22404 case 'OUTLINE-WIDTH':
22405 switch(strtoupper($v)) {
22406 case 'THIN': $v = '0.03em'; break;
22407 case 'MEDIUM': $v = '0.05em'; break;
22408 case 'THICK': $v = '0.07em'; break;
22410 $w = $this->ConvertSize($v,$this->blk
[$this->blklvl
]['inner_width'],$this->FontSize
);
22412 $this->textparam
['outline-WIDTH'] = $w;
22413 $this->textparam
['outline-s'] = true;
22415 else { $this
->textparam
['outline-s'] = false; }
22418 case 'TEXT-OUTLINE-COLOR': // mPDF 5.6.07
22419 case 'OUTLINE-COLOR':
22420 if (strtoupper($v) == 'INVERT') {
22421 if ($this->colorarray
) {
22422 $cor = $this->colorarray
;
22423 $this->textparam
['outline-COLOR'] = $this->_invertColor($cor);
22426 $this->textparam
['outline-COLOR'] = $this->ConvertColor(255);
22430 $cor = $this->ConvertColor($v);
22431 if ($cor) { $this
->textparam
['outline-COLOR'] = $cor
; }
22435 case 'COLOR': // font color
22436 $cor = $this->ConvertColor($v);
22438 $this->colorarray
= $cor;
22439 $this->SetTColor($cor);
22444 }//end of switch($k)
22450 /*-- END HTML-CSS --*/
22453 function SetStyle($tag,$enable) {
22454 $this->$tag=$enable;
22456 foreach(array('B','I','U','S') as $s) {
22461 if ($this->S
&& empty($this->upperCase
)) { @include(_MPDF_PATH
.'includes/upperCase.php'); }
22462 $this->currentfontstyle
=$style;
22463 $this->SetFont('',$style,0,false);
22466 // Set multiple styles at one $str e.g. "BIS"
22467 function SetStylesArray($arr) {
22469 foreach(array('B','I','U','S') as $s) {
22470 if (isset($arr[$s])) {
22475 else { $this
->$s
= false; }
22477 else if ($this->$s) { $style
.=$s
; }
22479 $this->currentfontstyle
=$style;
22480 $this->SetFont('',$style,0,false);
22483 // Set multiple styles at one $str e.g. "BIS"
22484 function SetStyles($str) {
22486 foreach(array('B','I','U','S') as $s) {
22487 if (strpos($str,$s) !== false) {
22491 else { $this
->$s
= false; }
22493 $this->currentfontstyle
=$style;
22494 $this->SetFont('',$style,0,false);
22497 function ResetStyles() {
22498 foreach(array('B','I','U','S') as $s) {
22501 $this->currentfontstyle
='';
22502 $this->SetFont('','',0,false);
22506 function DisableTags($str='')
22508 if ($str == '') //enable all tags
22510 //Insert new supported tags in the long string below.
22511 $this->enabledtags
= "<span><s><strike><del><bdo><big><small><ins><cite><acronym><font><sup><sub><b><u><i><a><strong><em><code><samp><tt><kbd><var><q><table><thead><tfoot><tbody><tr><th><td><ol><ul><li><dl><dt><dd><form><input><select><textarea><option><div><p><h1><h2><h3><h4><h5><h6><pre><center><blockquote><address><hr><img><br><indexentry><indexinsert><bookmark><watermarktext><watermarkimage><tts><ttz><tta><column_break><columnbreak><newcolumn><newpage><page_break><pagebreak><formfeed><columns><toc><tocentry><tocpagebreak><pageheader><pagefooter><setpageheader><setpagefooter><sethtmlpageheader><sethtmlpagefooter><annotation><template><jpgraph><barcode><dottab><caption><textcircle><fieldset><legend><article><aside><figure><figcaption><footer><header><hgroup><nav><section><mark><details><summary><meter><progress><time>"; // mPDF 5.5.09
22515 $str = explode(",",$str);
22516 foreach($str as $v) $this->enabledtags
= str_replace(trim($v),'',$this->enabledtags
);
22523 function finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight) {
22524 $af = 0; // Above font
22525 $bf = 0; // Below font
22526 $mta = 0; // Maximum top-aligned
22527 $mba = 0; // Maximum bottom-aligned
22529 $af = max($af, ($lhxt['BS'] - ($maxfontsize * (0.5 +
$this->baselineC
))));
22532 $af = max($af, ($lhxt['M'] - $maxfontsize)/2);
22533 $bf = max($bf, ($lhxt['M'] - $maxfontsize)/2);
22536 $bf = max($bf, ($lhxt['TT'] - $maxfontsize));
22539 $af = max($af, ($lhxt['TB'] - $maxfontsize));
22542 $mta = max($mta, $lhxt['T']);
22545 $mba = max($mba, $lhxt['B']);
22547 if ((!$lhfixed || !$forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
22548 $maxlineHeight = $maxfontsize +
$af +
$bf;
22550 else if (!$lhfixed) { $af
= $bf
= ($maxlineHeight
- $maxfontsize
)/2; }
22551 if ($mta > $maxlineHeight) {
22552 $bf +
= ($mta - $maxlineHeight);
22553 $maxlineHeight = $mta;
22555 if ($mba > $maxlineHeight) {
22556 $af +
= ($mba - $maxlineHeight);
22557 $maxlineHeight = $mba;
22559 return $maxlineHeight;
22562 function TableWordWrap($maxwidth, $forcewrap = 0, $textbuffer = '', $def_fontsize, $returnarray=false) { // NB ** returnarray used in flowchart
22566 $textbuffer[0][0] = preg_replace('/^[ ]*/','',$textbuffer[0][0]);
22567 if ((count($textbuffer) == 0) or ((count($textbuffer) == 1) && ($textbuffer[0][0] == ''))) { return 0; }
22571 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight
)) { $lhfixed
= true; }
22572 if ($lhfixed) { $def_lineheight
= $this
->_computeLineheight($this
->table_lineheight
, $def_fontsize
);}
22573 else { $def_lineheight
= 0; }
22574 // START OF NEW LINE
22575 // Initialise lineheight variables
22577 $forceExactLineheight = true;
22578 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22579 $maxlineHeight = $def_lineheight ;
22582 $ln = 1; // Counts line number
22583 $mxw = $this->GetCharWidth('W',false);
22584 for($cctr=0;$cctr<count($textbuffer);$cctr++
) { // mPDF 5.6.22
22585 $chunk = $textbuffer[$cctr]; // mPDF 5.6.22
22588 if (substr($line,0,3) == "\xbb\xa4\xac") { //identifier has been identified!
22589 $objattr = $this->_getObjAttr($line);
22590 if ($objattr['type'] == 'nestedtable') {
22592 // Finalise & add lineheight
22593 $ch +
= $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22594 $level = $objattr['level'];
22595 $ih = $this->table
[($level+
1)][$objattr['nestedcontent']]['h']; // nested table width
22597 // START OF NEW LINE
22598 // Initialise lineheight variables
22601 $forceExactLineheight = true;
22602 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22603 $maxlineHeight = $def_lineheight ;
22609 list($skipln,$iw,$ih) = $this->inlineObject((isset($specialcontent['type']) ? $specialcontent['type'] : null),0,0, $objattr, $this->lMargin
,$width,$maxwidth,$maxlineHeight,false,true);
22610 if ($objattr['type'] == 'hr') {
22612 // Finalise & add lineheight
22613 $ch +
= $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22616 // START OF NEW LINE
22617 // Initialise lineheight variables
22620 $forceExactLineheight = true;
22621 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22622 $maxlineHeight = $def_lineheight ;
22628 if ($skipln==1 || $skipln==-2) {
22629 // Finish last line
22631 // Finalise & add lineheight
22632 $ch +
= $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22633 // START OF NEW LINE
22634 // Initialise lineheight variables
22636 $forceExactLineheight = true;
22637 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22638 $maxlineHeight = $def_lineheight ;
22643 $va = (isset($objattr['vertical-align']) ? $objattr['vertical-align'] : null);
22645 $lhxt[$va] = max($lhxt[$va], $ih);
22647 if ($lhfixed && $ih > $def_fontsize) { $forceExactLineheight
= false; }
22648 $maxlineHeight = max($maxlineHeight ,$ih);
22653 // SET FONT SIZE/STYLE from $chunk[n]
22655 if(isset($chunk[11]) and $chunk[11] != '') {
22656 if ($this->shrin_k
) {
22657 $this->SetFontSize($chunk[11]/$this->shrin_k
,false);
22660 $this->SetFontSize($chunk[11],false);
22663 if ($line == "\n") {
22665 $maxfontsize = max($maxfontsize,$this->FontSize
);
22666 $fh = $this->_computeLineheight($this->table_lineheight
);
22667 if ($lhfixed && $this->FontSize
> $def_fontsize) {
22668 $fh = $this->FontSize
;
22669 $forceExactLineheight = false;
22671 $maxlineHeight = max($maxlineHeight,$fh);
22673 // Finalise & add lineheight
22674 $ch +
= $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22675 // START OF NEW LINE
22676 // Initialise lineheight variables
22678 $forceExactLineheight = true;
22679 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22680 $maxlineHeight = $this->_computeLineheight($this->table_lineheight
);
22684 if(isset($chunk[11]) and $chunk[11] != '') {
22685 $this->SetFontSize($this->default_font_size
,false);
22690 $lbw = $rbw = 0; // Border widths
22691 if(isset($chunk[16]) && !empty($chunk[16])) { //Border
22692 $this->spanborddet
= $chunk[16];
22693 if (isset($this->spanborddet
['L'])) $lbw = $this->spanborddet
['L']['w'];
22694 if (isset($this->spanborddet
['R'])) $rbw = $this->spanborddet
['R']['w'];
22696 if(isset($chunk[15])) { // Word spacing
22697 $this->wSpacingCSS
= $chunk[15];
22698 if ($this->wSpacingCSS
&& strtoupper($this->wSpacingCSS
) != 'NORMAL') {
22699 $this->minwSpacing
= $this->ConvertSize($this->wSpacingCSS
,$this->FontSize
);
22702 if(isset($chunk[14])) { // Letter spacing
22703 $this->lSpacingCSS
= $chunk[14];
22704 if (($this->lSpacingCSS
|| $this->lSpacingCSS
==='0') && strtoupper($this->lSpacingCSS
) != 'NORMAL') {
22705 $this->fixedlSpacing
= $this->ConvertSize($this->lSpacingCSS
,$this->FontSize
);
22708 if(isset($chunk[13])) { // Font Kerning
22709 $this->kerning
= $chunk[13];
22711 if(isset($chunk[9])) { // Text params - Outline, hyphens // mPDF 5.6.08
22712 $this->textparam
= $chunk[9];
22715 if(isset($chunk[4]) and $chunk[4] != '') { $font
= $this
->SetFont($chunk
[4],$this
->FontStyle
,0,false); }
22717 // FONT STYLE B I U
22718 if(isset($chunk[2]) and $chunk[2] != '') {
22719 $this->SetStyles($chunk[2]);
22722 $space = $this->GetCharWidth(' ',false);
22724 if (mb_substr($line,0,1,$this->mb_enc
) == ' ') { // line (chunk) starts with a space
22729 if (mb_substr($line,(mb_strlen($line,$this->mb_enc
)-1),1,$this->mb_enc
) == ' ') { $lsend
= true; } // line (chunk) ends with a space
22730 else { $lsend
= false; }
22731 $line= trim($line);
22732 if ($line == '') { continue; }
22735 if ($this->iterationCounter
) $line = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/','\\1', $line);
22737 $words = explode(' ', $line);
22739 foreach ($words as $k=>$word) {
22740 $word = trim($word);
22741 $wordwidth = $this->GetStringWidth($word);
22742 if ($k==0) { $wordwidth +
= $lbw
; }
22743 if ($k==(count($words)-1)) { $wordwidth +
= $rbw
; }
22744 //maxwidth is insufficient for one word
22745 if ($wordwidth > $maxwidth +
0.0001) {
22747 while($wordwidth > $maxwidth +
0.0001) {
22748 $chw = 0; // check width
22749 $oneCJKorphan = false;
22750 $mlen = mb_strlen($word, $this->mb_enc
);
22751 for ( $i = 0; $i < $mlen; $i++
) {
22752 $chw = $this->GetStringWidth(mb_substr($word,0,$i+
1,$this->mb_enc
));
22753 if ($k==0) { $chw +
= $lbw
; }
22754 if ($k==(count($words)-1)) { $chw +
= $rbw
; }
22755 if ($chw > $maxwidth) {
22756 if ($i==0 && $firstchunk) {
22757 // If first letter of line does not fit
22758 $wordwidth = $maxwidth - 0.0001;
22759 if ($this->debug
) { $this
->Error("Table cell width calculated less than that needed for one character!"); }
22762 /*-- CJK-FONTS --*/
22763 // mPDF 5.6.40 mPDF 5.6.44
22764 if ($this->checkCJK
&& !$this->usingCoreFont
&& preg_match("/[".$this->pregCJKchars
."]/u", $word)) { // mPDF 5.6.44
22765 if (!$oneCJKorphan && preg_match('/['.$this->CJKoverflow
.']$/u',mb_substr($word,0,$i+
1,$this->mb_enc
)) && $this->allowCJKorphans
) {
22766 $wordwidth = $maxwidth - 0.0001;
22767 $oneCJKorphan = true;
22771 // Last character that fits is not allowed to end a line - move lastchar(s) to start of next line
22772 if ($i>0 && preg_match("/[".$this->CJKleading
."$]/u", mb_substr($word,0,$i,$this->mb_enc
))) {
22775 // Next character is not allowed to start a new line
22776 else if (preg_match("/[".$this->CJKfollowing
."]/u", mb_substr($word,$i,1,$this->mb_enc
))) {
22777 // try squeezing another character(s) onto this line = Oikomi
22778 if ($this->allowCJKorphans
&& !$oneCJKorphan) {
22779 //if lookahead is not another following char
22780 if ($i==($mlen-1) || ($i<($mlen-1) && !preg_match("/[".$this->CJKfollowing
."]/u", mb_substr($word,$i+
1,1,$this->mb_enc
)))) {
22781 $wordwidth = $maxwidth - 0.0001;
22782 $oneCJKorphan = true;
22786 // or move lastchar(s) to next line
22790 // CJK numerals kept together
22791 else if (preg_match("/([".$this->pregCJKchars
."]+[0-9\x{ff10}-\x{ff19}]+$)/u", mb_substr($word,0,$i,$this->mb_enc
)) && preg_match("/^([0-9\x{ff10}-\x{ff19}]+[".$this->pregCJKchars
."]+)/u", mb_substr($word,$i,16,$this->mb_enc
))) {
22795 //move lastchar(s) to next line
22796 $m0 = mb_substr($word,$i-1,1,$this->mb_enc
); // chars to move
22797 $m1 = mb_substr($word,0,$i-1,$this->mb_enc
); // str after stripped chars to move
22799 if ($cjkfix == 3) { $match
= "0-9\x{ff10}-\x{ff19}"; }
22800 else { $match
= $this
->CJKleading
; }
22801 while(preg_match("/[".$match."$]/u", $m1) && mb_strlen($m1, $this->mb_enc
)>2) {
22802 $m0 = mb_substr($m1,$mi-1,1,$this->mb_enc
).$m0; // chars to move
22803 $m1 = mb_substr($m1,0,$mi-1,$this->mb_enc
); // str after stripped chars to move
22806 // Insert $m0 into $word at $i
22807 $word = mb_substr($word,0,$i,$this->mb_enc
) . $m0 . mb_substr($word,$i,mb_strlen($word, $this->mb_enc
)-$i,$this->mb_enc
);
22808 $mlen = mb_strlen($word, $this->mb_enc
); // increment max for loop counter
22814 /*-- END CJK-FONTS --*/
22816 if ($text && $firstchunk) {
22818 // Finalise & add lineheight
22819 $maxfontsize = max($maxfontsize,$this->FontSize
);
22820 $fh = $this->_computeLineheight($this->table_lineheight
);
22821 if ($lhfixed && $this->FontSize
> $def_fontsize) {
22822 $fh = $this->FontSize
;
22823 $forceExactLineheight = false;
22825 $maxlineHeight = max($maxlineHeight,$fh);
22826 $ch +
= $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22827 // START OF NEW LINE
22828 // Initialise lineheight variables
22829 $maxfontsize = $this->FontSize
;
22830 $forceExactLineheight = true;
22831 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22832 $maxlineHeight = $this->_computeLineheight($this->table_lineheight
);
22836 // Finalise & add lineheight
22837 $maxfontsize = max($maxfontsize,$this->FontSize
);
22838 $fh = $this->_computeLineheight($this->table_lineheight
);
22839 if ($lhfixed && $this->FontSize
> $def_fontsize) {
22840 $fh = $this->FontSize
;
22841 $forceExactLineheight = false;
22843 $maxlineHeight = max($maxlineHeight,$fh);
22844 $ch +
= $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22845 // START OF NEW LINE
22846 // Initialise lineheight variables
22847 $maxfontsize = $this->FontSize
;
22848 $forceExactLineheight = true;
22849 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22850 $maxlineHeight = $this->_computeLineheight($this->table_lineheight
);
22853 $text = mb_substr($word,0,$i,$this->mb_enc
);
22854 $word = mb_substr($word,$i,mb_strlen($word, $this->mb_enc
)-$i,$this->mb_enc
);
22855 $wordwidth = $this->GetStringWidth($word);
22861 if (mb_strlen($word, $this->mb_enc
)<2 && $wordwidth > $maxwidth +
0.0001) {
22862 $wordwidth = $maxwidth - 0.0001;
22863 if ($this->debug
) { $this
->Error("Table cell width calculated less than that needed for single character!"); }
22868 // Word fits on line...
22869 if ($width +
$wordwidth < $maxwidth +
0.0001) {
22870 $mxw = max($mxw, ($width+
$wordwidth));
22871 $width +
= $wordwidth +
$space;
22872 $text .= $word.' ';
22874 // Word does not fit on line...
22876 // mPDF 5.6.21 hard hyphens
22877 if ($this->textparam
['hyphens'] != 2 && preg_match('/\-/',$word)) {
22878 list($hardsuccess,$pre,$post,$prelength) = $this->hardHyphenate($word, ($maxwidth - $width)-$this->GetCharWidth("-", false));
22879 if ($hardsuccess) {
22882 $wordwidth = $this->GetStringWidth($word);
22883 if ($k==(count($words)-1)) { $wordwidth +
= $rbw
; }
22886 /*-- HYPHENATION --*/
22887 // Soft Hyphens chr(173)
22888 else if ($this->textparam
['hyphens'] != 2 && (!$this->usingCoreFont
&& preg_match("/\xc2\xad/",$word)) || ($this->usingCoreFont
&& preg_match("/".chr(173)."/",$word) && ($this->FontFamily
!='csymbol' && $this->FontFamily
!='czapfdingbats')) ) { // mPDF 5.6.06 5.6.08
22889 list($success,$pre,$post,$prelength) = $this->softHyphenate($word, ($maxwidth - $width));
22893 $wordwidth = $this->GetStringWidth($word);
22894 if ($k==(count($words)-1)) { $wordwidth +
= $rbw
; }
22897 else if ($this->textparam
['hyphens'] == 1) { // mPDF 5.6.06 5.6.08
22898 list($success,$pre,$post,$prelength) = $this->hyphenateWord($word, ($maxwidth - $width));
22902 $wordwidth = $this->GetStringWidth($word);
22903 if ($k==(count($words)-1)) { $wordwidth +
= $rbw
; }
22906 /*-- END HYPHENATION --*/
22910 if ( count($textbuffer)>1 && $cctr > 0 && $k==0
22911 && (substr($textbuffer[$cctr][0],0,3) != "\xbb\xa4\xac")
22912 && (substr($textbuffer[$cctr-1][0],0,3) != "\xbb\xa4\xac")
22913 && substr($textbuffer[$cctr-1][0],-1,1) != ' '
22914 && substr($textbuffer[$cctr][0],0,1) != ' '
22916 // Go back to find a space in a previous chunk of content
22918 for ($ix=$cctr-1;$ix>=0;$ix--) {
22919 if (preg_match('/[ ]/',$textbuffer[$ix][0])) { $found
= $ix
; break; }
22921 if ($found !== false) {
22922 $charpos = strrpos($textbuffer[$found][0],' ');
22924 $a1 = $a2 = $textbuffer[$found];
22926 $a2[0] = substr($textbuffer[$found][0], $charpos+
1, strlen($textbuffer[$found][0])-$charpos);
22927 $textbuffer[$found][0] = substr($textbuffer[$found][0], 0, $charpos);
22928 array_insert($textbuffer, $a1, $found+
1);
22929 array_insert($textbuffer, $a2, $found+
2);
22930 // Initialise all variables
22934 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight
)) { $lhfixed
= true; }
22935 if ($lhfixed) { $def_lineheight
= $this
->_computeLineheight($this
->table_lineheight
, $def_fontsize
);}
22936 else { $def_lineheight
= 0; }
22938 $forceExactLineheight = true;
22939 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22940 $maxlineHeight = $def_lineheight ;
22943 $ln = 1; // Counts line number
22944 $mxw = $this->GetCharWidth('W',false);
22953 // Finalise & add lineheight
22954 $maxfontsize = max($maxfontsize,$this->FontSize
);
22955 $fh = $this->_computeLineheight($this->table_lineheight
);
22956 if ($lhfixed && $this->FontSize
> $def_fontsize) {
22957 $fh = $this->FontSize
;
22958 $forceExactLineheight = false;
22960 $maxlineHeight = max($maxlineHeight,$fh);
22961 $ch +
= $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22963 // START OF NEW LINE
22964 // Initialise lineheight variables
22965 $maxfontsize = $this->FontSize
;
22966 $forceExactLineheight = true;
22967 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22968 $maxlineHeight = $this->_computeLineheight($this->table_lineheight
);
22970 $width = $wordwidth +
$space;
22973 $maxfontsize = max($maxfontsize,$this->FontSize
);
22974 $fh = $this->_computeLineheight($this->table_lineheight
);
22975 if ($lhfixed && $this->FontSize
> $def_fontsize) {
22976 $fh = $this->FontSize
;
22977 $forceExactLineheight = false;
22979 $maxlineHeight = max($maxlineHeight,$fh);
22982 // End of textbuffer chunk
22985 $text = rtrim($text);
22988 // RESET FONT SIZE/STYLE
22989 // RESETTING VALUES
22990 //Now we must deactivate what we have used
22991 if(isset($chunk[2]) and $chunk[2] != '') {
22992 $this->ResetStyles();
22994 if(isset($chunk[4]) and $chunk[4] != '') {
22995 $this->SetFont($this->default_font
,$this->FontStyle
,0,false);
22997 if(isset($chunk[11]) and $chunk[11] != '') {
22998 $this->SetFontSize($this->default_font_size
,false);
23000 $this->spanborddet
= array();
23001 $this->kerning
= false;
23002 $this->lSpacingCSS
= '';
23003 $this->wSpacingCSS
= '';
23004 $this->fixedlSpacing
= false;
23005 $this->minwSpacing
= 0;
23007 // Finalise lineheight if something output on line and add
23009 $ch +
= $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23011 if ($returnarray) { return array($ch
,$ln
,$mxw
); }
23012 else {
return $ch
; }
23017 function TableCheckMinWidth($maxwidth, $forcewrap = 0, $textbuffer) {
23020 if ((count($textbuffer) == 0) or ((count($textbuffer) == 1) && ($textbuffer[0][0] == ''))) { return 0; }
23022 foreach ($textbuffer as $chunk) {
23026 if ($this->iterationCounter
) $line = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/','\\1', $line);
23028 // IMAGES & FORM ELEMENTS
23029 if (substr($line,0,3) == "\xbb\xa4\xac") { //inline object - FORM element or IMAGE!
23030 $objattr = $this->_getObjAttr($line);
23031 if ($objattr['type']!='hr' && isset($objattr['width']) && ($objattr['width']/$this->shrin_k
) > ($maxwidth +
0.0001) ) {
23032 if (($objattr['width']/$this->shrin_k
) > $biggestword) { $biggestword
= ($objattr
['width']/$this
->shrin_k
); }
23038 if ($line == "\n") {
23041 $line = trim($line );
23042 // SET FONT SIZE/STYLE from $chunk[n]
23045 if(isset($chunk[11]) and $chunk[11] != '') {
23046 if ($this->shrin_k
) {
23047 $this->SetFontSize($chunk[11]/$this->shrin_k
,false);
23050 $this->SetFontSize($chunk[11],false);
23054 if(isset($chunk[4]) and $chunk[4] != '') { $font
= $this
->SetFont($chunk
[4],$this
->FontStyle
,0,false); }
23056 if(isset($chunk[2]) and $chunk[2] != '') {
23057 $this->SetStyles($chunk[2]);
23060 $lbw = $rbw = 0; // Border widths
23061 if(isset($chunk[16]) && !empty($chunk[16])) { //Border
23062 $this->spanborddet
= $chunk[16];
23063 $lbw = $this->spanborddet
['L']['w'];
23064 $rbw = $this->spanborddet
['R']['w'];
23066 if(isset($chunk[15])) { // Word spacing
23067 $this->wSpacingCSS
= $chunk[15];
23068 if ($this->wSpacingCSS
&& strtoupper($this->wSpacingCSS
) != 'NORMAL') {
23069 $this->minwSpacing
= $this->ConvertSize($this->wSpacingCSS
,$this->FontSize
);
23072 if(isset($chunk[14])) { // Letter spacing
23073 $this->lSpacingCSS
= $chunk[14];
23074 if (($this->lSpacingCSS
|| $this->lSpacingCSS
==='0') && strtoupper($this->lSpacingCSS
) != 'NORMAL') {
23075 $this->fixedlSpacing
= $this->ConvertSize($this->lSpacingCSS
,$this->FontSize
);
23078 if(isset($chunk[13])) { // Font Kerning
23079 $this->kerning
= $chunk[13];
23082 $words = explode(' ', $line);
23083 foreach ($words as $k=>$word) {
23084 $word = trim($word);
23085 $wordwidth = $this->GetStringWidth($word);
23086 if ($k==0) { $wordwidth +
= $lbw
; }
23087 if ($k==(count($words)-1)) { $wordwidth +
= $rbw
; }
23089 //Warn user that maxwidth is insufficient
23090 if ($wordwidth > $maxwidth +
0.0001) {
23091 if ($wordwidth > $biggestword) { $biggestword
= $wordwidth
; }
23096 // RESET FONT SIZE/STYLE
23097 // RESETTING VALUES
23098 //Now we must deactivate what we have used
23099 if(isset($chunk[2]) and $chunk[2] != '') {
23100 $this->ResetStyles();
23102 if(isset($chunk[4]) and $chunk[4] != '') {
23103 $this->SetFont($this->default_font
,$this->FontStyle
,0,false);
23105 if(isset($chunk[11]) and $chunk[11] != '') {
23106 $this->SetFontSize($this->default_font_size
,false);
23108 $this->spanborddet
= array();
23109 $this->kerning
= false;
23110 $this->lSpacingCSS
= '';
23111 $this->wSpacingCSS
= '';
23112 $this->fixedlSpacing
= false;
23113 $this->minwSpacing
= 0;
23116 //Return -(wordsize) if word is bigger than maxwidth
23118 if (($toonarrow) && ($this->table_error_report
)) {
23119 $this->Error("Word is too long to fit in table - ".$this->table_error_report_param
);
23121 if ($toonarrow) return -$biggestword;
23125 function shrinkTable(&$table,$k) {
23126 $table['border_spacing_H'] /= $k;
23127 $table['border_spacing_V'] /= $k;
23129 $table['padding']['T'] /= $k;
23130 $table['padding']['R'] /= $k;
23131 $table['padding']['B'] /= $k;
23132 $table['padding']['L'] /= $k;
23134 $table['margin']['T'] /= $k;
23135 $table['margin']['R'] /= $k;
23136 $table['margin']['B'] /= $k;
23137 $table['margin']['L'] /= $k;
23139 $table['border_details']['T']['w'] /= $k;
23140 $table['border_details']['R']['w'] /= $k;
23141 $table['border_details']['B']['w'] /= $k;
23142 $table['border_details']['L']['w'] /= $k;
23144 if (isset($table['max_cell_border_width']['T'])) $table['max_cell_border_width']['T'] /= $k;
23145 if (isset($table['max_cell_border_width']['R'])) $table['max_cell_border_width']['R'] /= $k;
23146 if (isset($table['max_cell_border_width']['B'])) $table['max_cell_border_width']['B'] /= $k;
23147 if (isset($table['max_cell_border_width']['L'])) $table['max_cell_border_width']['L'] /= $k;
23149 if ($this->simpleTables
){
23150 $table['simple']['border_details']['T']['w'] /= $k;
23151 $table['simple']['border_details']['R']['w'] /= $k;
23152 $table['simple']['border_details']['B']['w'] /= $k;
23153 $table['simple']['border_details']['L']['w'] /= $k;
23156 $table['miw'] /= $k;
23157 $table['maw'] /= $k;
23159 if ($this->cacheTables
) { $fh
= fopen($table
['cache'], "r+b"); }
23161 for($j = 0 ; $j < $table['nc'] ; $j++
) { //columns
23163 $table['wc'][$j]['miw'] /= $k;
23164 $table['wc'][$j]['maw'] /= $k;
23167 if (isset($table['decimal_align'][$j]['maxs0']) && $table['decimal_align'][$j]['maxs0']) { $table
['decimal_align'][$j
]['maxs0'] /= $k
; }
23168 if (isset($table['decimal_align'][$j]['maxs1']) && $table['decimal_align'][$j]['maxs1']) { $table
['decimal_align'][$j
]['maxs1'] /= $k
; }
23170 if (isset($table['wc'][$j]['absmiw']) && $table['wc'][$j]['absmiw'] ) $table['wc'][$j]['absmiw'] /= $k;
23172 for($i = 0 ; $i < $table['nr']; $i++
) { //rows
23173 if ($this->cacheTables
) {
23174 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
23177 $c = &$table['cells'][$i][$j];
23178 if (isset($c) && $c) {
23179 if (!$this->simpleTables
){
23180 if ($this->packTableData
) {
23181 $cell = $this->_unpackCellBorder($c['borderbin'] );
23182 $cell['border_details']['T']['w'] /= $k;
23183 $cell['border_details']['R']['w'] /= $k;
23184 $cell['border_details']['B']['w'] /= $k;
23185 $cell['border_details']['L']['w'] /= $k;
23186 $cell['border_details']['mbw']['TL'] /= $k;
23187 $cell['border_details']['mbw']['TR'] /= $k;
23188 $cell['border_details']['mbw']['BL'] /= $k;
23189 $cell['border_details']['mbw']['BR'] /= $k;
23190 $cell['border_details']['mbw']['LT'] /= $k;
23191 $cell['border_details']['mbw']['LB'] /= $k;
23192 $cell['border_details']['mbw']['RT'] /= $k;
23193 $cell['border_details']['mbw']['RB'] /= $k;
23194 $c['borderbin'] = $this->_packCellBorder($cell);
23197 $c['border_details']['T']['w'] /= $k;
23198 $c['border_details']['R']['w'] /= $k;
23199 $c['border_details']['B']['w'] /= $k;
23200 $c['border_details']['L']['w'] /= $k;
23201 $c['border_details']['mbw']['TL'] /= $k;
23202 $c['border_details']['mbw']['TR'] /= $k;
23203 $c['border_details']['mbw']['BL'] /= $k;
23204 $c['border_details']['mbw']['BR'] /= $k;
23205 $c['border_details']['mbw']['LT'] /= $k;
23206 $c['border_details']['mbw']['LB'] /= $k;
23207 $c['border_details']['mbw']['RT'] /= $k;
23208 $c['border_details']['mbw']['RB'] /= $k;
23211 $c['padding']['T'] /= $k;
23212 $c['padding']['R'] /= $k;
23213 $c['padding']['B'] /= $k;
23214 $c['padding']['L'] /= $k;
23216 if (isset($c['w'])) { $c
['w'] /= $k
; }
23220 if (isset($c['absmiw'])) $c['absmiw'] /= $k;
23221 if (isset($c['nestedmaw'])) $c['nestedmaw'] /= $k;
23222 if (isset($c['nestedmiw'])) $c['nestedmiw'] /= $k;
23223 if (isset($c['textbuffer'])) {
23224 foreach($c['textbuffer'] AS $n=>$tb) {
23225 if (!empty($tb[16])) {
23226 $c['textbuffer'][$n][16]['T']['w'] /= $k;
23227 $c['textbuffer'][$n][16]['B']['w'] /= $k;
23228 $c['textbuffer'][$n][16]['L']['w'] /= $k;
23229 $c['textbuffer'][$n][16]['R']['w'] /= $k;
23233 if ($this->cacheTables
) {
23234 $this->_cacheCell($c, '', "W", $fh, $table['cells'][$i][$j]);
23240 if ($this->cacheTables
) { fclose($fh
); }
23243 function _cacheCell($c, $file, $mode="A", $fh=null, $offset=0) { // mode = Append or (over)Write (needs offset and fh)
23244 // Requires either $file OR $fh (file_handle)
23245 if (!is_array($c) || !isset($c)) { return ''; }
23247 if(isset($c['w'])) { $cw
= $c
['w']; } else { $cw
= -1; }
23248 if(isset($c['w0'])) { $cw0
= $c
['w0']; } else { $cw0
= -1; }
23249 if(isset($c['h0'])) { $ch0
= $c
['h0']; } else { $ch0
= -1; }
23251 $data = pack("n2d19A1A1n2sA32A128",
23252 $c['colspan'], /* n (16 bit; 2 bytes) [pos 0] */
23253 $c['rowspan'], /* n (16 bit; 2 bytes) [pos 2] */
23254 $c['s'], /* d NB machine-dependent size (64 bit; 8 bytes on test winOS) [pos 4] */
23255 $c['maxs'], /* d NB machine-dependent size [pos 4 + 1*D] */
23256 $c['nestedmaw'], /* d NB machine-dependent size [pos 4 + 2*D] */
23257 $c['nestedmiw'], /* d NB machine-dependent size [pos 4 + 3*D] */
23258 $c['padding']['L'], /* d NB machine-dependent size [pos 4 + 4*D] */
23259 $c['padding']['R'], /* d NB machine-dependent size [pos 4 + 5*D] */
23260 $c['padding']['T'], /* d NB machine-dependent size [pos 4 + 6*D] */
23261 $c['padding']['B'], /* d NB machine-dependent size [pos 4 + 7*D] */
23262 $c['dfs'], /* d NB machine-dependent size [pos 4 + 8*D] */
23263 $cw, /* d NB machine-dependent size [pos 4 + 9*D] */
23264 $c['h'], /* d NB machine-dependent size [pos 4 + 10*D] */
23265 $c['absmiw'], /* d NB machine-dependent size [pos 4 + 11*D] */
23266 $c['maw'], /* d NB machine-dependent size [pos 4 + 12*D] */
23267 $c['miw'], /* d NB machine-dependent size [pos 4 + 13*D] */
23268 $c['mih'], /* d NB machine-dependent size [pos 4 + 14*D] */
23269 $c['x0'], /* d NB machine-dependent size [pos 4 + 15*D] */
23270 $cw0, /* d NB machine-dependent size [pos 4 + 16*D] */
23271 $c['y0'], /* d NB machine-dependent size [pos 4 + 17*D] */
23272 $ch0, /* d NB machine-dependent size [pos 4 + 18*D] */
23273 $c['a'], /* A1 (1 byte) [pos 4 + 19*D] */
23274 $c['va'], /* A1 (1 byte) [pos 5 + 19*D] */
23275 $c['nowrap'], /* 1 or blank n (16 bit; 2 bytes) [pos 6 + 19*D] */
23276 $c['wpercent'], /* 0 - 100 n (16 bit; 2 bytes) [pos 8 + 19*D] */
23277 $c['R'], /* 90 or -90 s (16 bit; 2 bytes) [pos 10 + 19*D] */
23278 $c['bgcolor'], /* A32 (32 bytes) [pos 12 + 19*D] */
23279 $c['gradient'] /* A128 (128 bytes) [pos 44 + 19*D] */
23282 if ($c['background-image']) {
23283 $data .= pack("n2d2A6A6n3dA4A128",
23284 strlen($data), /* offset in main data to start of bgimage data */
23285 $c['background-image']['image_id'], /* n */
23286 $c['background-image']['orig_w'], /* d NB machine-dependent size */
23287 $c['background-image']['orig_h'], /* d NB machine-dependent size */
23288 $c['background-image']['x_pos'], /* A6 calc size or "50%" */
23289 $c['background-image']['y_pos'], /* A6 calc size or "50%" */
23290 $c['background-image']['x_repeat'], /* n true or false*/
23291 $c['background-image']['y_repeat'], /* n true or false */
23292 $c['background-image']['resize'], /* n 0 - 6 */
23293 $c['background-image']['opacity'], /* d 0-1 */
23294 $c['background-image']['itype'], /* A4 jpg etc */
23295 $c['background-image']['gradient'] /* A128 CSS string */
23298 else $data .= pack("n",0);
23299 $tb_offset = 2 +
186 +
2 +
strlen($data);
23300 $stb = serialize($c['textbuffer']).' '; // buffer to allow updating in reverseTableDir
23301 $lentb = strlen($stb);
23302 $data2 = pack("nA".$lentb, $lentb, $stb);
23305 if ($mode=="W" && $offset) {
23306 if (!$fh) { $fh
= fopen($file
, "r+b"); } // Overwrite (but not truncate)
23307 else $tempfh = false;
23308 fseek($fh, $offset);
23311 $fh = fopen($file, "ab"); // APPEND
23313 fwrite($fh, pack("n",$tb_offset)); // Offset to Text buffer 2 bytes
23314 fwrite($fh, $c['borderbin']); // border details 186 bytes
23315 fwrite($fh, pack("n",strlen($data))); // Length of Main data
23316 fwrite($fh, $data); // Main data
23317 fwrite($fh, $data2); // Text buffer (starts with "n" length of text buffer)
23318 if ($tempfh) fclose($fh);
23319 return ($tb_offset +
2 +
$lentb);
23322 function _cacheUpdateTxB($c, $fh, $offset) {
23323 fseek($fh, $offset);
23324 $tb_offset = $this->read_short($fh); // First entry = Offset to Text buffer 2 bytes
23325 fseek($fh, ($tb_offset-2), SEEK_CUR
);
23326 $lentb = $this->read_short($fh); // First entry in textbuffer = Length of serialized textbuffer - do not update
23327 $stb = serialize($c['textbuffer']);
23328 fwrite($fh, pack("A".$lentb, $stb));
23331 function _cacheUpdateBorder($c, $fh, $offset) {
23333 fseek($fh, $offset);
23334 fwrite($fh, $c['borderbin']);
23337 function _cacheUpdateMtx($c, $fh, $offset, $var) {
23338 if ($var=='mih') { $offset +
= (2 +
186 +
2 +
4 +
14*_DSIZE
); }
23339 else if ($var=='x0') { $offset +
= (2 +
186 +
2 +
4 +
15*_DSIZE
); } // x0 and w0
23340 else if ($var=='y0') { $offset +
= (2 +
186 +
2 +
4 +
17*_DSIZE
); } // y0 and h0
23341 fseek($fh, $offset);
23342 if ($var=='mih') { fwrite($fh
, pack("d",$c
['mih'])); }
23343 else if ($var=='x0') { fwrite($fh
, pack("d2",$c
['x0'],$c
['w0'])); }
23344 else if ($var=='y0') { fwrite($fh
, pack("d2",$c
['y0'],$c
['h0'])); }
23347 function _uncacheCell($ptr, $file, $fh) {
23348 // Requires either $file or $fh (file_handle)
23349 if ($ptr==0) { return null; }
23350 if (is_array($ptr)) { $this
->Error("Probable cause - missing end tag </td>. You may be able to change the configurable variable: allow_html_optional_endtags "); }
23352 if (!$fh) { $fh
= fopen($file
, "rb"); }
23353 else $tempfh = false;
23356 $tb_offset = $this->read_short($fh); // First entry = Offset to Text buffer 2 bytes
23357 $c['borderbin'] = fread($fh,186); // border details 186 bytes
23358 $maindatalen = $this->read_short($fh); // Length of Main data (2 bytes)
23359 $str = fread($fh,$maindatalen ); // Main data
23360 $data = unpack("ncolspan/nrowspan/ds/dmaxs/dnmaw/dnmiw/dpl/dpr/dpt/dpb/ddfs/dw/dh/dabsmiw/dmaw/dmiw/dmih/dx0/dw0/dy0/dh0/A1a/A1va/nnowrap/nwpercent/sR/A32bgcol/A128grad/nbgimage", $str);
23362 if ($data['colspan']>0) $c['colspan'] = $data['colspan']; /* n */
23363 if ($data['rowspan']>0) $c['rowspan'] = $data['rowspan']; /* n */
23364 $c['s'] = $data['s']; /* d NB machine-dependent size */
23365 $c['maxs'] = $data['maxs']; /* d NB machine-dependent size */
23366 if ($data['nmaw']>0) $c['nestedmaw'] = $data['nmaw']; /* d NB machine-dependent size */
23367 if ($data['nmiw']>0) $c['nestedmiw'] = $data['nmiw']; /* d NB machine-dependent size */
23368 $c['padding']['L'] = $data['pl']; /* d NB machine-dependent size */
23369 $c['padding']['R'] = $data['pr']; /* d NB machine-dependent size */
23370 $c['padding']['T'] = $data['pt']; /* d NB machine-dependent size */
23371 $c['padding']['B'] = $data['pb']; /* d NB machine-dependent size */
23372 $c['dfs'] = $data['dfs']; /* d NB machine-dependent size */
23373 if ($data['w']>=0) $c['w'] = $data['w']; /* d NB machine-dependent size */
23374 if ($data['h']>0) $c['h'] = $data['h']; /* d NB machine-dependent size */
23375 if ($data['absmiw']>0) $c['absmiw'] = $data['absmiw']; /* d NB machine-dependent size */
23376 if ($data['maw']>0) $c['maw'] = $data['maw']; /* d NB machine-dependent size */
23377 if ($data['miw']>0) $c['miw'] = $data['miw']; /* d NB machine-dependent size */
23378 if ($data['mih']>0) $c['mih'] = $data['mih']; /* d NB machine-dependent size */
23379 if ($data['w0']>=0) { $c['w0'] = $data['w0']; /* d NB machine-dependent size */
23380 $c['x0'] = $data['x0']; } /* d NB machine-dependent size */
23381 if ($data['h0']>=0) { $c['h0'] = $data['h0']; /* d NB machine-dependent size */
23382 $c['y0'] = $data['y0']; } /* d NB machine-dependent size */
23383 $c['a'] = trim($data['a']); /* A1 */
23384 $c['va'] = trim($data['va']); /* A1 */
23385 if ($data['nowrap']) $c['nowrap'] = $data['nowrap']; /* 1 or blank n */
23386 else $c['nowrap'] = false;
23387 if ($data['wpercent']>0) $c['wpercent'] = $data['wpercent']; /* 0 - 100 n */
23388 if ($data['R']<>0) $c['R'] = $data['R']; /* 90 or -90 s */
23389 else $c['R'] = false;
23390 $c['bgcolor'] = trim($data['bgcol']); /* A32 */
23391 if (trim($data['grad']))
23392 $c['gradient'] = trim($data['grad']); /* A128 */
23393 else $c['gradient'] = false;
23394 if ($data['bgimage']>0) {
23395 $bgidata = substr($str, ($data['bgimage']+
2));
23396 $c['background-image'] = unpack("nimage_id/dorig_w/dorig_h/A6x_pos/A6y_pos/nx_repeat/ny_repeat/nresize/dopacity/A4itype/A128gradient", $bgidata);
23399 $tblen = $this->read_short($fh); // Length of Textbuffer
23400 $tbsp = fread($fh,$tblen); // Textbuffer (serialised and packed)
23401 $tbs = unpack("A".$tblen."textbuffer",$tbsp); // Textbuffer unpacked
23402 $c['textbuffer'] = unserialize(trim($tbs['textbuffer'])); // Textbuffer unserialized
23404 if ($tempfh) { fclose($fh
); }
23407 function read_short(&$fh) {
23409 $a = (ord($s[0])<<8) +
ord($s[1]);
23410 if ($a & (1 << 15) ) {
23411 $a = ($a - (1 << 16));
23415 function _backupCacheFiles() {
23416 foreach($this->table
AS $lvl=>$t) {
23417 foreach($this->table
[$lvl] AS $c=>$t2) {
23418 ///////////////////////////if (!file_exists($t2['cache'])) { echo $lvl; echo $c; print_r($this->table); exit; }
23419 copy( $t2['cache'], $t2['cache'].'.bak');
23423 function _restoreCacheFiles() {
23424 foreach($this->table
AS $lvl=>$t) {
23425 foreach($this->table
[$lvl] AS $c=>$t2) {
23426 copy( $t2['cache'].'.bak', $t2['cache']);
23432 function _packCellBorder($cell) {
23433 if (!is_array($cell) || !isset($cell)) { return ''; }
23435 if (!$this->packTableData
) { return $cell
; }
23437 $bindata = pack("nnda6A10nnda6A10nnda6A10nnda6A10nd9",
23439 $cell['border_details']['R']['s'],
23440 $cell['border_details']['R']['w'],
23441 $cell['border_details']['R']['c'],
23442 $cell['border_details']['R']['style'],
23443 $cell['border_details']['R']['dom'],
23445 $cell['border_details']['L']['s'],
23446 $cell['border_details']['L']['w'],
23447 $cell['border_details']['L']['c'],
23448 $cell['border_details']['L']['style'],
23449 $cell['border_details']['L']['dom'],
23451 $cell['border_details']['T']['s'],
23452 $cell['border_details']['T']['w'],
23453 $cell['border_details']['T']['c'],
23454 $cell['border_details']['T']['style'],
23455 $cell['border_details']['T']['dom'],
23457 $cell['border_details']['B']['s'],
23458 $cell['border_details']['B']['w'],
23459 $cell['border_details']['B']['c'],
23460 $cell['border_details']['B']['style'],
23461 $cell['border_details']['B']['dom'],
23463 $cell['border_details']['mbw']['BL'],
23464 $cell['border_details']['mbw']['BR'],
23465 $cell['border_details']['mbw']['RT'],
23466 $cell['border_details']['mbw']['RB'],
23467 $cell['border_details']['mbw']['TL'],
23468 $cell['border_details']['mbw']['TR'],
23469 $cell['border_details']['mbw']['LT'],
23470 $cell['border_details']['mbw']['LB'],
23472 $cell['border_details']['cellposdom']
23479 function _getBorderWidths($bindata) {
23480 if (!$bindata) { return array(0,0,0,0); }
23481 if (!$this->packTableData
) { return array($bindata
['border_details']['T']['w'], $bindata
['border_details']['R']['w'], $bindata
['border_details']['B']['w'], $bindata
['border_details']['L']['w']); }
23483 $bd = unpack("nbord/nrs/drw/a6rca/A10rst/nrd/nls/dlw/a6lca/A10lst/nld/nts/dtw/a6tca/A10tst/ntd/nbs/dbw/a6bca/A10bst/nbd/dmbl/dmbr/dmrt/dmrb/dmtl/dmtr/dmlt/dmlb/dcpd", $bindata);
23484 $cell['border_details']['R']['w'] = $bd['rw'];
23485 $cell['border_details']['L']['w'] = $bd['lw'];
23486 $cell['border_details']['T']['w'] = $bd['tw'];
23487 $cell['border_details']['B']['w'] = $bd['bw'];
23488 return array($bd['tw'], $bd['rw'], $bd['bw'], $bd['lw']);
23492 function _unpackCellBorder($bindata) {
23493 if (!$bindata) { return array(); }
23494 if (!$this->packTableData
) { return $bindata
; }
23496 $bd = unpack("nbord/nrs/drw/a6rca/A10rst/nrd/nls/dlw/a6lca/A10lst/nld/nts/dtw/a6tca/A10tst/ntd/nbs/dbw/a6bca/A10bst/nbd/dmbl/dmbr/dmrt/dmrb/dmtl/dmtr/dmlt/dmlb/dcpd", $bindata);
23498 $cell['border'] = $bd['bord'];
23499 $cell['border_details']['R']['s'] = $bd['rs'];
23500 $cell['border_details']['R']['w'] = $bd['rw'];
23501 $cell['border_details']['R']['c'] = $bd['rca'];
23502 $cell['border_details']['R']['style'] = trim($bd['rst']);
23503 $cell['border_details']['R']['dom'] = $bd['rd'];
23505 $cell['border_details']['L']['s'] = $bd['ls'];
23506 $cell['border_details']['L']['w'] = $bd['lw'];
23507 $cell['border_details']['L']['c'] = $bd['lca'];
23508 $cell['border_details']['L']['style'] = trim($bd['lst']);
23509 $cell['border_details']['L']['dom'] = $bd['ld'];
23511 $cell['border_details']['T']['s'] = $bd['ts'];
23512 $cell['border_details']['T']['w'] = $bd['tw'];
23513 $cell['border_details']['T']['c'] = $bd['tca'];
23514 $cell['border_details']['T']['style'] = trim($bd['tst']);
23515 $cell['border_details']['T']['dom'] = $bd['td'];
23517 $cell['border_details']['B']['s'] = $bd['bs'];
23518 $cell['border_details']['B']['w'] = $bd['bw'];
23519 $cell['border_details']['B']['c'] = $bd['bca'];
23520 $cell['border_details']['B']['style'] = trim($bd['bst']);
23521 $cell['border_details']['B']['dom'] = $bd['bd'];
23523 $cell['border_details']['mbw']['BL'] = $bd['mbl'];
23524 $cell['border_details']['mbw']['BR'] = $bd['mbr'];
23525 $cell['border_details']['mbw']['RT'] = $bd['mrt'];
23526 $cell['border_details']['mbw']['RB'] = $bd['mrb'];
23527 $cell['border_details']['mbw']['TL'] = $bd['mtl'];
23528 $cell['border_details']['mbw']['TR'] = $bd['mtr'];
23529 $cell['border_details']['mbw']['LT'] = $bd['mlt'];
23530 $cell['border_details']['mbw']['LB'] = $bd['mlb'];
23531 $cell['border_details']['cellposdom'] = $bd['cpd'];
23537 ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23538 ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23539 ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23540 //table Array of (w, h, bc, nr, wc, hr, cells)
23542 //h Height of table
23545 //hr List of height of each row
23546 //wc List of width of each column
23547 //cells List of cells of each rows, cells[i][j] is a cell in the table
23548 function _tableColumnWidth(&$table,$firstpass=false){
23549 $cs = &$table['cells'];
23551 $nc = $table['nc'];
23552 $nr = $table['nr'];
23553 $listspan = array();
23555 if ($table['borders_separate']) {
23556 $tblbw = $table['border_details']['L']['w'] +
$table['border_details']['R']['w'] +
$table['margin']['L'] +
$table['margin']['R'] +
$table['padding']['L'] +
$table['padding']['R'] +
$table['border_spacing_H'];
23558 else { $tblbw
= $table
['max_cell_border_width']['L']/2 + $table
['max_cell_border_width']['R']/2 + $table
['margin']['L'] + $table
['margin']['R']; }
23560 if ($this->cacheTables
) { $fh
= fopen($table
['cache'], "r+b"); }
23561 else { $fh
= null; }
23563 // ADDED table['l'][colno]
23564 // = total length of text approx (using $c['s']) in that column - used to approximately distribute col widths in _tableWidth
23566 for($j = 0 ; $j < $nc ; $j++
) { //columns
23567 $wc = &$table['wc'][$j];
23568 for($i = 0 ; $i < $nr ; $i++
) { //rows
23569 if (isset($cs[$i][$j]) && $cs[$i][$j]) {
23570 if ($this->cacheTables
) {
23571 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
23576 if ($this->simpleTables
){
23577 if ($table['borders_separate']) { // NB twice border width
23578 $extrcw = $table['simple']['border_details']['L']['w'] +
$table['simple']['border_details']['R']['w'] +
$c['padding']['L'] +
$c['padding']['R'] +
$table['border_spacing_H'];
23581 $extrcw = $table['simple']['border_details']['L']['w']/2 +
$table['simple']['border_details']['R']['w']/2 +
$c['padding']['L'] +
$c['padding']['R'];
23585 if ($this->packTableData
) {
23586 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
23589 $br = $c['border_details']['R']['w'];
23590 $bl = $c['border_details']['L']['w'];
23592 if ($table['borders_separate']) { // NB twice border width
23593 $extrcw = $bl +
$br +
$c['padding']['L'] +
$c['padding']['R'] +
$table['border_spacing_H'];
23596 $extrcw = $bl/2 +
$br/2 +
$c['padding']['L'] +
$c['padding']['R'];
23600 //$mw = $this->GetStringWidth('W') + $extrcw ;
23602 // mPDF 5.6.13 Decimal point alignment
23603 if(substr($c['a'],0,1) == 'D') {
23604 $mw = $table['decimal_align'][$j]['maxs0'] +
$table['decimal_align'][$j]['maxs1'] +
$extrcw ;
23607 $c['absmiw'] = $mw;
23609 if (isset($c['R']) && $c['R']) {
23610 $c['maw'] = $c['miw'] = $this->FontSize +
$extrcw ;
23611 if (isset($c['w'])) { // If cell width is specified
23612 if ($c['miw'] <$c['w']) { $c
['miw'] = $c
['w']; }
23614 if (!isset($c['colspan'])) {
23615 if ($wc['miw'] < $c['miw']) { $wc
['miw'] = $c
['miw']; }
23616 if ($wc['maw'] < $c['maw']) { $wc
['maw'] = $c
['maw']; }
23619 if (isset($table['l'][$j]) ) {
23620 $table['l'][$j] +
= $c['miw'] ;
23623 $table['l'][$j] = $c['miw'] ;
23627 if ($c['miw'] > $wc['miw']) { $wc
['miw'] = $c
['miw']; }
23628 if ($wc['miw'] > $wc['maw']) { $wc
['maw'] = $wc
['miw']; }
23633 if (isset($c['s'])) { $c
['s'] +
= $extrcw
; }
23634 if (isset($c['maxs'])) { $c
['maxs'] +
= $extrcw
; }
23635 if (isset($c['nestedmiw'])) { $c
['nestedmiw'] +
= $extrcw
; }
23636 if (isset($c['nestedmaw'])) { $c
['nestedmaw'] +
= $extrcw
; }
23640 // If minimum width has already been set by a nested table or inline object (image/form), use it
23641 if (isset($c['nestedmiw']) && $this->table
[1][1]['overflow']!='visible') { $miw
= $c
['nestedmiw']; }
23642 else { $miw
= $mw
; }
23644 if (isset($c['maxs']) && $c['maxs'] != '') { $c
['s'] = $c
['maxs']; }
23646 // If maximum width has already been set by a nested table, use it
23647 if (isset($c['nestedmaw'])) { $c
['maw'] = $c
['nestedmaw']; }
23648 else $c['maw'] = $c['s'];
23650 if (isset($table['overflow']) && $table['overflow']=='visible' && $table['level']==1) {
23651 if (($c['maw'] +
$tblbw) > $this->blk
[$this->blklvl
]['inner_width']) {
23652 $c['maw'] = $this->blk
[$this->blklvl
]['inner_width'] - $tblbw;
23656 if (isset($c['nowrap']) && $c['nowrap']) { $miw
= $c
['maw']; }
23658 if (isset($c['wpercent']) && $firstpass) {
23659 if (isset($c['colspan'])) { // Not perfect - but % set on colspan is shared equally on cols.
23660 for($k=0;$k<$c['colspan'];$k++
) {
23661 $table['wc'][($j+
$k)]['wpercent'] = $c['wpercent'] / $c['colspan'];
23665 if (isset($table['w']) && $table['w']) { $c
['w'] = $c
['wpercent']/100 * ($table
['w'] - $tblbw
); }
23666 $wc['wpercent'] = $c['wpercent'];
23670 if (isset($table['overflow']) && $table['overflow']=='visible' && $table['level']==1) {
23671 if (($c['w'] +
$tblbw) > $this->blk
[$this->blklvl
]['inner_width']) {
23672 $c['w'] = $this->blk
[$this->blklvl
]['inner_width'] - $tblbw;
23677 if (isset($c['w'])) { // If cell width is specified
23678 if ($miw<$c['w']) { $c
['miw'] = $c
['w']; } // Cell min width = that specified
23679 if ($miw>$c['w']) { $c
['miw'] = $c
['w'] = $miw
; } // If width specified is less than minimum allowed (W) increase it
23680 if (!isset($wc['w'])) { $wc
['w'] = 1; } // If the Col width is not specified = set it to 1
23683 else { $c
['miw'] = $miw
; } // If cell width not specified -> set Cell min width it to minimum allowed (W)
23685 if ($c['maw'] < $c['miw']) { $c
['maw'] = $c
['miw']; } // If Cell max width < Minwidth - increase it to =
23686 if (!isset($c['colspan'])) {
23687 if ($wc['miw'] < $c['miw']) { $wc
['miw'] = $c
['miw']; } // Update Col Minimum and maximum widths
23688 if ($wc['maw'] < $c['maw']) { $wc
['maw'] = $c
['maw']; }
23689 if ((isset($wc['absmiw']) && $wc['absmiw'] < $c['absmiw']) || !isset($wc['absmiw'])) { $wc
['absmiw'] = $c
['absmiw']; } // Update Col Minimum and maximum widths
23691 if (isset($table['l'][$j]) ) {
23692 $table['l'][$j] +
= $c['s'];
23695 $table['l'][$j] = $c['s'];
23700 $listspan[] = array($i,$j);
23703 //Check if minimum width of the whole column is big enough for largest word to fit
23704 if (isset($c['textbuffer']) && (!isset($table['overflow']) || $table['overflow']!='wrap')) { // mPDF 5.5.11
23705 $minwidth = $this->TableCheckMinWidth($wc['miw']- $extrcw ,0,$c['textbuffer']);
23707 else { $minwidth
= 0; }
23708 if ($minwidth < 0) {
23709 //increase minimum width
23710 if (!isset($c['colspan'])) {
23711 $wc['miw'] = max($wc['miw'],((-$minwidth) +
$extrcw) );
23714 $c['miw'] = max($c['miw'],((-$minwidth) +
$extrcw) );
23717 if (!isset($c['colspan'])) {
23718 if ($wc['miw'] > $wc['maw']) { $wc
['maw'] = $wc
['miw']; } //update maximum width, if needed
23720 if ($this->cacheTables
) {
23721 $this->_cacheCell($c, '', "W", $fh, $table['cells'][$i][$j]);
23730 $wc = &$table['wc'];
23731 foreach ($listspan as $span) {
23732 list($i,$j) = $span;
23733 if ($this->cacheTables
) {
23734 $c = $this->_uncacheCell($cs[$i][$j], '', $fh);
23738 $lc = $j +
$c['colspan'];
23739 if ($lc > $nc) { $lc
= $nc
; }
23743 for($k=$j;$k<$lc;$k++
) {
23744 if (isset($table['l'][$k]) ) {
23745 if ($c['R']) { $table
['l'][$k
] +
= $c
['miw']/$c
['colspan'] ; }
23746 else { $table
['l'][$k
] +
= $c
['s']/$c
['colspan']; }
23749 if ($c['R']) { $table
['l'][$k
] = $c
['miw']/$c
['colspan'] ; }
23750 else { $table
['l'][$k
] = $c
['s']/$c
['colspan']; }
23752 $wis +
= $wc[$k]['miw'];
23753 $was +
= $wc[$k]['maw'];
23754 if (!isset($c['w'])) {
23756 $wisa +
= $wc[$k]['miw'];
23757 $wasa +
= $wc[$k]['maw'];
23760 if ($c['miw'] > $wis) {
23762 for($k=$j;$k<$lc;$k++
) { $wc
[$k
]['miw'] = $c
['miw']/$c
['colspan']; }
23764 else if (!count($list)) {
23765 $wi = $c['miw'] - $wis;
23766 for($k=$j;$k<$lc;$k++
) { $wc
[$k
]['miw'] +
= ($wc
[$k
]['miw']/$wis
)*$wi
; }
23769 $wi = $c['miw'] - $wis;
23770 foreach ($list as $k) { $wc
[$k
]['miw'] +
= ($wc
[$k
]['miw']/$wisa
)*$wi
; }
23773 if ($c['maw'] > $was) {
23775 for($k=$j;$k<$lc;$k++
) { $wc
[$k
]['maw'] = $c
['maw']/$c
['colspan']; }
23777 else if (!count($list)) {
23778 $wi = $c['maw'] - $was;
23779 for($k=$j;$k<$lc;$k++
) { $wc
[$k
]['maw'] +
= ($wc
[$k
]['maw']/$was
)*$wi
; }
23782 $wi = $c['maw'] - $was;
23783 foreach ($list as $k) { $wc
[$k
]['maw'] +
= ($wc
[$k
]['maw']/$wasa
)*$wi
; }
23789 if ($this->cacheTables
) { fclose($fh
); }
23791 $checkminwidth = 0;
23792 $checkmaxwidth = 0;
23795 for( $i = 0 ; $i < $nc ; $i++
) {
23796 $checkminwidth +
= $table['wc'][$i]['miw'];
23797 $checkmaxwidth +
= $table['wc'][$i]['maw'];
23798 $totallength +
= $table['l'][$i];
23801 if (!isset($table['w']) && $firstpass) {
23804 for( $i = 0 ; $i < $nc ; $i++
) {
23805 if (isset($table['wc'][$i]['wpercent']) && $table['wc'][$i]['wpercent']) {
23806 $sumpc +
= $table['wc'][$i]['wpercent'];
23808 else { $notset++
; }
23811 // If sum of widths as % >= 100% and not all columns are set
23812 // Set a nominal width of 1% for unset columns
23813 if ($sumpc >= 100 && $notset) {
23814 for( $i = 0 ; $i < $nc ; $i++
) {
23815 if ((!isset($table['wc'][$i]['wpercent']) || !$table['wc'][$i]['wpercent']) &&
23816 (!isset($table['wc'][$i]['w']) || !$table['wc'][$i]['w'])) {
23817 $table['wc'][$i]['wpercent'] = 1;
23823 if ($sumpc) { // if any percents are set
23824 $sumnonpc = (100 - $sumpc);
23825 $sumpc = max($sumpc,100);
23828 $miwsurplusnonpc = 0;
23832 $mawsurplusnonpc = 0;
23834 for( $i = 0 ; $i < $nc ; $i++
) {
23835 if (isset($table['wc'][$i]['wpercent'])) {
23836 $maxcalcmiw = max($maxcalcmiw, ($table['wc'][$i]['miw'] * $sumpc /$table['wc'][$i]['wpercent']) );
23837 $maxcalcmaw = max($maxcalcmaw, ($table['wc'][$i]['maw'] * $sumpc /$table['wc'][$i]['wpercent']) );
23840 $miwleft +
= $table['wc'][$i]['miw'];
23841 $mawleft +
= $table['wc'][$i]['maw'];
23842 if (!isset($table['wc'][$i]['w'])) { $miwleftcount++
; $mawleftcount++
; }
23845 if ($miwleft && $sumnonpc > 0) { $miwnon
= $miwleft
* 100 / $sumnonpc
; }
23846 if ($mawleft && $sumnonpc > 0) { $mawnon
= $mawleft
* 100 / $sumnonpc
; }
23847 if (($miwnon > $checkminwidth || $maxcalcmiw > $checkminwidth) && $this->keep_table_proportions
) {
23848 if ($miwnon > $maxcalcmiw) {
23849 $miwsurplusnonpc = round((($miwnon * $sumnonpc / 100) - $miwleft),3);
23850 $checkminwidth = $miwnon;
23852 else { $checkminwidth
= $maxcalcmiw
; }
23853 for( $i = 0 ; $i < $nc ; $i++
) {
23854 if (isset($table['wc'][$i]['wpercent'])) {
23855 $newmiw = $checkminwidth * $table['wc'][$i]['wpercent']/100;
23856 if ($table['wc'][$i]['miw'] < $newmiw) {
23857 $table['wc'][$i]['miw'] = $newmiw;
23859 $table['wc'][$i]['w'] = 1;
23861 else if ($miwsurplusnonpc && !$table['wc'][$i]['w']) {
23862 $table['wc'][$i]['miw'] +
= $miwsurplusnonpc / $miwleftcount;
23866 if (($mawnon > $checkmaxwidth || $maxcalcmaw > $checkmaxwidth )) {
23867 if ($mawnon > $maxcalcmaw) {
23868 $mawsurplusnonpc = round((($mawnon * $sumnonpc / 100) - $mawleft),3);
23869 $checkmaxwidth = $mawnon;
23871 else { $checkmaxwidth
= $maxcalcmaw
; }
23872 for( $i = 0 ; $i < $nc ; $i++
) {
23873 if (isset($table['wc'][$i]['wpercent'])) {
23874 $newmaw = $checkmaxwidth * $table['wc'][$i]['wpercent']/100;
23875 if ($table['wc'][$i]['maw'] < $newmaw) {
23876 $table['wc'][$i]['maw'] = $newmaw;
23878 $table['wc'][$i]['w'] = 1;
23880 else if ($mawsurplusnonpc && !$table['wc'][$i]['w']) {
23881 $table['wc'][$i]['maw'] +
= $mawsurplusnonpc / $mawleftcount;
23883 if ($table['wc'][$i]['maw'] < $table['wc'][$i]['miw']) { $table
['wc'][$i
]['maw'] = $table
['wc'][$i
]['miw']; }
23886 if ($checkminwidth > $checkmaxwidth) { $checkmaxwidth
= $checkminwidth
; }
23890 if (isset($table['wpercent']) && $table['wpercent']) {
23891 $checkminwidth *= (100 / $table['wpercent']);
23892 $checkmaxwidth *= (100 / $table['wpercent']);
23896 $checkminwidth +
= $tblbw ;
23897 $checkmaxwidth +
= $tblbw ;
23899 // Table['miw'] set by percent in first pass may be larger than sum of column miw
23900 if ((isset($table['miw']) && $checkminwidth > $table['miw']) || !isset($table['miw'])) { $table
['miw'] = $checkminwidth
; }
23901 if ((isset($table['maw']) && $checkmaxwidth > $table['maw']) || !isset($table['maw'])) { $table
['maw'] = $checkmaxwidth
; }
23902 $table['tl'] = $totallength ;
23905 if (!$this->tableCJK
) {
23906 if ($this->table_rotate
) {
23907 $mxw = $this->tbrot_maxw
;
23910 $mxw = $this->blk
[$this->blklvl
]['inner_width'];
23912 if(!isset($table['overflow'])) { $table
['overflow'] = null; }
23913 if ($table['overflow']=='visible') {
23916 else if ($table['overflow']=='hidden' && !$this->table_rotate
&& !$this->ColActive
&& $checkminwidth > $mxw) {
23917 $table['w'] = $table['miw'];
23920 else if ($table['overflow']=='wrap') { return array(0,0); }
23922 if (isset($table['w']) && $table['w'] ) {
23923 if ($table['w'] >= $checkminwidth && $table['w'] <= $mxw) { $table
['maw'] = $mxw
= $table
['w']; }
23924 else if ($table['w'] >= $checkminwidth && $table['w'] > $mxw && $this->keep_table_proportions
) { $checkminwidth
= $table
['w']; }
23926 unset($table['w']);
23929 $ratio = $checkminwidth/$mxw;
23930 if ($checkminwidth > $mxw) { return array(($ratio +
0.001),$checkminwidth
); } // 0.001 to allow for rounded numbers when resizing
23938 function _tableWidth(&$table){
23939 $widthcols = &$table['wc'];
23940 $numcols = $table['nc'];
23942 if ($table['borders_separate']) {
23943 $tblbw = $table['border_details']['L']['w'] +
$table['border_details']['R']['w'] +
$table['margin']['L'] +
$table['margin']['R'] +
$table['padding']['L'] +
$table['padding']['R'] +
$table['border_spacing_H'];
23945 else { $tblbw
= $table
['max_cell_border_width']['L']/2 + $table
['max_cell_border_width']['R']/2 + $table
['margin']['L'] + $table
['margin']['R']; }
23947 if ($table['level']>1 && isset($table['w'])) {
23948 if (isset($table['wpercent']) && $table['wpercent']) {
23949 $table['w'] = $temppgwidth = (($table['w']-$tblbw) * $table['wpercent'] / 100) +
$tblbw ;
23952 $temppgwidth = $table['w'] ;
23955 else if ($this->table_rotate
) {
23956 $temppgwidth = $this->tbrot_maxw
;
23957 // If it is less than 1/20th of the remaining page height to finish the DIV (i.e. DIV padding + table bottom margin)
23958 // then allow for this
23959 $enddiv = $this->blk
[$this->blklvl
]['padding_bottom'] +
$this->blk
[$this->blklvl
]['border_bottom']['w'];
23960 if ($enddiv/$temppgwidth <0.05) { $temppgwidth
-= $enddiv
; }
23963 if (isset($table['w']) && $table['w']< $this->blk
[$this->blklvl
]['inner_width']) {
23965 $temppgwidth = $table['w'] ;
23967 else if ($table['overflow']=='visible' && $table['level'] ==1) {
23968 $temppgwidth = null;
23970 else if ($table['overflow']=='hidden' && !$this->ColActive
&& isset($table['w']) && $table['w'] > $this->blk
[$this->blklvl
]['inner_width'] && $table['w']==$table['miw']) {
23971 //$temppgwidth = $this->blk[$this->blklvl]['inner_width'];
23972 $temppgwidth = $table['w'] ;
23974 else { $temppgwidth
= $this
->blk
[$this
->blklvl
]['inner_width']; }
23978 $totaltextlength = 0; // Added - to sum $table['l'][colno]
23979 $totalatextlength = 0; // Added - to sum $table['l'][colno] for those columns where width not set
23980 $percentages_set = 0;
23981 for ( $i = 0 ; $i < $numcols ; $i++
) {
23982 if (isset($widthcols[$i]['wpercent'])) { $tablewidth +
= $widthcols
[$i
]['maw']; $percentages_set
= 1; }
23983 else if (isset($widthcols[$i]['w'])) { $tablewidth +
= $widthcols
[$i
]['miw']; }
23984 else { $tablewidth +
= $widthcols
[$i
]['maw']; }
23985 $totaltextlength +
= $table['l'][$i];
23987 if (!$totaltextlength) { $totaltextlength
=1; }
23988 $tablewidth +
= $tblbw; // Outer half of table borders
23990 if ($tablewidth > $temppgwidth) {
23991 $table['w'] = $temppgwidth;
23993 // if any widths set as percentages and max width fits < page width
23994 else if ($tablewidth < $temppgwidth && !isset($table['w']) && $percentages_set) {
23995 $table['w'] = $table['maw'];
23997 // if table width is set and is > allowed width
23998 if (isset($table['w']) && $table['w'] > $temppgwidth) { $table
['w'] = $temppgwidth
; }
23999 // IF the table width is now set - Need to distribute columns widths
24000 if (isset($table['w'])) {
24003 $notsetlist = array();
24004 for( $i = 0 ; $i < $numcols ; $i++
) {
24005 $wis +
= $widthcols[$i]['miw'];
24006 if (!isset($widthcols[$i]['w']) || ($widthcols[$i]['w'] && $table['w'] > $temppgwidth && !$this->keep_table_proportions
&& !$notfullwidth )){
24008 $wisa +
= $widthcols[$i]['miw'];
24009 $totalatextlength +
= $table['l'][$i];
24012 if (!$totalatextlength) { $totalatextlength
=1; }
24014 // Allocate spare (more than col's minimum width) across the cols according to their approx total text length
24015 // Do it by setting minimum width here
24016 if ($table['w'] > $wis +
$tblbw) {
24017 // First set any cell widths set as percentages
24018 if ($table['w'] < $temppgwidth || $this->keep_table_proportions
) {
24019 for($k=0;$k<$numcols;$k++
) {
24020 if (isset($widthcols[$k]['wpercent'])) {
24021 $curr = $widthcols[$k]['miw'];
24022 $widthcols[$k]['miw'] = ($table['w']-$tblbw) * $widthcols[$k]['wpercent']/100;
24023 $wis +
= $widthcols[$k]['miw'] - $curr;
24024 $wisa +
= $widthcols[$k]['miw'] - $curr;
24028 // Now allocate surplus up to maximum width of each column
24029 $surplus = 0; $ttl = 0; // number of surplus columns
24030 if (!count($list)) {
24031 $wi = ($table['w']-($wis +
$tblbw)); // i.e. extra space to distribute
24032 for($k=0;$k<$numcols;$k++
) {
24033 $spareratio = ($table['l'][$k] / $totaltextlength); // gives ratio to divide up free space
24034 // Don't allocate more than Maximum required width - save rest in surplus
24035 if ($widthcols[$k]['miw'] +
($wi * $spareratio) > $widthcols[$k]['maw']) {
24036 $surplus +
= ($wi * $spareratio) - ($widthcols[$k]['maw']-$widthcols[$k]['miw']);
24037 $widthcols[$k]['miw'] = $widthcols[$k]['maw'];
24040 $notsetlist[] = $k;
24041 $ttl +
= $table['l'][$k];
24042 $widthcols[$k]['miw'] +
= ($wi * $spareratio);
24048 $wi = ($table['w'] - ($wis +
$tblbw)); // i.e. extra space to distribute
24049 foreach ($list as $k) {
24050 $spareratio = ($table['l'][$k] / $totalatextlength); // gives ratio to divide up free space
24051 // Don't allocate more than Maximum required width - save rest in surplus
24052 if ($widthcols[$k]['miw'] +
($wi * $spareratio) > $widthcols[$k]['maw']) {
24053 $surplus +
= ($wi * $spareratio) - ($widthcols[$k]['maw']-$widthcols[$k]['miw']);
24054 $widthcols[$k]['miw'] = $widthcols[$k]['maw'];
24057 $notsetlist[] = $k;
24058 $ttl +
= $table['l'][$k];
24059 $widthcols[$k]['miw'] +
= ($wi * $spareratio);
24063 // If surplus still left over apportion it across columns
24065 // if some are set only add to remaining - otherwise add to all of them
24066 if (count($notsetlist) && count($notsetlist) < $numcols) {
24067 foreach ($notsetlist AS $i) {
24068 if ($ttl) $widthcols[$i]['miw'] +
= $surplus * $table['l'][$i] / $ttl ;
24071 // If some widths are defined, and others have been added up to their maxmum
24072 else if (count($list) && count($list) < $numcols) {
24073 foreach ($list AS $i) {
24074 $widthcols[$i]['miw'] +
= $surplus / count($list) ;
24077 else if ($numcols) { // If all columns
24078 $ttl = array_sum($table['l']);
24079 for ($i=0;$i<$numcols;$i++
) {
24080 $widthcols[$i]['miw'] +
= $surplus * $table['l'][$i] / $ttl;
24087 // This sets the columns all to minimum width (which has been increased above if appropriate)
24088 for ($i=0;$i<$numcols;$i++
) {
24089 $widthcols[$i] = $widthcols[$i]['miw'];
24092 // TABLE NOT WIDE ENOUGH EVEN FOR MINIMUM CONTENT WIDTH
24093 // If sum of column widths set are too wide for table
24094 $checktablewidth = 0;
24095 for ( $i = 0 ; $i < $numcols ; $i++
) {
24096 $checktablewidth +
= $widthcols[$i];
24098 if ($checktablewidth > ($temppgwidth +
0.001 - $tblbw)) {
24099 $usedup = 0; $numleft = 0;
24100 for ($i=0;$i<$numcols;$i++
) {
24101 if ((isset($widthcols[$i]) && $widthcols[$i] > (($temppgwidth - $tblbw) / $numcols)) && (!isset($widthcols[$i]['w']))) {
24103 unset($widthcols[$i]);
24105 else { $usedup +
= $widthcols
[$i
]; }
24107 for ($i=0;$i<$numcols;$i++
) {
24108 if (!isset($widthcols[$i]) || !$widthcols[$i]) {
24109 $widthcols[$i] = ((($temppgwidth - $tblbw) - $usedup)/ ($numleft));
24115 else { //table has no width defined
24116 $table['w'] = $tablewidth;
24117 for ( $i = 0 ; $i < $numcols ; $i++
) {
24118 if (isset($widthcols[$i]['wpercent']) && $this->keep_table_proportions
) { $colwidth
= $widthcols
[$i
]['maw']; }
24119 else if (isset($widthcols[$i]['w'])) { $colwidth
= $widthcols
[$i
]['miw']; }
24120 else { $colwidth
= $widthcols
[$i
]['maw']; }
24121 unset($widthcols[$i]);
24122 $widthcols[$i] = $colwidth;
24126 if ($table['overflow']=='visible' && $table['level'] ==1) {
24127 if ($tablewidth > $this->blk
[$this->blklvl
]['inner_width']) {
24128 if ($this->cacheTables
) { $fh
= fopen($table
['cache'], "r+b"); }
24129 else { $fh
= null; }
24130 for ($j = 0 ; $j < $numcols; $j++
) { //columns
24131 for ($i = 0 ; $i < $table['nr']; $i++
) { //rows
24132 if (isset($table['cells'][$i][$j]) && $table['cells'][$i][$j]) {
24133 if ($this->cacheTables
) {
24134 $cc = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24135 $colspan = $cc['colspan'];
24138 $colspan = $table['cells'][$i][$j]['colspan'];
24139 if ($colspan > 1) {
24141 for ($c = $j; $c < ($j +
$colspan); $c++
) {
24142 $w +
= $widthcols[$c];
24144 if ($w > $this->blk
[$this->blklvl
]['inner_width']) {
24145 $diff = $w - ($this->blk
[$this->blklvl
]['inner_width'] - $tblbw);
24146 for ($c = $j; $c < ($j +
$colspan); $c++
) {
24147 $widthcols[$c] -= $diff * ($widthcols[$c]/$w);
24149 $table['w'] -= $diff;
24150 $table['csp'][$j] = $w - $diff;
24157 if ($this->cacheTables
) { fclose($fh
); }
24161 for ($i = 0 ; $i < $numcols; $i++
) { //columns
24162 if (isset($table['csp'][$i])) {
24163 $w = $table['csp'][$i];
24164 unset($table['csp'][$i]);
24166 else { $w
= $widthcols
[$i
]; }
24167 if (($currWc +
$w +
$tblbw) > $this->blk
[$this->blklvl
]['inner_width']) {
24169 $currWc = $widthcols[$i] ;
24171 else { $currWc +
= $widthcols
[$i
] ; }
24172 $table['colPg'][$i] = $pgNo;
24179 function _tableHeight(&$table){
24180 $level = $table['level'];
24181 $levelid = $table['levelid'];
24182 $cells = &$table['cells'];
24183 $numcols = $table['nc'];
24184 $numrows = $table['nr'];
24185 $listspan = array();
24186 $checkmaxheight = 0;
24187 $headerrowheight = 0;
24188 $checkmaxheightplus = 0;
24189 $headerrowheightplus = 0;
24190 $firstrowheight = 0;
24192 $footerrowheight = 0;
24193 $footerrowheightplus = 0;
24194 if ($this->table_rotate
) {
24195 $temppgheight = $this->tbrot_maxh
;
24196 $remainingpage = $this->tbrot_maxh
;
24199 $temppgheight = ($this->h
- $this->bMargin
- $this->tMargin
) - $this->kwt_height
;
24200 $remainingpage = ($this->h
- $this->bMargin
- $this->y
) - $this->kwt_height
;
24202 // If it is less than 1/20th of the remaining page height to finish the DIV (i.e. DIV padding + table bottom margin)
24203 // then allow for this
24204 $enddiv = $this->blk
[$this->blklvl
]['padding_bottom'] +
$this->blk
[$this->blklvl
]['border_bottom']['w'] +
$table['margin']['B'];
24205 if ($remainingpage > $enddiv && $enddiv/$remainingpage <0.05) { $remainingpage
-= $enddiv
; }
24206 else if ($remainingpage == 0) { $remainingpage
= 0.001; }
24207 if ($temppgheight > $enddiv && $enddiv/$temppgheight <0.05) { $temppgheight
-= $enddiv
; }
24208 else if ($temppgheight == 0) { $temppgheight
= 0.001; }
24210 if ($remainingpage < 0) { $remainingpage
= 0.001; } // mPDF 5.6.64
24211 if ($temppgheight < 0) { $temppgheight
= 0.001; } // mPDF 5.6.64
24213 if ($this->cacheTables
) { $fh
= fopen($table
['cache'], "r+b"); }
24214 else { $fh
= null; }
24216 for( $i = 0 ; $i < $numrows ; $i++
) { //rows
24217 $heightrow = &$table['hr'][$i];
24218 for( $j = 0 ; $j < $numcols ; $j++
) { //columns
24219 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
24220 if ($this->cacheTables
) {
24221 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24224 $c = &$cells[$i][$j];
24226 if ($this->simpleTables
){
24227 if ($table['borders_separate']) { // NB twice border width
24228 $extraWLR = ($table['simple']['border_details']['L']['w']+
$table['simple']['border_details']['R']['w']) +
($c['padding']['L']+
$c['padding']['R'])+
$table['border_spacing_H'];
24229 $extrh = ($table['simple']['border_details']['T']['w']+
$table['simple']['border_details']['B']['w']) +
($c['padding']['T']+
$c['padding']['B'])+
$table['border_spacing_V'];
24232 $extraWLR = ($table['simple']['border_details']['L']['w']+
$table['simple']['border_details']['R']['w'])/2 +
($c['padding']['L']+
$c['padding']['R']);
24233 $extrh = ($table['simple']['border_details']['T']['w']+
$table['simple']['border_details']['B']['w'])/2 +
($c['padding']['T']+
$c['padding']['B']);
24237 if ($this->packTableData
) {
24238 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
24241 $bt = $c['border_details']['T']['w'];
24242 $bb = $c['border_details']['B']['w'];
24243 $br = $c['border_details']['R']['w'];
24244 $bl = $c['border_details']['L']['w'];
24246 if ($table['borders_separate']) { // NB twice border width
24247 $extraWLR = $bl +
$br +
$c['padding']['L'] +
$c['padding']['R'] +
$table['border_spacing_H'];
24248 $extrh = $bt +
$bb +
$c['padding']['T'] +
$c['padding']['B'] +
$table['border_spacing_V'];
24251 $extraWLR = $bl/2 +
$br/2 +
$c['padding']['L'] +
$c['padding']['R'];
24252 $extrh = $bt/2 +
$bb/2 +
$c['padding']['T']+
$c['padding']['B'];
24256 if ($table['overflow']=='visible' && $level==1)
24257 list($x,$cw) = $this->_splitTableGetWidth($table, $i,$j, $fh);
24259 list($x,$cw) = $this->_tableGetWidth($table, $i,$j, $fh);
24262 // ++ extra parameter forces wrap to break word
24263 if ($c['R'] && isset($c['textbuffer'])) { // mPDF 5.4.01
24265 foreach($c['textbuffer'] AS $t) { $str
.= $t
[0].' '; }
24267 $s_fs = $this->FontSizePt
;
24268 $s_f = $this->FontFamily
;
24269 $s_st = $this->FontStyle
;
24270 $this->SetFont($c['textbuffer'][0][4],$c['textbuffer'][0][2],$c['textbuffer'][0][11] / $this->shrin_k
,true,true);
24271 $tempch = $this->GetStringWidth($str);
24272 if ($c['R'] >= 45 && $c['R'] < 90) {
24273 $tempch = ((sin(deg2rad($c['R']))) * $tempch ) +
((sin(deg2rad($c['R']))) * (($c['textbuffer'][0][11]/_MPDFK
) / $this->shrin_k
));
24275 $this->SetFont($s_f,$s_st,$s_fs,true,true);
24276 $ch = ($tempch ) +
$extrh ;
24279 if (isset($c['textbuffer'])) {
24280 $tempch = $this->TableWordWrap(($cw-$extraWLR),1,$c['textbuffer'], $c['dfs']);
24282 else { $tempch
= 0; }
24284 // Added cellpadding top and bottom. (Lineheight already adjusted to table_lineheight)
24285 $ch = $tempch +
$extrh ;
24287 //If height is defined and it is bigger than calculated $ch then update values
24288 if (isset($c['h']) && $c['h'] > $ch) {
24289 $c['mih'] = $ch; //in order to keep valign working
24292 else $c['mih'] = $ch;
24293 if ($this->cacheTables
) {
24294 $this->_cacheUpdateMtx($c, $fh, $table['cells'][$i][$j], 'mih');
24296 if (isset($c['rowspan'])) $listspan[] = array($i,$j);
24297 elseif ($heightrow < $ch) $heightrow = $ch;
24299 // this is the extra used in _tableWrite to determine whether to trigger a page change
24300 if ($table['borders_separate']) {
24301 if ($i == ($numrows-1) || (isset($c['rowspan']) && ($i+
$c['rowspan']) == ($numrows)) ) {
24302 $extra = $table['margin']['B'] +
$table['padding']['B'] +
$table['border_details']['B']['w'] +
$table['border_spacing_V']/2;
24305 $extra = $table['border_spacing_V']/2;
24309 if (!$this->simpleTables
){
24312 else if ($this->simpleTables
){
24313 $extra = $table['simple']['border_details']['B']['w'] /2;
24316 if (isset($table['is_thead'][$i]) && $table['is_thead'][$i]) {
24318 $headerrowheight +
= $ch;
24319 $headerrowheightplus +
= $ch+
$extra;
24322 else if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i]) {
24324 $footerrowheight +
= $ch;
24325 $footerrowheightplus +
= $ch+
$extra;
24329 $checkmaxheight = max($checkmaxheight,$ch);
24330 $checkmaxheightplus = max($checkmaxheightplus,$ch+
$extra);
24332 if ($this->tableLevel
==1 && $i == $table['headernrows']) { $firstrowheight
= max($ch
,$firstrowheight
); }
24338 $heightrow = &$table['hr'];
24339 foreach ($listspan as $span) {
24340 list($i,$j) = $span;
24341 if ($this->cacheTables
) {
24342 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24345 $c = &$cells[$i][$j];
24346 $lr = $i +
$c['rowspan'];
24347 if ($lr > $numrows) $lr = $numrows;
24350 for($k=$i;$k<$lr;$k++
) {
24351 $hs +
= $heightrow[$k];
24352 if (!isset($c['h'])) {
24354 $hsa +
= $heightrow[$k];
24358 if ($table['borders_separate']) {
24359 if ($i == ($numrows-1) || ($i+
$c['rowspan']) == ($numrows) ) {
24360 $extra = $table['margin']['B'] +
$table['padding']['B'] +
$table['border_details']['B']['w'] +
$table['border_spacing_V']/2;
24363 $extra = $table['border_spacing_V']/2;
24367 if (!$this->simpleTables
){
24368 if ($this->packTableData
) {
24369 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
24372 $bb = $c['border_details']['B']['w'];
24376 else if ($this->simpleTables
){
24377 $extra = $table['simple']['border_details']['B']['w'] /2;
24380 if (!empty($table['is_thead'][$i])) {
24381 $headerrowheight = max($headerrowheight,$hs);
24382 $headerrowheightplus = max($headerrowheightplus,$hs+
$extra);
24384 else if (!empty($table['is_tfoot'][$i])) {
24385 $footerrowheight = max($footerrowheight,$hs);
24386 $footerrowheightplus = max($footerrowheightplus,$hs+
$extra);
24389 $checkmaxheight = max($checkmaxheight,$hs);
24390 $checkmaxheightplus = max($checkmaxheightplus,$hs+
$extra);
24392 if ($this->tableLevel
==1 && $i == $table['headernrows']) { $firstrowheight
= max($hs
,$firstrowheight
); }
24394 if ($c['mih'] > $hs) {
24396 for($k=$i;$k<$lr;$k++
) $heightrow[$k] = $c['mih']/$c['rowspan'];
24398 elseif (!count($list)) {
24399 $hi = $c['mih'] - $hs;
24400 for($k=$i;$k<$lr;$k++
) $heightrow[$k] +
= ($heightrow[$k]/$hs)*$hi;
24403 $hi = $c['mih'] - $hsa;
24404 foreach ($list as $k) $heightrow[$k] +
= ($heightrow[$k]/$hsa)*$hi;
24409 // If rowspans overlap so that one or more rows do not have a height set...
24410 // i.e. for one or more rows, the only cells (explicit) in that row have rowspan>1
24411 // so heightrow is still == 0
24412 if ($heightrow[$i]==0) {
24413 // Get row extent to analyse above and below
24415 foreach ($listspan as $checkspan) {
24416 list($cki,$ckj) = $checkspan;
24417 if ($this->cacheTables
) {
24418 $c = $this->_uncacheCell($table['cells'][$cki][$ckj], '', $fh);
24421 $c = &$cells[$cki][$ckj];
24422 if (isset($c['rowspan']) && $c['rowspan']>1) {
24423 if (($cki +
$c['rowspan']-1) >= $i) { $top
= min($top
, $cki
); }
24426 $bottom = $i +
$c['rowspan']-1;
24427 // Check for overconstrained conditions
24428 for ($k=$top; $k<=$bottom; $k++
) {
24429 // if ['hr'] for any of the others is also 0, then abort (too complicated)
24430 if ($k != $i && $heightrow[$k]==0) { break(1); }
24431 // check again that top and bottom are not crossed by rowspans - or abort (too complicated)
24433 // ???? take account of colspan as well???
24434 for( $m = 0 ; $m < $numcols ; $m++
) { //columns
24435 if (!isset($cells[$k][$m]) || $cells[$k][$m]==0) {
24440 else if ($k==$bottom) {
24441 // ???? take account of colspan as well???
24442 for( $m = 0 ; $m < $numcols ; $m++
) { //columns
24443 if ($this->cacheTables
) {
24444 $c = $this->_uncacheCell($table['cells'][$k][$m], '', $fh);
24447 $c = &$cells[$k][$m];
24448 if (isset($c['rowspan']) && $c['rowspan']>1) {
24454 // By columns add up col height using ['h'] if set or ['mih'] if not
24455 // Intentionally do not substract border-spacing
24459 for( $m = 0 ; $m < $numcols ; $m++
) { //columns
24460 for ($k=$top; $k<=$bottom; $k++
) {
24461 if (isset($cells[$k][$m]) && $cells[$k][$m]!=0) {
24462 if ($this->cacheTables
) {
24463 $c = $this->_uncacheCell($table['cells'][$k][$m], '', $fh);
24466 $c = &$cells[$k][$m];
24467 if (isset($c['h']) && $c['h']) {
24470 // ???? take account of colspan as well???
24474 $colH[$m] +
= $useh;
24475 if (!isset($c['rowspan']) || $c['rowspan']<2) { $newhr
[$k
] = max($newhr
[$k
], $useh
); }
24478 $extH = max($tabH, $colH[$m]);
24480 $newhr[$i] = $extH - array_sum($newhr);
24481 for ($k=$top; $k<=$bottom; $k++
) { $heightrow
[$k
] = $newhr
[$k
]; }
24488 $table['h'] = array_sum($heightrow);
24491 if ($this->cacheTables
) { fclose($fh
); }
24493 if ($table['borders_separate']) {
24494 $table['h'] +
= $table['margin']['T'] +
$table['margin']['B'] +
$table['border_details']['T']['w'] +
$table['border_details']['B']['w'] +
$table['border_spacing_V'] +
$table['padding']['T'] +
$table['padding']['B'];
24497 $table['h'] +
= $table['margin']['T'] +
$table['margin']['B'] +
$table['max_cell_border_width']['T']/2 +
$table['max_cell_border_width']['B']/2;
24500 $maxrowheight = $checkmaxheightplus +
$headerrowheightplus +
$footerrowheightplus;
24501 $maxfirstrowheight = $firstrowheight +
$headerrowheightplus +
$footerrowheightplus; // includes thead, 1st row and tfoot
24502 return array($table['h'],$maxrowheight,$temppgheight,$remainingpage,$maxfirstrowheight);
24505 function _tableGetWidth(&$table, $i,$j, $fh){
24506 if ($this->cacheTables
) {
24507 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24510 $cell = &$table['cells'][$i][$j];
24512 if (isset($cell['x0'])) { return array($cell
['x0'], $cell
['w0']); }
24514 $widthcols = &$table['wc'];
24515 for( $k = 0 ; $k < $j ; $k++
) $x +
= $widthcols[$k];
24516 $w = $widthcols[$j];
24517 if (isset($cell['colspan'])) {
24518 for ( $k = $j+
$cell['colspan']-1 ; $k > $j ; $k-- ) $w +
= $widthcols[$k];
24522 if ($this->cacheTables
) {
24523 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'x0');
24525 return array($x, $w);
24530 function _splitTableGetWidth(&$table, $i,$j, $fh){
24531 if ($this->cacheTables
) {
24532 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24535 $cell = &$table['cells'][$i][$j];
24537 if (isset($cell['x0'])) return array($cell['x0'], $cell['w0']);
24539 $widthcols = &$table['wc'];
24540 $pg = $table['colPg'][$j];
24541 for( $k = 0 ; $k < $j ; $k++
) {
24542 if ($table['colPg'][$k]==$pg) $x +
= $widthcols[$k];
24544 $w = $widthcols[$j];
24545 if (isset($cell['colspan'])) {
24546 for ( $k = $j+
$cell['colspan']-1 ; $k > $j ; $k-- ) if ($table['colPg'][$k]==$pg) $w +
= $widthcols[$k];
24550 if ($this->cacheTables
) {
24551 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'x0');
24553 return array($x, $w);
24559 function _tableGetHeight(&$table, $i,$j, $fh){
24560 if ($this->cacheTables
) {
24561 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24564 $cell = &$table['cells'][$i][$j];
24566 if (isset($cell['y0'])) return array($cell['y0'], $cell['h0']);
24568 $heightrow = &$table['hr'];
24569 for ($k=0;$k<$i;$k++
) $y +
= $heightrow[$k];
24570 $h = $heightrow[$i];
24571 if (isset($cell['rowspan'])){
24572 for ($k=$i+
$cell['rowspan']-1;$k>$i;$k--)
24573 $h +
= $heightrow[$k];
24577 if ($this->cacheTables
) {
24578 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'y0');
24580 return array($y, $h);
24585 function _tableGetMaxRowHeight($table, $row, $fh) {
24586 if ($row==$table['nc']-1) { return $table
['hr'][$row
]; }
24587 $maxrowheight = $table['hr'][$row];
24588 for ($i=$row+
1;$i<$table['nr'];$i++
) {
24590 for ($j=0;$j<$table['nc'];$j++
) {
24591 if ($this->cacheTables
) {
24592 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24594 if (isset($cell['colspan'])) { $cellsset +
= $cell
['colspan']; }
24595 else $cellsset +
= 1;
24599 if ($table['cells'][$i][$j]) {
24600 if (isset($table['cells'][$i][$j]['colspan'])) { $cellsset +
= $table
['cells'][$i
][$j
]['colspan']; }
24601 else $cellsset +
= 1;
24605 if ($cellsset == $table['nc']) { return $maxrowheight
; }
24606 else { $maxrowheight +
= $table
['hr'][$i
]; }
24608 return $maxrowheight;
24612 // CHANGED TO ALLOW TABLE BORDER TO BE SPECIFIED CORRECTLY - added border_details
24613 function _tableRect($x, $y, $w, $h, $bord=-1, $details=array(), $buffer=false, $bSeparate=false, $cort='cell', $tablecorner='', $bsv=0, $bsh=0) {
24614 $cellBorderOverlay = array();
24616 if ($bord==-1) { $this
->Rect($x
, $y
, $w
, $h
); }
24617 else if ($this->simpleTables
&& ($cort=='cell')) {
24618 $this->SetLineWidth($details['L']['w']);
24619 if ($details['L']['c']) {
24620 $this->SetDColor($details['L']['c']);
24622 else { $this
->SetDColor($this
->ConvertColor(0)); }
24623 $this->SetLineJoin(0);
24624 $this->Rect($x, $y, $w, $h);
24627 if (!$bSeparate && $buffer) {
24628 $priority = 'LRTB';
24629 for($p=0;$p<strlen($priority);$p++
) {
24630 $side = $priority[$p];
24631 $details['p'] = $side ;
24634 if (isset($details[$side]['w'])) { $dom +
= ($details
[$side
]['w'] * 100000); }
24635 if (isset($details[$side]['style'])) { $dom +
= (array_search($details
[$side
]['style'],$this
->borderstyles
)*100) ; }
24636 if (isset($details[$side]['dom'])) { $dom +
= ($details
[$side
]['dom']*10); }
24638 // Precedence to darker colours at joins
24640 if (isset($details[$side]['c']) && is_array($details[$side]['c'])) {
24641 if ($details[$side]['c']{0}==3) { // RGB
24642 $coldom = 10-(((ord($details[$side]['c']{1})*1.00)+
(ord($details[$side]['c']{2})*1.00)+
(ord($details[$side]['c']{3})*1.00))/76.5);
24644 } // 10 black - 0 white
24645 if ($coldom) { $dom +
= $coldom
; }
24646 // Lastly precedence to RIGHT and BOTTOM cells at joins
24647 if (isset($details['cellposdom'])) { $dom +
= $details
['cellposdom']; }
24650 if ($side == 'T' && $this->issetBorder($bord, _BORDER_TOP
)) { $cbord
= _BORDER_TOP
; $save
= true; }
24651 else if ($side == 'L' && $this->issetBorder($bord, _BORDER_LEFT
)) { $cbord
= _BORDER_LEFT
; $save
= true; }
24652 else if ($side == 'R' && $this->issetBorder($bord, _BORDER_RIGHT
)) { $cbord
= _BORDER_RIGHT
; $save
= true; }
24653 else if ($side == 'B' && $this->issetBorder($bord, _BORDER_BOTTOM
)) { $cbord
= _BORDER_BOTTOM
; $save
= true; }
24656 $this->cellBorderBuffer
[] = pack("A16nCnda6A10d14",
24657 str_pad(sprintf("%08.7f", $dom),16,"0",STR_PAD_LEFT
),
24660 $details[$side]['s'],
24661 $details[$side]['w'],
24662 $details[$side]['c'],
24663 $details[$side]['style'],
24665 $details['mbw']['BL'],
24666 $details['mbw']['BR'],
24667 $details['mbw']['RT'],
24668 $details['mbw']['RB'],
24669 $details['mbw']['TL'],
24670 $details['mbw']['TR'],
24671 $details['mbw']['LT'],
24672 $details['mbw']['LB'],
24673 $details['cellposdom'],
24676 if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'groove' || $details[$side]['style'] == 'inset' || $details[$side]['style'] == 'outset' || $details[$side]['style'] == 'double' ) {
24677 $details[$side]['overlay'] = true;
24678 $this->cellBorderBuffer
[] = pack("A16nCnda6A10d14",
24679 str_pad(sprintf("%08.7f", ($dom+
4)),16,"0",STR_PAD_LEFT
),
24682 $details[$side]['s'],
24683 $details[$side]['w'],
24684 $details[$side]['c'],
24685 $details[$side]['style'],
24687 $details['mbw']['BL'],
24688 $details['mbw']['BR'],
24689 $details['mbw']['RT'],
24690 $details['mbw']['RB'],
24691 $details['mbw']['TL'],
24692 $details['mbw']['TR'],
24693 $details['mbw']['LT'],
24694 $details['mbw']['LB'],
24695 $details['cellposdom'],
24704 if (isset($details['p']) && strlen($details['p'])>1) { $priority
= $details
['p']; }
24705 else { $priority
='LTRB'; }
24710 if (isset($details['T']['w'])) { $Tw
= $details
['T']['w']; }
24711 if (isset($details['R']['w'])) { $Rw
= $details
['R']['w']; }
24712 if (isset($details['B']['w'])) { $Bw
= $details
['B']['w']; }
24713 if (isset($details['L']['w'])) { $Lw
= $details
['L']['w']; }
24715 $x2 = $x +
$w; $y2 = $y +
$h;
24716 $oldlinewidth = $this->LineWidth
;
24718 for($p=0;$p<strlen($priority);$p++
) {
24719 $side = $priority[$p];
24725 if ($Tw && $side=='T' && $this->issetBorder($bord, _BORDER_TOP
)) { // TOP
24730 $this->SetLineWidth($Tw);
24731 if ($cort == 'cell' || strpos($tablecorner,'L')!==false) {
24732 if ($Tw > $Lw) $xadj = ($Tw - $Lw)/2;
24733 if ($Tw < $Lw) $xadj = ($Tw +
$Lw)/2;
24735 else { $xadj
= $Tw
/2 - $bsh
/2; }
24736 if ($cort == 'cell' || strpos($tablecorner,'R')!==false) {
24737 if ($Tw > $Rw) $xadj2 = ($Tw - $Rw)/2;
24738 if ($Tw < $Rw) $xadj2 = ($Tw +
$Rw)/2;
24740 else { $xadj2
= $Tw
/2 - $bsh
/2; }
24741 if (!$bSeparate && $details['mbw']['TL']) {
24742 $xadj = ($Tw - $details['mbw']['TL'])/2 ;
24744 if (!$bSeparate && $details['mbw']['TR']) {
24745 $xadj2 = ($Tw - $details['mbw']['TR'])/2;
24749 if ($Lw && $side=='L' && $this->issetBorder($bord, _BORDER_LEFT
)) { // LEFT
24754 $this->SetLineWidth($Lw);
24755 if ($cort == 'cell' || strpos($tablecorner,'T')!==false) {
24756 if ($Lw > $Tw) $yadj = ($Lw - $Tw)/2;
24757 if ($Lw < $Tw) $yadj = ($Lw +
$Tw)/2;
24759 else { $yadj
= $Lw
/2 - $bsv
/2; }
24760 if ($cort == 'cell' || strpos($tablecorner,'B')!==false) {
24761 if ($Lw > $Bw) $yadj2 = ($Lw - $Bw)/2;
24762 if ($Lw < $Bw) $yadj2 = ($Lw +
$Bw)/2;
24764 else { $yadj2
= $Lw
/2 - $bsv
/2; }
24765 if (!$bSeparate && $details['mbw']['LT']) {
24766 $yadj = ($Lw - $details['mbw']['LT'])/2;
24768 if (!$bSeparate && $details['mbw']['LB']) {
24769 $yadj2 = ($Lw - $details['mbw']['LB'])/2;
24773 if ($Rw && $side=='R' && $this->issetBorder($bord, _BORDER_RIGHT
)) { // RIGHT
24778 $this->SetLineWidth($Rw);
24779 if ($cort == 'cell' || strpos($tablecorner,'T')!==false) {
24780 if ($Rw < $Tw) $yadj = ($Rw +
$Tw)/2;
24781 if ($Rw > $Tw) $yadj = ($Rw - $Tw)/2;
24783 else { $yadj
= $Rw
/2 - $bsv
/2; }
24785 if ($cort == 'cell' || strpos($tablecorner,'B')!==false) {
24786 if ($Rw > $Bw) $yadj2 = ($Rw - $Bw)/2;
24787 if ($Rw < $Bw) $yadj2 = ($Rw +
$Bw)/2;
24789 else { $yadj2
= $Rw
/2 - $bsv
/2; }
24791 if (!$bSeparate && $details['mbw']['RT']) {
24792 $yadj = ($Rw - $details['mbw']['RT'])/2;
24794 if (!$bSeparate && $details['mbw']['RB']) {
24795 $yadj2 = ($Rw - $details['mbw']['RB'])/2;
24799 if ($Bw && $side=='B' && $this->issetBorder($bord, _BORDER_BOTTOM
)) { // BOTTOM
24804 $this->SetLineWidth($Bw);
24805 if ($cort == 'cell' || strpos($tablecorner,'L')!==false) {
24806 if ($Bw > $Lw) $xadj = ($Bw - $Lw)/2;
24807 if ($Bw < $Lw) $xadj = ($Bw +
$Lw)/2;
24809 else { $xadj
= $Bw
/2 - $bsh
/2; }
24810 if ($cort == 'cell' || strpos($tablecorner,'R')!==false) {
24811 if ($Bw > $Rw) $xadj2 = ($Bw - $Rw)/2;
24812 if ($Bw < $Rw) $xadj2 = ($Bw +
$Rw)/2;
24814 else { $xadj2
= $Bw
/2 - $bsh
/2; }
24815 if (!$bSeparate && $details['mbw']['BL']) {
24816 $xadj = ($Bw - $details['mbw']['BL'])/2;
24818 if (!$bSeparate && $details['mbw']['BR']) {
24819 $xadj2 = ($Bw - $details['mbw']['BR'])/2;
24826 /*-- TABLES-ADVANCED-BORDERS --*/
24827 if ($details[$side]['style'] == 'double') {
24828 if (!isset($details[$side]['overlay']) || !$details[$side]['overlay'] || $bSeparate) {
24829 if ($details[$side]['c']) {
24830 $this->SetDColor($details[$side]['c']);
24832 else { $this
->SetDColor($this
->ConvertColor(0)); }
24833 $this->Line($lx1 +
$xadj, $ly1 +
$yadj, $lx2 - $xadj2, $ly2 - $yadj2);
24835 if ((isset($details[$side]['overlay']) && $details[$side]['overlay']) || $bSeparate) {
24836 if ($bSeparate && $cort=='table') {
24838 $xadj -= $this->LineWidth
/2;
24839 $xadj2 -= $this->LineWidth
;
24840 if ($this->issetBorder($bord, _BORDER_LEFT
)) {
24841 $xadj +
= $this->LineWidth
/2;
24843 if ($this->issetBorder($bord, _BORDER_RIGHT
)) {
24844 $xadj2 +
= $this->LineWidth
;
24848 $yadj -= $this->LineWidth
/2;
24849 $yadj2 -= $this->LineWidth
;
24850 if ($this->issetBorder($bord, _BORDER_TOP
)) {
24851 $yadj +
= $this->LineWidth
/2;
24853 if ($this->issetBorder($bord, _BORDER_BOTTOM
)) {
24854 $yadj2 +
= $this->LineWidth
;
24858 $xadj -= $this->LineWidth
/2;
24859 $xadj2 -= $this->LineWidth
;
24860 if ($this->issetBorder($bord, _BORDER_LEFT
)) {
24861 $xadj +
= $this->LineWidth
/2;
24863 if ($this->issetBorder($bord, _BORDER_RIGHT
)) {
24864 $xadj2 +
= $this->LineWidth
;
24868 $yadj -= $this->LineWidth
/2;
24869 $yadj2 -= $this->LineWidth
;
24870 if ($this->issetBorder($bord, _BORDER_TOP
)) {
24871 $yadj +
= $this->LineWidth
/2;
24873 if ($this->issetBorder($bord, _BORDER_BOTTOM
)) {
24874 $yadj2 +
= $this->LineWidth
;
24879 $this->SetLineWidth($this->LineWidth
/3);
24881 $tbcol = $this->ConvertColor(255);
24882 for($l=0; $l <= $this->blklvl
; $l++
) {
24883 if ($this->blk
[$l]['bgcolor']) {
24884 $tbcol = ($this->blk
[$l]['bgcolorarray']); // mPDF 5.6.53
24889 $cellBorderOverlay[] = array(
24890 'x' => $lx1 +
$xadj,
24891 'y' => $ly1 +
$yadj,
24892 'x2' => $lx2 - $xadj2,
24893 'y2' => $ly2 - $yadj2,
24895 'lw' => $this->LineWidth
,
24899 $this->SetDColor($tbcol);
24900 $this->Line($lx1 +
$xadj, $ly1 +
$yadj, $lx2 - $xadj2, $ly2 - $yadj2);
24906 else if (isset($details[$side]['style']) && ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'groove' || $details[$side]['style'] == 'inset' || $details[$side]['style'] == 'outset')) {
24907 if (!isset($details[$side]['overlay']) || !$details[$side]['overlay'] || $bSeparate) {
24908 if ($details[$side]['c']) {
24909 $this->SetDColor($details[$side]['c']);
24911 else { $this
->SetDColor($this
->ConvertColor(0)); }
24912 if ($details[$side]['style'] == 'outset' || $details[$side]['style'] == 'groove') {
24913 $nc = $this->_darkenColor($details[$side]['c']);
24914 $this->SetDColor($nc);
24916 else if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'inset') {
24917 $nc = $this->_lightenColor($details[$side]['c']);
24918 $this->SetDColor($nc);
24920 $this->Line($lx1 +
$xadj, $ly1 +
$yadj, $lx2 - $xadj2, $ly2 - $yadj2);
24922 if ((isset($details[$side]['overlay']) && $details[$side]['overlay']) || $bSeparate) {
24923 if ($details[$side]['c']) {
24924 $this->SetDColor($details[$side]['c']);
24926 else { $this
->SetDColor($this
->ConvertColor(0)); }
24927 $doubleadj = ($this->LineWidth
)/3;
24928 $this->SetLineWidth($this->LineWidth
/2);
24929 $xadj3 = $yadj3 = $wadj3 = $hadj3 = 0;
24931 if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'inset') {
24932 $nc = $this->_darkenColor($details[$side]['c']);
24934 if ($bSeparate && $cort=='table') {
24936 $yadj3 = $this->LineWidth
/2;
24937 $xadj3 = -$this->LineWidth
/2;
24938 $wadj3 = $this->LineWidth
;
24939 if ($this->issetBorder($bord, _BORDER_LEFT
)) {
24940 $xadj3 +
= $this->LineWidth
; $wadj3 -= $this->LineWidth
;
24942 if ($this->issetBorder($bord, _BORDER_RIGHT
)) {
24943 $wadj3 -= $this->LineWidth
*2;
24947 $xadj3 = $this->LineWidth
/2;
24948 $yadj3 = -$this->LineWidth
/2;
24949 $hadj3 = $this->LineWidth
;
24950 if ($this->issetBorder($bord, _BORDER_TOP
)) {
24951 $yadj3 +
= $this->LineWidth
; $hadj3 -= $this->LineWidth
;
24953 if ($this->issetBorder($bord, _BORDER_BOTTOM
)) {
24954 $hadj3 -= $this->LineWidth
*2;
24958 $yadj3 = $this->LineWidth
/2;
24959 $xadj3 = -$this->LineWidth
/2;
24960 $wadj3 = $this->LineWidth
;
24963 $xadj3 = $this->LineWidth
/2;
24964 $yadj3 = -$this->LineWidth
/2;
24965 $hadj3 = $this->LineWidth
;
24969 else if ($side=='T') { $yadj3
= $this
->LineWidth
/2; $xadj3
= $this
->LineWidth
/2; $wadj3
= -$this
->LineWidth
*2; }
24970 else if ($side=='L') { $xadj3
= $this
->LineWidth
/2; $yadj3
= $this
->LineWidth
/2; $hadj3
= -$this
->LineWidth
*2; }
24972 else if ($side=='B' && $bSeparate) { $yadj3
= $this
->LineWidth
/2; $wadj3
= $this
->LineWidth
/2; }
24973 else if ($side=='R' && $bSeparate) { $xadj3
= $this
->LineWidth
/2; $hadj3
= $this
->LineWidth
/2; }
24975 else if ($side=='B') { $yadj3
= $this
->LineWidth
/2; $xadj3
= $this
->LineWidth
/2; }
24976 else if ($side=='R') { $xadj3
= $this
->LineWidth
/2; $yadj3
= $this
->LineWidth
/2; }
24979 $nc = $this->_lightenColor($details[$side]['c']);
24981 if ($bSeparate && $cort=='table') {
24983 $yadj3 = $this->LineWidth
/2;
24984 $xadj3 = -$this->LineWidth
/2;
24985 $wadj3 = $this->LineWidth
;
24986 if ($this->issetBorder($bord, _BORDER_LEFT
)) {
24987 $xadj3 +
= $this->LineWidth
; $wadj3 -= $this->LineWidth
;
24991 $xadj3 = $this->LineWidth
/2;
24992 $yadj3 = -$this->LineWidth
/2;
24993 $hadj3 = $this->LineWidth
;
24994 if ($this->issetBorder($bord, _BORDER_TOP
)) {
24995 $yadj3 +
= $this->LineWidth
; $hadj3 -= $this->LineWidth
;
24999 $yadj3 = $this->LineWidth
/2;
25000 $xadj3 = -$this->LineWidth
/2;
25001 $wadj3 = $this->LineWidth
;
25002 if ($this->issetBorder($bord, _BORDER_LEFT
)) {
25003 $xadj3 +
= $this->LineWidth
; $wadj3 -= $this->LineWidth
;
25007 $xadj3 = $this->LineWidth
/2;
25008 $yadj3 = -$this->LineWidth
/2;
25009 $hadj3 = $this->LineWidth
;
25010 if ($this->issetBorder($bord, _BORDER_TOP
)) {
25011 $yadj3 +
= $this->LineWidth
; $hadj3 -= $this->LineWidth
;
25016 else if ($side=='T') { $yadj3
= $this
->LineWidth
/2; $xadj3
= $this
->LineWidth
/2; }
25017 else if ($side=='L') { $xadj3
= $this
->LineWidth
/2; $yadj3
= $this
->LineWidth
/2; }
25019 else if ($side=='B' && $bSeparate) { $yadj3
= $this
->LineWidth
/2; $xadj3
= $this
->LineWidth
/2; }
25020 else if ($side=='R' && $bSeparate) { $xadj3
= $this
->LineWidth
/2; $yadj3
= $this
->LineWidth
/2; }
25022 else if ($side=='B') { $yadj3
= $this
->LineWidth
/2; $xadj3
= -$this
->LineWidth
/2; $wadj3
= $this
->LineWidth
; }
25023 else if ($side=='R') { $xadj3
= $this
->LineWidth
/2; $yadj3
= -$this
->LineWidth
/2; $hadj3
= $this
->LineWidth
; }
25028 $cellBorderOverlay[] = array(
25029 'x' => $lx1 +
$xadj +
$xadj3,
25030 'y' => $ly1 +
$yadj +
$yadj3,
25031 'x2' => $lx2 - $xadj2 +
$xadj3 +
$wadj3,
25032 'y2' => $ly2 - $yadj2 +
$yadj3 +
$hadj3,
25034 'lw' => $this->LineWidth
,
25038 $this->SetDColor($nc);
25039 $this->Line($lx1 +
$xadj +
$xadj3, $ly1 +
$yadj +
$yadj3, $lx2 - $xadj2 +
$xadj3 +
$wadj3, $ly2 - $yadj2 +
$yadj3 +
$hadj3);
25046 /*-- END TABLES-ADVANCED-BORDERS --*/
25047 if ($details[$side]['style'] == 'dashed') {
25048 $dashsize = 2; // final dash will be this + 1*linewidth
25049 $dashsizek = 1.5; // ratio of Dash/Blank
25050 $this->SetDash($dashsize,($dashsize/$dashsizek)+
($this->LineWidth
*2));
25052 else if ($details[$side]['style'] == 'dotted') {
25053 $this->SetLineJoin(1);
25054 $this->SetLineCap(1);
25055 $this->SetDash(0.001,($this->LineWidth
*2));
25057 if ($details[$side]['c']) {
25058 $this->SetDColor($details[$side]['c']);
25060 else { $this
->SetDColor($this
->ConvertColor(0)); }
25061 $this->Line($lx1 +
$xadj, $ly1 +
$yadj, $lx2 - $xadj2, $ly2 - $yadj2);
25062 /*-- TABLES-ADVANCED-BORDERS --*/
25064 /*-- END TABLES-ADVANCED-BORDERS --*/
25068 //BUTT style line cap
25069 $this->SetLineCap(2);
25073 if ($bSeparate && count($cellBorderOverlay)) {
25074 foreach($cellBorderOverlay AS $cbo) {
25075 $this->SetLineWidth($cbo['lw']);
25076 $this->SetDColor($cbo['col']);
25077 $this->Line($cbo['x'], $cbo['y'], $cbo['x2'], $cbo['y2']);
25081 // $this->SetLineWidth($oldlinewidth);
25082 // $this->SetDColor($this->ConvertColor(0));
25088 /*-- TABLES-ADVANCED-BORDERS --*/
25089 function _lightenColor($c) {
25090 if (is_array($c)) { die('Color error in _lightencolor'); }
25091 if ($c{0}==3 || $c{0}==5) { // RGB
25092 list($h,$s,$l) = $this->rgb2hsl(ord($c{1})/255,ord($c{2})/255,ord($c{3})/255);
25093 $l +
= ((1 - $l)*0.8);
25094 list($r,$g,$b) = $this->hsl2rgb($h,$s,$l);
25095 $ret = array(3,$r,$g,$b);
25097 else if ($c{0}==4 || $c{0}==6) { // CMYK
25098 $ret = array(4, max(0,(ord($c{1})-20)), max(0,(ord($c{2})-20)), max(0,(ord($c{3})-20)), max(0,(ord($c{4})-20)) );
25100 else if ($c{0}==1) { // Grayscale
25101 $ret = array(1,min(255,(ord($c{1})+
32)));
25103 $c = array_pad($ret, 6, 0);
25104 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
25109 function _darkenColor($c) {
25110 if (is_array($c)) { die('Color error in _darkenColor'); }
25111 if ($c{0}==3 || $c{0}==5) { // RGB
25112 list($h,$s,$l) = $this->rgb2hsl(ord($c{1})/255,ord($c{2})/255,ord($c{3})/255);
25115 list($r,$g,$b) = $this->hsl2rgb($h,$s,$l);
25116 $ret = array(3,$r,$g,$b);
25118 else if ($c{0}==4 || $c{0}==6) { // CMYK
25119 $ret = array(4, min(100,(ord($c{1})+
20)), min(100,(ord($c{2})+
20)), min(100,(ord($c{3})+
20)), min(100,(ord($c{4})+
20)) );
25121 else if ($c{0}==1) { // Grayscale
25122 $ret = array(1,max(0,(ord($c{1})-32)));
25124 $c = array_pad($ret, 6, 0);
25125 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
25129 /*-- END TABLES-ADVANCED-BORDERS --*/
25133 function setBorder(&$var, $flag, $set = true) {
25134 $flag = intval($flag);
25135 if ($set) { $set
= true; }
25136 $var = intval($var);
25137 $var = $set ? ($var | $flag) : ($var & ~
$flag);
25139 function issetBorder($var, $flag) {
25140 $flag = intval($flag);
25141 $var = intval($var);
25142 return (($var & $flag) == $flag);
25146 function _table2cellBorder(&$tableb, &$cbdb, &$cellb, $bval) {
25147 if ($tableb && $tableb['w'] > $cbdb['w']) {
25149 $this->setBorder($cellb, $bval);
25151 else if ($tableb && $tableb['w'] == $cbdb['w']
25152 && array_search($tableb['style'],$this->borderstyles
) > array_search($cbdb['style'],$this->borderstyles
)) {
25154 $this->setBorder($cellb, $bval);
25158 // FIX BORDERS ********************************************
25159 function _fixTableBorders(&$table){
25160 if ($this->cacheTables
) { $fh
= fopen($table
['cache'], "r+b"); }
25161 else { $fh
= null; }
25163 if (!$table['borders_separate'] && $table['border_details']['L']['w']) {
25164 $table['max_cell_border_width']['L'] = $table['border_details']['L']['w'];
25166 if (!$table['borders_separate'] && $table['border_details']['R']['w']) {
25167 $table['max_cell_border_width']['R'] = $table['border_details']['R']['w'];
25169 if (!$table['borders_separate'] && $table['border_details']['T']['w']) {
25170 $table['max_cell_border_width']['T'] = $table['border_details']['T']['w'];
25172 if (!$table['borders_separate'] && $table['border_details']['B']['w']) {
25173 $table['max_cell_border_width']['B'] = $table['border_details']['B']['w'];
25175 if ($this->simpleTables
) { return; }
25176 $cells = &$table['cells'];
25177 $numcols = $table['nc'];
25178 $numrows = $table['nr'];
25179 /*-- TABLES-ADVANCED-BORDERS --*/
25180 if (isset($table['topntail']) && $table['topntail']) { $tntborddet
= $this
->border_details($table
['topntail']); }
25181 if (isset($table['thead-underline']) && $table['thead-underline']) { $thuborddet
= $this
->border_details($table
['thead-underline']); }
25182 /*-- END TABLES-ADVANCED-BORDERS --*/
25184 for( $i = 0 ; $i < $numrows ; $i++
) { //Rows
25185 for( $j = 0 ; $j < $numcols ; $j++
) { //Columns
25186 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25187 if ($this->cacheTables
) {
25188 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25191 $cell = &$cells[$i][$j];
25192 if ($this->packTableData
) { // includes $this->cacheTables
25193 $cbord = $this->_unpackCellBorder($cell['borderbin']);
25196 $cbord = &$cells[$i][$j];
25199 if (!$cbord['border'] && isset($table['border']) && $table['border'] && $this->table_border_attr_set
) {
25200 $cbord['border'] = $table['border'];
25201 $cbord['border_details'] = $table['border_details'];
25204 if (isset($cell['colspan']) && $cell['colspan']>1) { $ccolsp
= $cell
['colspan']; }
25205 else { $ccolsp
= 1; }
25206 if (isset($cell['rowspan']) && $cell['rowspan']>1) { $crowsp
= $cell
['rowspan']; }
25207 else { $crowsp
= 1; }
25209 $cbord['border_details']['cellposdom'] = ((($i+
1)/$numrows) / 10000 ) +
((($j+
1)/$numcols) / 10 );
25210 // Inherit Cell border from Table border
25211 if ($this->table_border_css_set
&& !$table['borders_separate']) {
25213 $this->_table2cellBorder($table['border_details']['T'], $cbord['border_details']['T'], $cbord['border'], _BORDER_TOP
);
25215 if ($i == ($numrows-1) || ($i+
$crowsp) == ($numrows) ) {
25216 $this->_table2cellBorder($table['border_details']['B'], $cbord['border_details']['B'], $cbord['border'], _BORDER_BOTTOM
);
25219 $this->_table2cellBorder($table['border_details']['L'], $cbord['border_details']['L'], $cbord['border'], _BORDER_LEFT
);
25221 if ($j == ($numcols-1) || ($j+
$ccolsp) == ($numcols) ) {
25222 $this->_table2cellBorder($table['border_details']['R'], $cbord['border_details']['R'], $cbord['border'], _BORDER_RIGHT
);
25226 /*-- TABLES-ADVANCED-BORDERS --*/
25228 if (isset($table['topntail']) && $table['topntail']) {
25230 $cbord['border_details']['T'] = $tntborddet;
25231 $this->setBorder($cbord['border'], _BORDER_TOP
);
25233 if ($this->tableLevel
==1 && $table['headernrows']>0 && $i == $table['headernrows']-1) {
25234 $cbord['border_details']['B'] = $tntborddet;
25235 $this->setBorder($cbord['border'], _BORDER_BOTTOM
);
25236 $fixbottom = false;
25238 else if ($this->tableLevel
==1 && $table['headernrows']>0 && $i == $table['headernrows']) {
25239 if (!$table['borders_separate']) {
25240 $cbord['border_details']['T'] = $tntborddet;
25241 $this->setBorder($cbord['border'], _BORDER_TOP
);
25244 if ($this->tableLevel
==1 && $table['footernrows']>0 && $i == ($numrows-$table['footernrows']-1)) {
25245 if (!$table['borders_separate']) {
25246 $cbord['border_details']['B'] = $tntborddet;
25247 $this->setBorder($cbord['border'], _BORDER_BOTTOM
);
25248 $fixbottom = false;
25251 else if ($this->tableLevel
==1 && $table['footernrows']>0 && $i == ($numrows-$table['footernrows'])) {
25252 $cbord['border_details']['T'] = $tntborddet;
25253 $this->setBorder($cbord['border'], _BORDER_TOP
);
25255 if ($this->tabletheadjustfinished
) { // $this->tabletheadjustfinished called from tableheader
25256 if (!$table['borders_separate']) {
25257 $cbord['border_details']['T'] = $tntborddet;
25258 $this->setBorder($cbord['border'], _BORDER_TOP
);
25261 if ($i == ($numrows-1) || ($i+
$crowsp) == ($numrows) ) {
25262 $cbord['border_details']['B'] = $tntborddet;
25263 $this->setBorder($cbord['border'], _BORDER_BOTTOM
);
25266 if (isset($table['thead-underline']) && $table['thead-underline']) {
25267 if ($table['borders_separate']) {
25269 $cbord['border_details']['B'] = $thuborddet;
25270 $this->setBorder($cbord['border'], _BORDER_BOTTOM
);
25271 $fixbottom = false;
25275 if ($this->tableLevel
==1 && $table['headernrows']>0 && $i == $table['headernrows']-1) {
25276 $cbord['border_details']['T'] = $thuborddet;
25277 $this->setBorder($cbord['border'], _BORDER_TOP
);
25279 else if ($this->tabletheadjustfinished
) { // $this->tabletheadjustfinished called from tableheader
25280 $cbord['border_details']['T'] = $thuborddet;
25281 $this->setBorder($cbord['border'], _BORDER_TOP
);
25286 // Collapse Border - Algorithm for conflicting borders
25287 // Hidden >> Width >> double>solid>dashed>dotted... >> style set on cell>table >> top/left>bottom/right
25288 // Do not turn off border which is overridden
25289 // Needed for page break for TOP/BOTTOM both to be defined in Collapsed borders
25290 // Means it is painted twice. (Left/Right can still disable overridden border)
25291 if (!$table['borders_separate']) {
25292 if (($i < ($numrows-1) || ($i+
$crowsp) < $numrows ) && $fixbottom ) { // Bottom
25293 for ($cspi = 0; $cspi<$ccolsp; $cspi++
) {
25294 // already defined Top for adjacent cell below
25295 if (isset($cells[($i+
$crowsp)][$j+
$cspi])) {
25296 if ($this->packTableData
) {
25297 if ($this->cacheTables
) {
25298 $adjc = $this->_uncacheCell($table['cells'][$i+
$crowsp][$j+
$cspi], '', $fh);
25300 else { $adjc
= $cells
[($i+$crowsp
)][$j+$cspi
]; }
25301 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25303 else { $celladj
=& $cells
[($i+$crowsp
)][$j+$cspi
]; }
25305 else { $celladj
= false; }
25306 if ($celladj && $celladj['border_details']['T']['s'] == 1) {
25307 $csadj = $celladj['border_details']['T']['w'];
25308 $csthis = $cbord['border_details']['B']['w'];
25310 if ($cbord['border_details']['B']['style']=='hidden') {
25311 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25312 $this->setBorder($celladj['border'] , _BORDER_TOP
, false);
25313 $this->setBorder($cbord['border'] , _BORDER_BOTTOM
, false);
25315 else if ($celladj['border_details']['T']['style']=='hidden') {
25316 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25317 $this->setBorder($cbord['border'] , _BORDER_BOTTOM
, false);
25318 $this->setBorder($celladj['border'] , _BORDER_TOP
, false);
25321 else if ($csthis > $csadj) {
25322 if (!isset($cells[($i+
$crowsp)][$j+
$cspi]['colspan']) || (isset($cells[($i+
$crowsp)][$j+
$cspi]['colspan']) && $cells[($i+
$crowsp)][$j+
$cspi]['colspan']<2)) { // don't overwrite bordering cells that span
25323 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25324 $this->setBorder($cbord['border'] , _BORDER_BOTTOM
);
25327 else if ($csadj > $csthis) {
25328 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25329 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25330 $this->setBorder($celladj['border'] , _BORDER_TOP
);
25334 // double>solid>dashed>dotted...
25335 else if (array_search($cbord['border_details']['B']['style'],$this->borderstyles
) > array_search($celladj['border_details']['T']['style'],$this->borderstyles
)) {
25336 if (!isset($cells[($i+
$crowsp)][$j+
$cspi]['colspan']) || (isset($cells[($i+
$crowsp)][$j+
$cspi]['colspan']) && $cells[($i+
$crowsp)][$j+
$cspi]['colspan']<2)) { // don't overwrite bordering cells that span
25337 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25338 $this->setBorder($cbord['border'] , _BORDER_BOTTOM
);
25341 else if (array_search($celladj['border_details']['T']['style'],$this->borderstyles
) > array_search($cbord['border_details']['B']['style'],$this->borderstyles
)) {
25342 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25343 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25344 $this->setBorder($celladj['border'] , _BORDER_TOP
);
25350 // Style set on cell vs. table
25351 else if ($celladj['border_details']['T']['dom'] > $cbord['border_details']['B']['dom']) {
25352 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25353 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25354 $this->setBorder($celladj['border'] , _BORDER_TOP
);
25357 // Style set on cell vs. table - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT
25359 if (!isset($cells[($i+
$crowsp)][$j+
$cspi]['colspan']) || (isset($cells[($i+
$crowsp)][$j+
$cspi]['colspan']) && $cells[($i+
$crowsp)][$j+
$cspi]['colspan']<2)) { // don't overwrite bordering cells that span
25360 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25361 $this->setBorder($cbord['border'] , _BORDER_BOTTOM
);
25365 else if ($celladj) {
25366 if (!isset($cells[($i+
$crowsp)][$j+
$cspi]['colspan']) || (isset($cells[($i+
$crowsp)][$j+
$cspi]['colspan']) && $cells[($i+
$crowsp)][$j+
$cspi]['colspan']<2)) { // don't overwrite bordering cells that span
25367 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25370 if ($celladj && $this->packTableData
) {
25371 $celladj['borderbin'] = $this->_packCellBorder($celladj);
25372 unset($celladj['border']);
25373 unset($celladj['border_details']);
25375 if ($this->cacheTables
) {
25376 $this->_cacheUpdateBorder($celladj, $fh, $table['cells'][$i+
$crowsp][$j+
$cspi]);
25382 if ($j < ($numcols-1) || ($j+
$ccolsp) < $numcols ) { // Right-Left
25383 for ($cspi = 0; $cspi<$crowsp; $cspi++
) {
25384 // already defined Left for adjacent cell to R
25385 if (isset($cells[($i+
$cspi)][$j+
$ccolsp])) {
25386 if ($this->packTableData
) {
25387 if ($this->cacheTables
) {
25388 $adjc = $this->_uncacheCell($table['cells'][$i+
$cspi][$j+
$ccolsp], '', $fh);
25390 else { $adjc
= $cells
[($i+$cspi
)][$j+$ccolsp
]; }
25391 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25393 else { $celladj
=& $cells
[$i+$cspi
][$j+$ccolsp
]; }
25395 else { $celladj
= false; }
25396 if ($celladj && $celladj['border_details']['L']['s'] == 1) {
25397 $csadj = $celladj['border_details']['L']['w'];
25398 $csthis = $cbord['border_details']['R']['w'];
25400 if ($cbord['border_details']['R']['style']=='hidden') {
25401 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25402 $this->setBorder($celladj['border'] , _BORDER_LEFT
, false);
25403 $this->setBorder($cbord['border'] , _BORDER_RIGHT
, false);
25405 else if ($celladj['border_details']['L']['style']=='hidden') {
25406 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25407 $this->setBorder($cbord['border'] , _BORDER_RIGHT
, false);
25408 $this->setBorder($celladj['border'] , _BORDER_LEFT
, false);
25411 else if ($csthis > $csadj) {
25412 if (!isset($cells[($i+
$cspi)][$j+
$ccolsp]['rowspan']) || (isset($cells[($i+
$cspi)][$j+
$ccolsp]['rowspan']) && $cells[($i+
$cspi)][$j+
$ccolsp]['rowspan']<2)) { // don't overwrite bordering cells that span
25413 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25414 $this->setBorder($cbord['border'] , _BORDER_RIGHT
);
25415 $this->setBorder($celladj['border'] , _BORDER_LEFT
, false);
25418 else if ($csadj > $csthis) {
25419 if ($crowsp < 2) { // don't overwrite this cell if it spans
25420 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25421 $this->setBorder($cbord['border'] , _BORDER_RIGHT
, false);
25422 $this->setBorder($celladj['border'] , _BORDER_LEFT
);
25426 // double>solid>dashed>dotted...
25427 else if (array_search($cbord['border_details']['R']['style'],$this->borderstyles
) > array_search($celladj['border_details']['L']['style'],$this->borderstyles
)) {
25428 if (!isset($cells[($i+
$cspi)][$j+
$ccolsp]['rowspan']) || (isset($cells[($i+
$cspi)][$j+
$ccolsp]['rowspan']) && $cells[($i+
$cspi)][$j+
$ccolsp]['rowspan']<2)) { // don't overwrite bordering cells that span
25429 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25430 $this->setBorder($celladj['border'] , _BORDER_LEFT
, false);
25431 $this->setBorder($cbord['border'] , _BORDER_RIGHT
);
25434 else if (array_search($celladj['border_details']['L']['style'],$this->borderstyles
) > array_search($cbord['border_details']['R']['style'],$this->borderstyles
)) {
25435 if ($crowsp < 2) { // don't overwrite this cell if it spans
25436 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25437 $this->setBorder($cbord['border'] , _BORDER_RIGHT
, false);
25438 $this->setBorder($celladj['border'] , _BORDER_LEFT
);
25443 // Style set on cell vs. table
25444 else if ($celladj['border_details']['L']['dom'] > $cbord['border_details']['R']['dom']) {
25445 if ($crowsp < 2) { // don't overwrite this cell if it spans
25446 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25447 $this->setBorder($celladj['border'] , _BORDER_LEFT
);
25450 // Style set on cell vs. table - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT
25452 if (!isset($cells[($i+
$cspi)][$j+
$ccolsp]['rowspan']) || (isset($cells[($i+
$cspi)][$j+
$ccolsp]['rowspan']) && $cells[($i+
$cspi)][$j+
$ccolsp]['rowspan']<2)) { // don't overwrite bordering cells that span
25453 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25454 $this->setBorder($cbord['border'] , _BORDER_RIGHT
);
25458 else if ($celladj) {
25459 // if right-cell border is not set
25460 if (!isset($cells[($i+
$cspi)][$j+
$ccolsp]['rowspan']) || (isset($cells[($i+
$cspi)][$j+
$ccolsp]['rowspan']) && $cells[($i+
$cspi)][$j+
$ccolsp]['rowspan']<2)) { // don't overwrite bordering cells that span
25461 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25464 if ($celladj && $this->packTableData
) {
25465 $celladj['borderbin'] = $this->_packCellBorder($celladj);
25466 unset($celladj['border']);
25467 unset($celladj['border_details']);
25469 if ($this->cacheTables
) {
25470 $this->_cacheUpdateBorder($celladj, $fh, $table['cells'][$i+
$cspi][$j+
$ccolsp]);
25478 // Set maximum cell border width meeting at LRTB edges of cell - used for extended cell border
25479 // ['border_details']['mbw']['LT'] = meeting border width - Left border - Top end
25480 if (!$table['borders_separate']) {
25481 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $cbord['border_details']['L']['w']);
25482 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $cbord['border_details']['R']['w']);
25483 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $cbord['border_details']['T']['w']);
25484 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $cbord['border_details']['B']['w']);
25485 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $cbord['border_details']['L']['w']);
25486 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $cbord['border_details']['R']['w']);
25487 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $cbord['border_details']['T']['w']);
25488 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $cbord['border_details']['B']['w']);
25489 if (($i+
$crowsp) < $numrows && isset($cells[$i+
$crowsp][$j])) { // Has Bottom adjoining cell
25490 if ($this->packTableData
) {
25491 if ($this->cacheTables
) {
25492 $adjc = $this->_uncacheCell($table['cells'][$i+
$crowsp][$j], '', $fh);
25494 else { $adjc
= $cells
[$i+$crowsp
][$j
]; }
25495 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25497 else { $celladj
=& $cells
[$i+$crowsp
][$j
]; }
25498 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $celladj['border_details']['L']['w'], $celladj['border_details']['mbw']['TL']);
25499 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $celladj['border_details']['R']['w'], $celladj['border_details']['mbw']['TR']);
25500 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $celladj['border_details']['mbw']['LT']);
25501 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $celladj['border_details']['mbw']['RT']);
25504 if (($j+
$ccolsp) < $numcols && isset($cells[$i][$j+
$ccolsp])) { // Has Right adjoining cell
25505 if ($this->packTableData
) {
25506 if ($this->cacheTables
) {
25507 $adjc = $this->_uncacheCell($table['cells'][$i][$j+
$ccolsp], '', $fh);
25509 else { $adjc
= $cells
[$i
][$j+$ccolsp
]; }
25510 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25512 else { $celladj
=& $cells
[$i
][$j+$ccolsp
]; }
25513 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $celladj['border_details']['T']['w'], $celladj['border_details']['mbw']['LT']);
25514 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $celladj['border_details']['B']['w'], $celladj['border_details']['mbw']['LB']);
25515 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $celladj['border_details']['mbw']['TL']);
25516 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $celladj['border_details']['mbw']['BL']);
25520 if ($i > 0 && isset($cells[$i-1][$j]) && (($this->packTableData
&& $cells[$i-1][$j]['borderbin']) || $cells[$i-1][$j]['border'])) { // Has Top adjoining cell
25521 if ($this->packTableData
) {
25522 if ($this->cacheTables
) {
25523 $adjc = $this->_uncacheCell($table['cells'][$i-1][$j], '', $fh);
25525 else { $adjc
= $cells
[$i
-1][$j
]; }
25526 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25528 else { $celladj
=& $cells
[$i
-1][$j
]; }
25529 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['L']['w'], $celladj['border_details']['mbw']['BL']);
25530 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $celladj['border_details']['R']['w'], $celladj['border_details']['mbw']['BR']);
25531 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $celladj['border_details']['mbw']['LB']);
25532 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $celladj['border_details']['mbw']['RB']);
25534 if ($celladj['border_details']['mbw']['BL']) {
25535 $celladj['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['mbw']['BL']);
25537 if ($celladj['border_details']['mbw']['BR'] ) {
25538 $celladj['border_details']['mbw']['BR'] = max($celladj['border_details']['mbw']['BR'], $cbord['border_details']['mbw']['TR']);
25540 if ($this->packTableData
) { $cells
[$i
-1][$j
]['borderbin'] = $this
->_packCellBorder($celladj
); }
25543 if ($j > 0 && isset($cells[$i][$j-1]) && (($this->packTableData
&& $cells[$i][$j-1]['borderbin']) || $cells[$i][$j-1]['border'])) { // Has Left adjoining cell
25544 if ($this->packTableData
) {
25545 if ($this->cacheTables
) {
25546 $adjc = $this->_uncacheCell($table['cells'][$i][$j-1], '', $fh);
25548 else { $adjc
= $cells
[$i
][$j
-1]; }
25549 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25551 else { $celladj
=& $cells
[$i
][$j
-1]; }
25552 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $celladj['border_details']['T']['w'], $celladj['border_details']['mbw']['RT']);
25553 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $celladj['border_details']['B']['w'], $celladj['border_details']['mbw']['RB']);
25554 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $celladj['border_details']['mbw']['BR']);
25555 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['mbw']['TR']);
25557 if ($celladj['border_details']['mbw']['RT']) {
25558 $celladj['border_details']['mbw']['RT'] = max($celladj['border_details']['mbw']['RT'], $cbord['border_details']['mbw']['LT']);
25560 if ($celladj['border_details']['mbw']['RB']) {
25561 $celladj['border_details']['mbw']['RB'] = max($celladj['border_details']['mbw']['RB'], $cbord['border_details']['mbw']['LB']);
25563 if ($this->packTableData
) { $cells
[$i
][$j
-1]['borderbin'] = $this
->_packCellBorder($celladj
); }
25568 // Update maximum cell border width at LRTB edges of table - used for overall table width
25569 if ($j == 0 && $cbord['border_details']['L']['w']) {
25570 $table['max_cell_border_width']['L'] = max($table['max_cell_border_width']['L'],$cbord['border_details']['L']['w']);
25572 if (($j == ($numcols-1) || ($j+
$ccolsp) == $numcols ) && $cbord['border_details']['R']['w']) {
25573 $table['max_cell_border_width']['R'] = max($table['max_cell_border_width']['R'],$cbord['border_details']['R']['w']);
25575 if ($i == 0 && $cbord['border_details']['T']['w']) {
25576 $table['max_cell_border_width']['T'] = max($table['max_cell_border_width']['T'],$cbord['border_details']['T']['w']);
25578 if (($i == ($numrows-1) || ($i+
$crowsp) == $numrows ) && $cbord['border_details']['B']['w']) {
25579 $table['max_cell_border_width']['B'] = max($table['max_cell_border_width']['B'],$cbord['border_details']['B']['w']);
25582 /*-- END TABLES-ADVANCED-BORDERS --*/
25584 if ($this->packTableData
) { $cell
['borderbin'] = $this
->_packCellBorder($cbord
); }
25586 if ($this->cacheTables
) {
25587 $this->_cacheUpdateBorder($cell, $fh, $table['cells'][$i][$j]);
25594 if ($this->cacheTables
) { fclose($fh
); }
25597 // END FIX BORDERS ************************************************************************************
25600 function _reverseTableDir(&$table) {
25601 if ($this->cacheTables
) { $fh
= fopen($table
['cache'], "r+b"); }
25602 $cells = &$table['cells'];
25603 $numcols = $table['nc'];
25604 $numrows = $table['nr'];
25605 for( $i = 0 ; $i < $numrows ; $i++
) { //Rows
25607 for( $j = ($numcols-1) ; $j >= 0 ; $j-- ) { //Columns
25608 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25609 if ($this->cacheTables
) {
25610 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25613 $cell = &$cells[$i][$j];
25614 $col = $numcols - $j - 1;
25615 if (isset($cell['colspan']) && $cell['colspan'] > 1) { $col
-= ($cell
['colspan']-1); }
25617 for ($n=0; $n < count($cell['textbuffer']); $n++
) {
25618 $t = $cell['textbuffer'][$n][0];
25619 if (substr($t,0,19) == "\xbb\xa4\xactype=nestedtable") {
25620 $objattr = $this->_getObjAttr($t);
25621 $objattr['col'] = $col;
25622 $cell['textbuffer'][$n][0] = "\xbb\xa4\xactype=nestedtable,objattr=".serialize($objattr)."\xbb\xa4\xac";
25623 $this->table
[($this->tableLevel+
1)][$objattr['nestedcontent']]['nestedpos'][1] = $col;
25624 if ($this->cacheTables
) {
25625 $this->_cacheUpdateTxB($cell, $fh, $table['cells'][$i][$j]);
25629 $row[$col] = $cells[$i][$j];
25633 for($f=0; $f < $numcols; $f++
) {
25634 if (!isset($row[$f])) { $row
[$f
] = 0; }
25636 $table['cells'][$i] = $row;
25638 if ($this->cacheTables
) { fclose($fh
); }
25642 function _tableWrite(&$table, $split=false, $startrow=0, $startcol=0, $splitpg=0, $rety = 0){
25643 $level = $table['level'];
25644 $levelid = $table['levelid'];
25646 $cells = &$table['cells'];
25647 $numcols = $table['nc'];
25648 $numrows = $table['nr'];
25650 if ($this->ColActive
&& $level==1) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
25652 if (!$split || ($startrow==0 && $splitpg==0) || $startrow>0){
25653 // TABLE TOP MARGIN
25654 if ($table['margin']['T']) {
25655 if (!$this->table_rotate
&& $level==1) {
25656 $this->DivLn($table['margin']['T'],$this->blklvl
,true,1); // collapsible
25659 $this->y +
= ($table['margin']['T']);
25662 // Advance down page by half width of top border
25663 if ($table['borders_separate']) {
25664 if ($startrow>0 && (!isset($table['is_thead']) || count($table['is_thead'])==0))
25665 $adv = $table['border_spacing_V']/2;
25667 $adv = $table['padding']['T'] +
$table['border_details']['T']['w'] +
$table['border_spacing_V']/2;
25670 $adv = $table['max_cell_border_width']['T']/2;
25672 if (!$this->table_rotate
&& $level==1) { $this
->DivLn($adv
); }
25673 else { $this
->y +
= $adv
; }
25677 $this->x
= $this->lMargin +
$this->blk
[$this->blklvl
]['outer_left_margin'] +
$this->blk
[$this->blklvl
]['padding_left'] +
$this->blk
[$this->blklvl
]['border_left']['w'];
25680 $right = $x0 +
$this->blk
[$this->blklvl
]['inner_width'];
25681 $outerfilled = $this->y
; // Keep track of how far down the outer DIV bgcolor is painted (NB rowspans)
25682 $this->outerfilled
= $this->y
;
25683 $this->colsums
= array();
25688 $right = $x0 +
$table['w'];
25691 if ($this->table_rotate
) {
25692 $temppgwidth = $this->tbrot_maxw
;
25693 $this->PageBreakTrigger
= $pagetrigger = $y0 +
($this->blk
[$this->blklvl
]['inner_width']);
25695 $this->tbrot_y0
= $this->y
- $adv - $table['margin']['T'] ;
25696 $this->tbrot_x0
= $this->x
;
25697 $this->tbrot_w
= $table['w'];
25698 if ($table['borders_separate']) { $this
->tbrot_h
= $table
['margin']['T'] + $table
['padding']['T'] + $table
['border_details']['T']['w'] + $table
['border_spacing_V']/2; }
25699 else { $this
->tbrot_h
= $table
['margin']['T'] + $table
['padding']['T'] + $table
['max_cell_border_width']['T']; }
25703 $this->PageBreakTrigger
= $pagetrigger = ($this->h
- $this->bMargin
);
25705 $temppgwidth = $this->blk
[$this->blklvl
]['inner_width'];
25706 if (isset($table['a']) and ($table['w'] < $this->blk
[$this->blklvl
]['inner_width'])) {
25707 if ($table['a']=='C') { $x0 +
= ((($right
-$x0
) - $table
['w'])/2); }
25708 else if ($table['a']=='R') { $x0
= $right
- $table
['w']; }
25712 $temppgwidth = $table['w'];
25715 if(!isset($table['overflow'])) { $table
['overflow'] = null; }
25716 if ($table['overflow']=='hidden' && $level==1 && !$this->table_rotate
&& !$this->ColActive
) {
25717 //Bounding rectangle to clip
25718 $this->tableClipPath
= sprintf('q %.3F %.3F %.3F %.3F re W n',$x0*_MPDFK
,$this->h
*_MPDFK
,$this->blk
[$this->blklvl
]['inner_width']*_MPDFK
,-$this->h
*_MPDFK
);
25719 $this->_out($this->tableClipPath
);
25721 else { $this
->tableClipPath
= ''; }
25724 if ($table['borders_separate']) { $indent
= $table
['margin']['L'] + $table
['border_details']['L']['w'] + $table
['padding']['L'] + $table
['border_spacing_H']/2; }
25725 else { $indent
= $table
['margin']['L'] + $table
['max_cell_border_width']['L']/2; }
25730 $tableheader = array();
25731 $tablefooter = array();
25732 $tableheaderrowheight = 0;
25733 $tablefooterrowheight = 0;
25736 // mPD 3.0 Set the Page & Column where table starts
25737 if (($this->mirrorMargins
) && (($this->page
)%
2==0)) { // EVEN
25738 $tablestartpage = 'EVEN';
25740 else if (($this->mirrorMargins
) && (($this->page
)%
2==1)) { // ODD
25741 $tablestartpage = 'ODD';
25743 else { $tablestartpage
= ''; }
25744 if ($this->ColActive
) { $tablestartcolumn
= $this
->CurrCol
; }
25745 else { $tablestartcolumn
= ''; }
25747 if ($this->cacheTables
) { $fh
= fopen($table
['cache'], "r+b"); }
25748 else { $fh
= null; }
25751 for( $i = 0; $i < $numrows ; $i++
) { //Rows
25752 if ($this->progressBar
) { $this
->UpdateProgressBar(7,intval(30 +
($i
*40/$numrows
)),' '); } // *PROGRESS-BAR*
25753 if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i] && $level==1) {
25754 $tablefooterrowheight +
= $table['hr'][$i];
25755 $tablefooter[$i][0]['trbackground-images'] = $table['trbackground-images'][$i];
25756 $tablefooter[$i][0]['trgradients'] = $table['trgradients'][$i];
25757 $tablefooter[$i][0]['trbgcolor'] = $table['bgcolor'][$i];
25758 for( $j = $startcol ; $j < $numcols ; $j++
) { //Columns
25759 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25760 if ($this->cacheTables
) {
25761 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25764 $cell = &$cells[$i][$j];
25766 if ($table['colPg'][$j] != $splitpg) { continue; }
25767 list($x,$w) = $this->_splitTableGetWidth($table, $i, $j, $fh);
25768 $js = $j - $startcol;
25771 list($x,$w) = $this->_tableGetWidth($table, $i, $j, $fh);
25775 list($y,$h) = $this->_tableGetHeight($table, $i, $j, $fh);
25778 //Get info of tfoot ==>> table footer
25779 $tablefooter[$i][$js]['x'] = $x;
25780 $tablefooter[$i][$js]['y'] = $y;
25781 $tablefooter[$i][$js]['h'] = $h;
25782 $tablefooter[$i][$js]['w'] = $w;
25783 if (isset($cell['textbuffer'])) { $tablefooter
[$i
][$js
]['textbuffer'] = $cell
['textbuffer']; }
25784 else { $tablefooter
[$i
][$js
]['textbuffer'] = ''; }
25785 $tablefooter[$i][$js]['a'] = $cell['a'];
25786 $tablefooter[$i][$js]['R'] = $cell['R'];
25787 $tablefooter[$i][$js]['va'] = $cell['va'];
25788 $tablefooter[$i][$js]['mih'] = $cell['mih'];
25789 $tablefooter[$i][$js]['gradient'] = $cell['gradient']; // *BACKGROUNDS*
25790 $tablefooter[$i][$js]['background-image'] = $cell['background-image']; // *BACKGROUNDS*
25791 //CELL FILL BGCOLOR
25792 if (!$this->simpleTables
){
25793 if ($this->packTableData
) {
25794 $c = $this->_unpackCellBorder($cell['borderbin']);
25795 $tablefooter[$i][$js]['border'] = $c['border'];
25796 $tablefooter[$i][$js]['border_details'] = $c['border_details'];
25799 $tablefooter[$i][$js]['border'] = $cell['border'];
25800 $tablefooter[$i][$js]['border_details'] = $cell['border_details'];
25803 else if ($this->simpleTables
){
25804 $tablefooter[$i][$js]['border'] = $table['simple']['border'];
25805 $tablefooter[$i][$js]['border_details'] = $table['simple']['border_details'];
25807 $tablefooter[$i][$js]['bgcolor'] = $cell['bgcolor'];
25808 $tablefooter[$i][$js]['padding'] = $cell['padding'];
25809 $tablefooter[$i][$js]['rowspan'] = $cell['rowspan'];
25810 $tablefooter[$i][$js]['colspan'] = $cell['colspan'];
25816 if ($level==1) { $this
->_out('___TABLE___BACKGROUNDS'.date('jY')); }
25817 $tableheaderadj = 0;
25818 $tablefooteradj = 0;
25820 $tablestartpageno = $this->page
;
25822 //Draw Table Contents and Borders
25823 for( $i = 0; $i < $numrows ; $i++
) { //Rows
25824 if ($split && $startrow > 0) {
25825 $thnr = (isset($table['is_thead']) ? count($table['is_thead']) : 0);
25826 if ($i >= $thnr && $i < $startrow) { continue; }
25827 if ($i == $startrow){ $returny
= $rety
- $tableheaderrowheight
; }
25830 // Get Maximum row/cell height in row - including rowspan>1 + 1 overlapping
25831 $maxrowheight = $this->_tableGetMaxRowHeight($table, $i, $fh);
25834 $newpagestarted = false;
25835 for( $j = $startcol ; $j < $numcols ; $j++
) { //Columns
25837 if ($table['colPg'][$j] > $splitpg) { break; }
25840 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25841 if ($this->cacheTables
) {
25842 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25845 $cell = &$cells[$i][$j];
25847 $lastCol = $j +
(isset($cell['colspan']) ? ($cell['colspan']-1) : 0) ;
25848 list($x,$w) = $this->_splitTableGetWidth($table, $i, $j, $fh);
25850 else {
list($x
,$w
) = $this
->_tableGetWidth($table
, $i
, $j
, $fh
); }
25852 list($y,$h) = $this->_tableGetHeight($table, $i, $j, $fh);
25857 if ($table['borders_separate']) {
25858 if (!empty($tablefooter) || $i == ($numrows-1) || (isset($cell['rowspan']) && ($i+
$cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i+
1) == $numrows) ) {
25859 $extra = $table['padding']['B'] +
$table['border_details']['B']['w'] +
$table['border_spacing_V']/2;
25860 //$extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
25863 $extra = $table['border_spacing_V']/2;
25866 else { $extra
= $table
['max_cell_border_width']['B']/2; }
25868 if ($j==$startcol && ((($y +
$maxrowheight +
$extra ) > ($pagetrigger+
0.001)) || (($this->keepColumns
|| !$this->ColActive
) && !empty($tablefooter) && ($y +
$maxrowheight +
$tablefooterrowheight +
$extra) > $pagetrigger) && ($this->tableLevel
==1 && $i < ($numrows - $table['headernrows']))) && ($y0 >0 || $x0 > 0) && !$this->InFooter
&& $this->autoPageBreak
) {
25871 $finalSpread = true;
25872 $firstSpread = true;
25874 for($t=$startcol; $t<$numcols; $t++
) {
25875 // Are there more columns to print on a next page?
25876 if ($table['colPg'][$t] > $splitpg) {
25877 $finalSpread = false;
25881 if ($startcol>0) { $firstSpread
= false; }
25884 if (($this->keepColumns
|| !$this->ColActive
) && !empty($tablefooter) && $i > 0 ) {
25887 $this->TableHeaderFooter($tablefooter,$tablestartpage,$tablestartcolumn,'F',$level, $firstSpread, $finalSpread);
25888 if ($this->table_rotate
) {
25889 $this->tbrot_h +
= $this->y
- $ya ;
25891 $tablefooteradj = $this->y
- $ya ;
25896 $oldcolumn = $this->CurrCol
;
25897 if ($this->AcceptPageBreak()) {
25898 $newpagestarted = true;
25899 $this->y
= $y +
$y0;
25901 // Move down to account for border-spacing or
25902 // extra half border width in case page breaks in middle
25903 if($i>0 && !$this->table_rotate
&& $level==1 && !$this->ColActive
) {
25904 if ($table['borders_separate']) {
25905 $adv = $table['border_spacing_V']/2;
25907 if (($this->keepColumns
|| !$this->ColActive
) && !empty($tablefooter) && $i > 0 ) {
25908 $adv +
= ($table['padding']['B'] +
$table['border_details']['B']['w']);
25914 if (!$this->simpleTables
){
25915 if (!empty($tablefooter)) { $maxbwbottom
= $table
['max_cell_border_width']['B']; }
25918 for( $ctj = 0 ; $ctj < $numcols ; $ctj++
) {
25919 if (isset($cells[$brow][$ctj]) && $cells[$brow][$ctj]) {
25920 if ($this->cacheTables
) {
25921 $cadj = $this->_uncacheCell($table['cells'][$brow][$ctj], '', $fh);
25922 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cadj['borderbin']);
25924 else if ($this->packTableData
) {
25925 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$brow][$ctj]['borderbin']);
25928 $bb = $cells[$brow][$ctj]['border_details']['B']['w'];
25930 $maxbwbottom = max($maxbwbottom , $bb);
25934 if (!empty($tableheader)) { $maxbwtop
= $table
['max_cell_border_width']['T']; }
25937 for( $ctj = 0 ; $ctj < $numcols ; $ctj++
) {
25938 if (isset($cells[$trow][$ctj]) && $cells[$trow][$ctj]) {
25939 if ($this->cacheTables
) {
25940 $cadj = $this->_uncacheCell($table['cells'][$trow][$ctj], '', $fh);
25941 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cadj['borderbin']);
25943 else if ($this->packTableData
) {
25944 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$trow][$ctj]['borderbin']);
25947 $bt = $cells[$trow][$ctj]['border_details']['T']['w'];
25949 $maxbwtop = max($maxbwtop , $bt);
25954 else if ($this->simpleTables
){
25955 $maxbwtop = $table['simple']['border_details']['T']['w'];
25956 $maxbwbottom = $table['simple']['border_details']['B']['w'];
25958 $adv = $maxbwbottom /2;
25963 // Rotated table split over pages - needs this->y for borders/backgrounds
25964 if($i>0 && $this->table_rotate
&& $level==1) {
25965 // $this->y = $y0 + $this->tbrot_w;
25968 if ($this->tableClipPath
) { $this
->_out("Q"); }
25973 if ($table['borders_separate']) {
25974 $bx -= ($table['padding']['L'] +
$table['border_details']['L']['w'] +
$table['border_spacing_H']/2);
25975 if ($tablestartpageno != $this->page
) { // IF already broken across a previous pagebreak
25976 $by +
= $table['max_cell_border_width']['T']/2;
25977 if (empty($tableheader)) { $by
-= ($table
['border_spacing_V']/2); }
25980 $by -= ($table['padding']['T'] +
$table['border_details']['T']['w'] +
$table['border_spacing_V']/2);
25984 else if ($tablestartpageno != $this->page
&& !empty($tableheader)) { $by +
= $maxbwtop
/2; }
25986 $by -= $tableheaderadj;
25987 $bh = $this->y
- $by +
$tablefooteradj;
25988 if (!$table['borders_separate']) { $bh
-= $adv
; }
25991 for($t=$startcol; $t<$numcols; $t++
) {
25992 if ($table['colPg'][$t] == $splitpg) { $bw +
= $table
['wc'][$t
]; }
25993 if ($table['colPg'][$t] > $splitpg) { break; }
25995 if ($table['borders_separate']) {
25996 if ($firstSpread) {
25997 $bw +
= $table['padding']['L'] +
$table['border_details']['L']['w'] +
$table['border_spacing_H'];
26000 $bx +
= ($table['padding']['L'] +
$table['border_details']['L']['w']);
26001 $bw +
= $table['border_spacing_H'];
26003 if ($finalSpread) {
26004 $bw +
= $table['padding']['R'] +
$table['border_details']['R']['w']/2 +
$table['border_spacing_H'];
26009 $bw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26013 if ($this->splitTableBorderWidth
&& ($this->keepColumns
|| !$this->ColActive
) && empty($tablefooter) && $i > 0 && $table['border_details']['B']['w']) {
26014 $prevDrawColor = $this->DrawColor
;
26015 $lw = $this->LineWidth
;
26016 $this->SetLineWidth($this->splitTableBorderWidth
);
26017 $this->SetDColor($table['border_details']['B']['c']);
26018 $this->SetLineJoin(0);
26019 $this->SetLineCap(0);
26022 if (!$table['borders_separate']) {
26023 $blx -= ($table['max_cell_border_width']['L']/2);
26024 $blw +
= ($table['max_cell_border_width']['L']/2 +
$table['max_cell_border_width']['R']/2);
26026 $this->Line($blx,$this->y+
($this->splitTableBorderWidth
/2),$blx+
$blw,$this->y+
($this->splitTableBorderWidth
/2));
26027 $this->DrawColor
= $prevDrawColor;
26028 $this->_out($this->DrawColor
);
26029 $this->SetLineWidth($lw);
26030 $this->SetLineJoin(2);
26031 $this->SetLineCap(2);
26034 if (!$this->ColActive
&& ($i > 0 || $j > 0)) {
26035 if (isset($table['bgcolor'][-1])) {
26036 $color = $this->ConvertColor($table['bgcolor'][-1]);
26038 if (!$table['borders_separate']) { $bh
-= $table
['max_cell_border_width']['B']/2; }
26039 $this->tableBackgrounds
[$level*9][] = array('gradient'=>false, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'col'=>$color);
26043 /*-- BACKGROUNDS --*/
26044 if (isset($table['gradient'])) {
26045 $g = $this->grad
->parseBackgroundGradient($table['gradient']);
26047 $this->tableBackgrounds
[$level*9+
1][] = array('gradient'=>true, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26051 if (isset($table['background-image'])) {
26052 if ($table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['background-image']['gradient'] )) {
26053 $g = $this->grad
->parseMozGradient( $table['background-image']['gradient'] );
26055 $this->tableBackgrounds
[$level*9+
1][] = array('gradient'=>true, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26059 $image_id = $table['background-image']['image_id'];
26060 $orig_w = $table['background-image']['orig_w'];
26061 $orig_h = $table['background-image']['orig_h'];
26062 $x_pos = $table['background-image']['x_pos'];
26063 $y_pos = $table['background-image']['y_pos'];
26064 $x_repeat = $table['background-image']['x_repeat'];
26065 $y_repeat = $table['background-image']['y_repeat'];
26066 $resize = $table['background-image']['resize'];
26067 $opacity = $table['background-image']['opacity'];
26068 $itype = $table['background-image']['itype'];
26069 $this->tableBackgrounds
[$level*9+
2][] = array('x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>'', 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
26072 /*-- END BACKGROUNDS --*/
26075 // $this->AcceptPageBreak() has moved tablebuffer to $this->pages content
26076 if ($this->tableBackgrounds
) {
26077 $s = $this->PrintTableBackgrounds();
26078 if ($this->bufferoutput
) {
26079 $this->headerbuffer
= preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->headerbuffer
);
26080 $this->headerbuffer
= preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this->headerbuffer
);
26083 $this->pages
[$this->page
] = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages
[$this->page
]);
26084 $this->pages
[$this->page
] = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this->pages
[$this->page
]);
26086 $this->tableBackgrounds
= array();
26090 if ($i == 0 && $j == 0) { $y0
= -1; }
26091 else if ($finalSpread) {
26101 return array(false, $startrow, $startcol, $splitpg, $returny, $y0);
26104 $this->AddPage($this->CurOrientation
);
26106 $this->_out('___TABLE___BACKGROUNDS'.date('jY'));
26109 if ($this->tableClipPath
) { $this
->_out($this
->tableClipPath
); }
26111 // Added to correct for OddEven Margins
26112 $x= $x +
$this->MarginCorrection
;
26113 $x0= $x0 +
$this->MarginCorrection
;
26116 if ($this->splitTableBorderWidth
&& ($this->keepColumns
|| !$this->ColActive
) && empty($tableheader) && $i > 0 && $table['border_details']['T']['w'] ) {
26117 $prevDrawColor = $this->DrawColor
;
26118 $lw = $this->LineWidth
;
26119 $this->SetLineWidth($this->splitTableBorderWidth
);
26120 $this->SetDColor($table['border_details']['T']['c']);
26121 $this->SetLineJoin(0);
26122 $this->SetLineCap(0);
26123 $blx +
= $this->MarginCorrection
;
26124 $this->Line($blx,$this->y
-($this->splitTableBorderWidth
/2),$blx+
$blw,$this->y
-($this->splitTableBorderWidth
/2));
26125 $this->DrawColor
= $prevDrawColor;
26126 $this->_out($this->DrawColor
);
26127 $this->SetLineWidth($lw);
26128 $this->SetLineJoin(2);
26129 $this->SetLineCap(2);
26132 // Move down to account for half of top border-spacing or
26133 // extra half border width in case page was broken in middle
26134 if($i>0 && !$this->table_rotate
&& $level==1 && $table['headernrows']==0) {
26135 if ($table['borders_separate']) { $adv
= $table
['border_spacing_V']/2; }
26138 for( $ctj = 0 ; $ctj < $numcols ; $ctj++
) {
26139 if (isset($cells[$i][$ctj]) && $cells[$i][$ctj]) {
26140 if (!$this->simpleTables
){
26141 if ($this->cacheTables
) {
26142 $celltj = $this->_uncacheCell($table['cells'][$i][$ctj], '', $fh);
26143 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($celltj['borderbin']);
26145 else if ($this->packTableData
) {
26146 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$i][$ctj]['borderbin']);
26149 $bt = $cells[$i][$ctj]['border_details']['T']['w'];
26151 $maxbwtop = max($maxbwtop, $bt);
26153 else if ($this->simpleTables
){
26154 $maxbwtop = max($maxbwtop, $table['simple']['border_details']['T']['w']);
26158 $adv = $maxbwtop /2;
26164 if ($this->table_rotate
) {
26165 $this->tbrot_x0
= $this->lMargin +
$this->blk
[$this->blklvl
]['outer_left_margin'] +
$this->blk
[$this->blklvl
]['padding_left'] +
$this->blk
[$this->blklvl
]['border_left']['w'];
26166 if ($table['borders_separate']) { $this
->tbrot_h
= $table
['margin']['T'] + $table
['padding']['T'] + $table
['border_details']['T']['w'] + $table
['border_spacing_V']/2; }
26167 else { $this
->tbrot_h
= $table
['margin']['T'] + $table
['max_cell_border_width']['T'] ; }
26168 $this->tbrot_y0
= $this->y
;
26169 $pagetrigger = $y0 - $tableheaderadj +
($this->blk
[$this->blklvl
]['inner_width']);
26172 $pagetrigger = $this->PageBreakTrigger
;
26175 if ($this->kwt_saved
&& $level==1) {
26176 $this->kwt_moved
= true;
26180 // Disable Table header repeat if Keep Block together
26181 if (!$this->keep_block_together
&& !empty($tableheader)) {
26183 $this->TableHeaderFooter($tableheader,$tablestartpage,$tablestartcolumn,'H',$level);
26184 if ($this->table_rotate
) {
26185 $this->tbrot_h
= $this->y
- $ya ;
26187 $tableheaderadj = $this->y
- $ya ;
26190 else if ($i==0 && !$this->keep_block_together
&& !$this->table_rotate
&& $level==1 && !$this->ColActive
) {
26191 // Advance down page
26192 if ($table['borders_separate']) { $adv
= $table
['border_spacing_V']/2 + $table
['border_details']['T']['w'] + $table
['padding']['T']; }
26193 else { $adv
= $table
['max_cell_border_width']['T'] /2 ; }
26195 if ($this->table_rotate
) {
26196 $this->y +
= ($adv);
26199 $this->DivLn($adv,$this->blklvl
,true);
26205 $y = $y0 = $this->y
;
26211 if ($this->CurrCol
!= $oldcolumn) {
26212 // Added to correct for Columns
26213 $x +
= $this->ChangeColumn
* ($this->ColWidth+
$this->ColGap
);
26214 $x0 +
= $this->ChangeColumn
* ($this->ColWidth+
$this->ColGap
);
26215 if ($this->CurrCol
== 0) { // just added a page - possibly with tableheader
26216 $y0 = $this->y
; // this->y0 is global used by Columns - $y0 is internal to tablewrite
26219 $y0 = $this->y0
; // this->y0 is global used by Columns - $y0 is internal to tablewrite
26223 if ($this->CurrCol
!= 0 && ($this->keepColumns
&& $this->ColActive
) && !empty($tableheader) && $i > 0 ) {
26226 $this->TableHeaderFooter($tableheader,$tablestartpage,$tablestartcolumn,'H',$level);
26230 /*-- END COLUMNS --*/
26238 if ($this->kwt_saved
&& $level==1) {
26239 $this->printkwtbuffer();
26240 $x0 = $x = $this->x
;
26241 $y0 = $y = $this->y
;
26242 $this->kwt_moved
= false;
26243 $this->kwt_saved
= false;
26247 // Set the Page & Column where table actually starts
26248 if ($i==0 && $j==0 && $level==1) {
26249 if (($this->mirrorMargins
) && (($this->page
)%
2==0)) { // EVEN
26250 $tablestartpage = 'EVEN';
26252 else if (($this->mirrorMargins
) && (($this->page
)%
2==1)) { // ODD
26253 $tablestartpage = 'ODD';
26255 else { $tablestartpage
= ''; }
26256 $tablestartpageno = $this->page
;
26257 if ($this->ColActive
) { $tablestartcolumn
= $this
->CurrCol
; } // *COLUMNS*
26262 $align = $cell['a'];
26266 // If outside columns, this is done in PaintDivBB
26267 if ($this->ColActive
) {
26268 //OUTER FILL BGCOLOR of DIVS
26269 if ($this->blklvl
> 0 && ($j==0) && !$this->table_rotate
&& $level==1) {
26270 $firstblockfill = $this->GetFirstBlockFill();
26271 if ($firstblockfill && $this->blklvl
>= $firstblockfill) {
26272 $divh = $maxrowheight;
26274 if ((!isset($cell['rowspan']) && $i == $numrows-1) || (isset($cell['rowspan']) && (($i == $numrows-1 && $cell['rowspan']<2) || ($cell['rowspan']>1 && ($i +
$cell['rowspan']-1) == $numrows-1)))) { // mPDF 5.6.54
26275 if ($table['borders_separate']) {
26276 $adv = $table['margin']['B'] +
$table['padding']['B'] +
$table['border_details']['B']['w'] +
$table['border_spacing_V']/2;
26279 $adv = $table['margin']['B'] +
$table['max_cell_border_width']['B']/2;
26281 $divh +
= $adv; //last row: fill bottom half of bottom border (y advanced at end)
26284 if (($this->y +
$divh) > $outerfilled ) { // if not already painted by previous rowspan
26287 if ($outerfilled > $this->y
) {
26288 $divh = ($this->y +
$divh) - $outerfilled;
26289 $this->y
= $outerfilled;
26292 $this->DivLn($divh,-3,false);
26293 $outerfilled = $this->y +
$divh;
26294 // Reset current block fill
26295 $bcor = $this->blk
[$this->blklvl
]['bgcolorarray'];
26296 if ($bcor ) $this->SetFColor($bcor);
26305 //TABLE BACKGROUND FILL BGCOLOR - for cellSpacing
26306 if ($this->ColActive
) {
26307 if ($table['borders_separate']) {
26308 $fill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
26310 $color = $this->ConvertColor($fill);
26312 $xadj = ($table['border_spacing_H']/2);
26313 $yadj = ($table['border_spacing_V']/2);
26314 $wadj = $table['border_spacing_H'];
26315 $hadj = $table['border_spacing_V'];
26316 if ($i == 0) { // Top
26317 $yadj +
= $table['padding']['T'] +
$table['border_details']['T']['w'] ;
26318 $hadj +
= $table['padding']['T'] +
$table['border_details']['T']['w'] ;
26320 if ($j == 0) { // Left
26321 $xadj +
= $table['padding']['L'] +
$table['border_details']['L']['w'] ;
26322 $wadj +
= $table['padding']['L'] +
$table['border_details']['L']['w'] ;
26324 if ($i == ($numrows-1) || (isset($cell['rowspan']) && ($i+
$cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i+
1) == $numrows)) { // Bottom
26325 $hadj +
= $table['padding']['B'] +
$table['border_details']['B']['w'] ;
26327 if ($j == ($numcols-1) || (isset($cell['colspan']) && ($j+
$cell['colspan']) == $numcols) || (!isset($cell['colspan']) && ($j+
1) == $numcols)) { // Right
26328 $wadj +
= $table['padding']['R'] +
$table['border_details']['R']['w'] ;
26330 $this->SetFColor($color);
26331 $this->Rect($x - $xadj, $y - $yadj, $w +
$wadj, $h +
$hadj, 'F');
26336 /*-- END COLUMNS --*/
26338 if ($table['empty_cells']!='hide' || !empty($cell['textbuffer']) || (isset($cell['nestedcontent']) && $cell['nestedcontent']) || !$table['borders_separate'] ) { $paintcell
= true; }
26339 else { $paintcell
= false; }
26343 $bord_det = array();
26345 if (!$this->simpleTables
){
26346 if ($this->packTableData
) {
26347 if ($cell['borderbin']) {
26348 $c = $this->_unpackCellBorder($cell['borderbin']);
26349 $bord = $c['border'];
26350 $bord_det = $c['border_details'];
26353 else if ($cell['border']) {
26354 $bord = $cell['border'];
26355 $bord_det = $cell['border_details'];
26358 else if ($this->simpleTables
){
26359 if ($table['simple']['border']) {
26360 $bord = $table['simple']['border'];
26361 $bord_det = $table['simple']['border_details'];
26365 //TABLE ROW OR CELL FILL BGCOLOR
26367 if (isset($cell['bgcolor']) && $cell['bgcolor'] && $cell['bgcolor']!='transparent') {
26368 $fill = $cell['bgcolor'];
26371 else if (isset($table['bgcolor'][$i]) && $table['bgcolor'][$i] && $table['bgcolor'][$i]!='transparent') { // Row color
26372 $fill = $table['bgcolor'][$i];
26375 if ($fill && $paintcell) {
26376 $color = $this->ConvertColor($fill);
26378 if ($table['borders_separate']) {
26379 if ($this->ColActive
) {
26380 $this->SetFColor($color);
26381 $this->Rect($x+
($table['border_spacing_H']/2), $y+
($table['border_spacing_V']/2), $w- $table['border_spacing_H'], $h- $table['border_spacing_V'], 'F');
26384 $this->tableBackgrounds
[$level*9+
$leveladj][] = array('gradient'=>false, 'x'=>($x +
($table['border_spacing_H']/2)), 'y'=>($y +
($table['border_spacing_V']/2)), 'w'=>($w - $table['border_spacing_H']), 'h'=>($h - $table['border_spacing_V']), 'col'=>$color);
26388 if ($this->ColActive
) {
26389 $this->SetFColor($color);
26390 $this->Rect($x, $y, $w, $h, 'F');
26393 $this->tableBackgrounds
[$level*9+
$leveladj][] = array('gradient'=>false, 'x'=>$x, 'y'=>$y, 'w'=>$w, 'h'=>$h, 'col'=>$color);
26399 /*-- BACKGROUNDS --*/
26400 if (isset($cell['gradient']) && $cell['gradient'] && $paintcell){
26401 $g = $this->grad
->parseBackgroundGradient($cell['gradient']);
26403 if ($table['borders_separate']) {
26404 $px = $x+
($table['border_spacing_H']/2);
26405 $py = $y+
($table['border_spacing_V']/2);
26406 $pw = $w- $table['border_spacing_H'];
26407 $ph = $h- $table['border_spacing_V'];
26415 if ($this->ColActive
) {
26416 $this->grad
->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
26419 $this->tableBackgrounds
[$level*9+
7][] = array('gradient'=>true, 'x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26424 if (isset($cell['background-image']) && $paintcell) {
26425 if ($cell['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $cell['background-image']['gradient'] )) {
26426 $g = $this->grad
->parseMozGradient( $cell['background-image']['gradient'] );
26428 if ($table['borders_separate']) {
26429 $px = $x+
($table['border_spacing_H']/2);
26430 $py = $y+
($table['border_spacing_V']/2);
26431 $pw = $w- $table['border_spacing_H'];
26432 $ph = $h- $table['border_spacing_V'];
26440 if ($this->ColActive
) {
26441 $this->grad
->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
26444 $this->tableBackgrounds
[$level*9+
7][] = array('gradient'=>true, 'x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26448 else if ($cell['background-image']['image_id']) { // Background pattern
26449 $n = count($this->patterns
)+
1;
26450 if ($table['borders_separate']) {
26451 $px = $x+
($table['border_spacing_H']/2);
26452 $py = $y+
($table['border_spacing_V']/2);
26453 $pw = $w- $table['border_spacing_H'];
26454 $ph = $h- $table['border_spacing_V'];
26462 if ($this->ColActive
) {
26463 list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($cell['background-image']['orig_w'], $cell['background-image']['orig_h'], $pw, $ph, $cell['background-image']['resize'], $cell['background-image']['x_repeat'], $cell['background-image']['y_repeat']);
26464 $this->patterns
[$n] = array('x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'pgh'=>$this->h
, 'image_id'=>$cell['background-image']['image_id'], 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$cell['background-image']['x_pos'] , 'y_pos'=>$cell['background-image']['y_pos'] , 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat);
26465 if ($cell['background-image']['opacity']>0 && $cell['background-image']['opacity']<1) { $opac
= $this
->SetAlpha($cell
['background-image']['opacity'],'Normal',true); }
26466 else { $opac
= ''; }
26467 $this->_out(sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $px*_MPDFK
, ($this->h
-$py)*_MPDFK
, $pw*_MPDFK
, -$ph*_MPDFK
));
26470 $image_id = $cell['background-image']['image_id'];
26471 $orig_w = $cell['background-image']['orig_w'];
26472 $orig_h = $cell['background-image']['orig_h'];
26473 $x_pos = $cell['background-image']['x_pos'];
26474 $y_pos = $cell['background-image']['y_pos'];
26475 $x_repeat = $cell['background-image']['x_repeat'];
26476 $y_repeat = $cell['background-image']['y_repeat'];
26477 $resize = $cell['background-image']['resize'];
26478 $opacity = $cell['background-image']['opacity'];
26479 $itype = $cell['background-image']['itype'];
26480 $this->tableBackgrounds
[$level*9+
8][] = array('x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>'', 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
26484 /*-- END BACKGROUNDS --*/
26486 if (isset($cell['colspan']) && $cell['colspan']>1) { $ccolsp
= $cell
['colspan']; }
26487 else { $ccolsp
= 1; }
26488 if (isset($cell['rowspan']) && $cell['rowspan']>1) { $crowsp
= $cell
['rowspan']; }
26489 else { $crowsp
= 1; }
26492 // but still need to do this for repeated headers...
26493 if (!$table['borders_separate'] && $this->tabletheadjustfinished
&& !$this->simpleTables
){
26494 if (isset($table['topntail']) && $table['topntail']) {
26495 $bord_det['T'] = $this->border_details($table['topntail']);
26496 $bord_det['T']['w'] /= $this->shrin_k
;
26497 $this->setBorder($bord, _BORDER_TOP
);
26499 if (isset($table['thead-underline']) && $table['thead-underline']) {
26500 $bord_det['T'] = $this->border_details($table['thead-underline']);
26501 $bord_det['T']['w'] /= $this->shrin_k
;
26502 $this->setBorder($bord, _BORDER_TOP
);
26507 //Get info of first row ==>> table header
26508 //Use > 1 row if THEAD
26509 if (isset($table['is_thead'][$i]) && $table['is_thead'][$i] && $level==1) {
26510 if ($j==0) $tableheaderrowheight +
= $table['hr'][$i];
26511 $tableheader[$i][0]['trbackground-images'] = (isset($table['trbackground-images'][$i]) ? $table['trbackground-images'][$i] : null);
26512 $tableheader[$i][0]['trgradients'] = (isset($table['trgradients'][$i]) ? $table['trgradients'][$i] : null);
26513 $tableheader[$i][0]['trbgcolor'] = (isset($table['bgcolor'][$i]) ? $table['bgcolor'][$i] : null);
26514 $tableheader[$i][$j]['x'] = $x;
26515 $tableheader[$i][$j]['y'] = $y;
26516 $tableheader[$i][$j]['h'] = $h;
26517 $tableheader[$i][$j]['w'] = $w;
26518 if (isset($cell['textbuffer'])) { $tableheader
[$i
][$j
]['textbuffer'] = $cell
['textbuffer']; }
26519 else { $tableheader
[$i
][$j
]['textbuffer'] = ''; }
26520 $tableheader[$i][$j]['a'] = $cell['a'];
26521 $tableheader[$i][$j]['R'] = $cell['R'];
26523 $tableheader[$i][$j]['va'] = $cell['va'];
26524 $tableheader[$i][$j]['mih'] = $cell['mih'];
26525 $tableheader[$i][$j]['gradient'] = (isset($cell['gradient']) ? $cell['gradient'] : null); // *BACKGROUNDS*
26526 $tableheader[$i][$j]['background-image'] = (isset($cell['background-image']) ? $cell['background-image'] : null); // *BACKGROUNDS*
26527 $tableheader[$i][$j]['rowspan'] = (isset($cell['rowspan']) ? $cell['rowspan'] : null);
26528 $tableheader[$i][$j]['colspan'] = (isset($cell['colspan']) ? $cell['colspan'] : null);
26529 $tableheader[$i][$j]['bgcolor'] = $cell['bgcolor'];
26531 if (!$this->simpleTables
){
26532 $tableheader[$i][$j]['border'] = $bord;
26533 $tableheader[$i][$j]['border_details'] = $bord_det;
26535 else if ($this->simpleTables
){
26536 $tableheader[$i][$j]['border'] = $table['simple']['border'];
26537 $tableheader[$i][$j]['border_details'] = $table['simple']['border_details'];
26539 $tableheader[$i][$j]['padding'] = $cell['padding'];
26543 if ($bord || $bord_det) {
26544 if ($table['borders_separate'] && $paintcell) {
26545 $this->_tableRect($x +
($table['border_spacing_H']/2)+
($bord_det['L']['w'] /2), $y+
($table['border_spacing_V']/2)+
($bord_det['T']['w'] /2), $w-$table['border_spacing_H']-($bord_det['L']['w'] /2)-($bord_det['R']['w'] /2), $h- $table['border_spacing_V']-($bord_det['T']['w'] /2)-($bord_det['B']['w']/2), $bord, $bord_det, false, $table['borders_separate']);
26547 else if (!$table['borders_separate']) {
26548 $this->_tableRect($x, $y, $w, $h, $bord, $bord_det, true, $table['borders_separate']); // true causes buffer
26554 if ($cell['R'] && INTVAL($cell['R']) > 0 && INTVAL($cell['R']) < 90 && isset($cell['va']) && $cell['va']!='B') { $cell
['va']='B';}
26555 if (!isset($cell['va']) || $cell['va']=='M') $this->y +
= ($h-$cell['mih'])/2;
26556 elseif (isset($cell['va']) && $cell['va']=='B') $this->y +
= $h-$cell['mih'];
26560 // TEXT (and nested tables)
26561 $this->divalign
=$align;
26563 $this->divwidth
=$w;
26564 if (!empty($cell['textbuffer'])) {
26566 if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i]) {
26567 if (preg_match('/{colsum([0-9]*)[_]*}/', $cell['textbuffer'][0][0], $m)) {
26568 $rep = sprintf("%01.".intval($m[1])."f", $this->colsums
[$j]);
26569 $cell['textbuffer'][0][0] = preg_replace('/{colsum[0-9_]*}/', $rep ,$cell['textbuffer'][0][0]);
26572 else if (!isset($table['is_thead'][$i])) { $this
->colsums
[$j
] +
= floatval(preg_replace('/^[^0-9\.\,]*/','',$cell
['textbuffer'][0][0])); } // mPDF 5.6.66
26576 if ($this->iterationCounter
) {
26577 foreach($cell['textbuffer'] AS $k=>$t) {
26578 if (preg_match('/{iteration ([a-zA-Z0-9_]+)}/',$t[0], $m)) {
26579 $vname = '__'.$m[1].'_';
26580 if (!isset($this->$vname)) { $this
->$vname
= 1; }
26581 else { $this
->$vname++
; }
26582 $cell['textbuffer'][$k][0] = preg_replace('/{iteration '.$m[1].'}/', $this->$vname, $cell['textbuffer'][$k][0]);
26589 $cellPtSize = $cell['textbuffer'][0][11] / $this->shrin_k
;
26590 if (!$cellPtSize) { $cellPtSize
= $this
->default_font_size
; }
26591 $cellFontHeight = ($cellPtSize/_MPDFK
);
26593 $angle = INTVAL($cell['R']);
26594 // Only allow 45 to 89 degrees (when bottom-aligned) or exactly 90 or -90
26595 if ($angle > 90) { $angle
= 90; }
26596 else if ($angle > 0 && $angle <45) { $angle
= 45; }
26597 else if ($angle < 0) { $angle
= -90; }
26598 $offset = ((sin(deg2rad($angle))) * 0.37 * $cellFontHeight);
26599 if (isset($cell['a']) && $cell['a']=='R') {
26600 $this->x +
= ($w) +
($offset) - ($cellFontHeight/3) - ($cell['padding']['R'] +
($table['border_spacing_H']/2));
26602 else if (!isset($cell['a']) || $cell['a']=='C') {
26603 $this->x +
= ($w/2) +
($offset);
26606 $this->x +
= ($offset) +
($cellFontHeight/3)+
($cell['padding']['L'] +
($table['border_spacing_H']/2));
26609 foreach($cell['textbuffer'] AS $t) { $str
.= $t
[0].' '; }
26611 if (!isset($cell['va']) || $cell['va']=='M') {
26612 $this->y
-= ($h-$cell['mih'])/2; //Undo what was added earlier VERTICAL ALIGN
26613 if ($angle > 0) { $this
->y +
= (($h
-$cell
['mih'])/2) + $cell
['padding']['T'] +
($cell
['mih']-($cell
['padding']['T'] + $cell
['padding']['B'])); }
26614 else if ($angle < 0) { $this
->y +
= (($h
-$cell
['mih'])/2)+
($cell
['padding']['T'] +
($table
['border_spacing_V']/2)); }
26616 elseif (isset($cell['va']) && $cell['va']=='B') {
26617 $this->y
-= $h-$cell['mih']; //Undo what was added earlier VERTICAL ALIGN
26618 if ($angle > 0) { $this
->y +
= $h
-($cell
['padding']['B'] +
($table
['border_spacing_V']/2)); }
26619 else if ($angle < 0) { $this
->y +
= $h
-$cell
['mih'] +
($cell
['padding']['T'] +
($table
['border_spacing_V']/2)); }
26621 elseif (isset($cell['va']) && $cell['va']=='T') {
26622 if ($angle > 0) { $this
->y +
= $cell
['mih']-($cell
['padding']['B'] +
($table
['border_spacing_V']/2)); }
26623 else if ($angle < 0) { $this
->y +
= ($cell
['padding']['T'] +
($table
['border_spacing_V']/2)); }
26625 $this->Rotate($angle,$this->x
,$this->y
);
26626 $s_fs = $this->FontSizePt
;
26627 $s_f = $this->FontFamily
;
26628 $s_st = $this->FontStyle
;
26629 if (!empty($cell['textbuffer'][0][3])) { //Font Color
26630 $cor = $cell['textbuffer'][0][3];
26631 $this->SetTColor($cor);
26633 $s_str = $this->strike
;
26634 $this->strike
= $cell['textbuffer'][0][8]; //Strikethrough
26635 $this->SetFont($cell['textbuffer'][0][4],$cell['textbuffer'][0][2],$cellPtSize,true,true);
26636 $this->Text($this->x
,$this->y
,$str);
26638 $this->SetFont($s_f,$s_st,$s_fs,true,true);
26639 $this->SetTColor(0);
26640 $this->strike
= $s_str;
26645 if (!$this->simpleTables
){
26647 $btlw = $bord_det['L']['w'];
26648 $btrw = $bord_det['R']['w'];
26649 $bttw = $bord_det['T']['w'];
26656 if ($table['borders_separate']) {
26657 $xadj = $btlw +
$cell['padding']['L'] +
($table['border_spacing_H']/2);
26658 $wadj = $btlw +
$btrw +
$cell['padding']['L'] +
$cell['padding']['R'] +
$table['border_spacing_H'];
26659 $yadj = $bttw +
$cell['padding']['T'] +
($table['border_spacing_H']/2);
26662 $xadj = $btlw/2 +
$cell['padding']['L'];
26663 $wadj = ($btlw +
$btrw)/2 +
$cell['padding']['L'] +
$cell['padding']['R'];
26664 $yadj = $bttw/2 +
$cell['padding']['T'];
26667 else if ($this->simpleTables
){
26668 if ($table['borders_separate']) { // NB twice border width
26669 $xadj = $table['simple']['border_details']['L']['w'] +
$cell['padding']['L'] +
($table['border_spacing_H']/2);
26670 $wadj = $table['simple']['border_details']['L']['w'] +
$table['simple']['border_details']['R']['w'] +
$cell['padding']['L'] +
$cell['padding']['R'] +
$table['border_spacing_H'];
26671 $yadj = $table['simple']['border_details']['T']['w'] +
$cell['padding']['T'] +
($table['border_spacing_H']/2);
26674 $xadj = $table['simple']['border_details']['L']['w']/2 +
$cell['padding']['L'];
26675 $wadj = ($table['simple']['border_details']['L']['w'] +
$table['simple']['border_details']['R']['w'])/2 +
$cell['padding']['L'] +
$cell['padding']['R'];
26676 $yadj = $table['simple']['border_details']['T']['w']/2 +
$cell['padding']['T'];
26680 $this->decimal_offset
= 0;
26681 if(substr($cell['a'],0,1) == 'D') {
26682 if ($cell['colspan'] > 1) { $this
->divalign
= $c
['a'] = substr($cell
['a'],2,1); }
26684 $smax = $table['decimal_align'][$j]['maxs0'];
26685 $d_content = $table['decimal_align'][$j]['maxs0'] +
$table['decimal_align'][$j]['maxs1'];
26686 $this->decimal_offset
= $smax;
26687 $extra = ($w - $d_content - $wadj);
26689 if(substr($cell['a'],2,1) == 'R') { $this
->decimal_offset +
= $extra
; }
26690 else if(substr($cell['a'],2,1) == 'C') { $this
->decimal_offset +
= ($extra
)/2; }
26694 $this->divwidth
=$w-$wadj;
26695 if ($this->divwidth
== 0) { $this
->divwidth
= 0.0001; }
26698 $this->printbuffer($cell['textbuffer'],'',true);
26703 /*-- BACKGROUNDS --*/
26704 if (!$this->ColActive
) {
26705 if (isset($table['trgradients'][$i]) && ($j==0 || $table['borders_separate'])) {
26706 $g = $this->grad
->parseBackgroundGradient($table['trgradients'][$i]);
26711 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26712 if ($table['borders_separate']) {
26713 $gw -= ($table['padding']['L'] +
$table['border_details']['L']['w'] +
$table['padding']['R'] +
$table['border_details']['R']['w'] +
$table['border_spacing_H']);
26715 $clx = $x+
($table['border_spacing_H']/2);
26716 $cly = $y+
($table['border_spacing_V']/2);
26717 $clw = $w- $table['border_spacing_H'];
26718 $clh = $h- $table['border_spacing_V'];
26719 // Set clipping path
26720 $s = ' q 0 w '; // Line width=0
26721 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // start point TL before the arc
26722 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK
, ($this->h
-($cly+
$clh))*_MPDFK
); // line to BL
26723 $s .= sprintf('%.3F %.3F l ', ($clx+
$clw)*_MPDFK
, ($this->h
-($cly+
$clh))*_MPDFK
); // line to BR
26724 $s .= sprintf('%.3F %.3F l ', ($clx+
$clw)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // line to TR
26725 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // line to TL
26726 $s .= ' W n '; // Ends path no-op & Sets the clipping path
26727 $this->tableBackgrounds
[$level*9+
4][] = array('gradient'=>true, 'x'=>$gx +
($table['border_spacing_H']/2), 'y'=>$gy +
($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s);
26730 $this->tableBackgrounds
[$level*9+
4][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26734 if (isset($table['trbackground-images'][$i]) && ($j==0 || $table['borders_separate'])) {
26735 if ($table['trbackground-images'][$i]['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['trbackground-images'][$i]['gradient'] )) {
26736 $g = $this->grad
->parseMozGradient( $table['trbackground-images'][$i]['gradient'] );
26741 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26742 if ($table['borders_separate']) {
26743 $gw -= ($table['padding']['L'] +
$table['border_details']['L']['w'] +
$table['padding']['R'] +
$table['border_details']['R']['w'] +
$table['border_spacing_H']);
26745 $clx = $x+
($table['border_spacing_H']/2);
26746 $cly = $y+
($table['border_spacing_V']/2);
26747 $clw = $w- $table['border_spacing_H'];
26748 $clh = $h- $table['border_spacing_V'];
26749 // Set clipping path
26750 $s = ' q 0 w '; // Line width=0
26751 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // start point TL before the arc
26752 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK
, ($this->h
-($cly+
$clh))*_MPDFK
); // line to BL
26753 $s .= sprintf('%.3F %.3F l ', ($clx+
$clw)*_MPDFK
, ($this->h
-($cly+
$clh))*_MPDFK
); // line to BR
26754 $s .= sprintf('%.3F %.3F l ', ($clx+
$clw)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // line to TR
26755 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // line to TL
26756 $s .= ' W n '; // Ends path no-op & Sets the clipping path
26757 $this->tableBackgrounds
[$level*9+
4][] = array('gradient'=>true, 'x'=>$gx +
($table['border_spacing_H']/2), 'y'=>$gy +
($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s);
26760 $this->tableBackgrounds
[$level*9+
4][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26765 $image_id = $table['trbackground-images'][$i]['image_id'];
26766 $orig_w = $table['trbackground-images'][$i]['orig_w'];
26767 $orig_h = $table['trbackground-images'][$i]['orig_h'];
26768 $x_pos = $table['trbackground-images'][$i]['x_pos'];
26769 $y_pos = $table['trbackground-images'][$i]['y_pos'];
26770 $x_repeat = $table['trbackground-images'][$i]['x_repeat'];
26771 $y_repeat = $table['trbackground-images'][$i]['y_repeat'];
26772 $resize = $table['trbackground-images'][$i]['resize'];
26773 $opacity = $table['trbackground-images'][$i]['opacity'];
26774 $itype = $table['trbackground-images'][$i]['itype'];
26779 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26780 if ($table['borders_separate']) {
26781 $gw -= ($table['padding']['L'] +
$table['border_details']['L']['w'] +
$table['padding']['R'] +
$table['border_details']['R']['w'] +
$table['border_spacing_H']);
26783 $clx = $x +
($table['border_spacing_H']/2);
26784 $cly = $y +
($table['border_spacing_V']/2);
26785 $clw = $w - $table['border_spacing_H'];
26786 $clh = $h - $table['border_spacing_V'];
26787 // Set clipping path
26788 $s = ' q 0 w '; // Line width=0
26789 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // start point TL
26790 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK
, ($this->h
-($cly+
$clh))*_MPDFK
); // line to BL
26791 $s .= sprintf('%.3F %.3F l ', ($clx+
$clw)*_MPDFK
, ($this->h
-($cly+
$clh))*_MPDFK
); // line to BR
26792 $s .= sprintf('%.3F %.3F l ', ($clx+
$clw)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // line to TR
26793 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK
, ($this->h
-($cly))*_MPDFK
); // line to TL
26794 $s .= ' W n '; // Ends path no-op & Sets the clipping path
26795 $this->tableBackgrounds
[$level*9+
5][] = array('x'=>$gx +
($table['border_spacing_H']/2), 'y'=>$gy +
($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>$s, 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
26798 $this->tableBackgrounds
[$level*9+
5][] = array('x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>'', 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
26804 /*-- END BACKGROUNDS --*/
26806 // TABLE BORDER - if separate
26807 if (($table['borders_separate'] || ($this->simpleTables
&& !$table['simple']['border'])) && $table['border']) {
26808 $halfspaceL = $table['padding']['L'] +
($table['border_spacing_H']/2);
26809 $halfspaceR = $table['padding']['R'] +
($table['border_spacing_H']/2);
26810 $halfspaceT = $table['padding']['T'] +
($table['border_spacing_V']/2);
26811 $halfspaceB = $table['padding']['B'] +
($table['border_spacing_V']/2);
26819 if ($i == 0) { // Top
26820 $tby -= $halfspaceT +
($table['border_details']['T']['w']/2);
26821 $tbh +
= $halfspaceT +
($table['border_details']['T']['w']/2);
26822 $this->setBorder($tab_bord , _BORDER_TOP
);
26825 if ($i == ($numrows-1) || (isset($cell['rowspan']) && ($i+
$cell['rowspan']) == $numrows)) { // Bottom
26826 $tbh +
= $halfspaceB +
($table['border_details']['B']['w']/2);
26827 $this->setBorder($tab_bord , _BORDER_BOTTOM
);
26830 if ($j == 0) { // Left
26831 $tbx -= $halfspaceL +
($table['border_details']['L']['w']/2);
26832 $tbw +
= $halfspaceL +
($table['border_details']['L']['w']/2);
26833 $this->setBorder($tab_bord , _BORDER_LEFT
);
26836 if ($j == ($numcols-1) || (isset($cell['colspan']) && ($j+
$cell['colspan']) == $numcols)) { // Right
26837 $tbw +
= $halfspaceR +
($table['border_details']['R']['w']/2);
26838 $this->setBorder($tab_bord , _BORDER_RIGHT
);
26841 $this->_tableRect($tbx, $tby, $tbw, $tbh, $tab_bord , $table['border_details'], false, $table['borders_separate'], 'table', $corner, $table['border_spacing_V'], $table['border_spacing_H'] );
26848 }//end of (if isset(cells)...)
26851 $newpagestarted = false;
26852 $this->tabletheadjustfinished
= false;
26854 if ($this->ColActive
&& $i < $numrows-1 && $level==1) { $this
->breakpoints
[$this
->CurrCol
][] = $y + $h
; } // *COLUMNS*
26857 if ($this->ColActive
) {
26858 if (count($this->cellBorderBuffer
)) { $this
->printcellbuffer(); }
26860 /*-- END COLUMNS --*/
26862 if ($i == $numrows-1) { $this
->y
= $y + $h
; } //last row jump (update this->y position)
26863 if ($this->table_rotate
&& $level==1) {
26864 $this->tbrot_h +
= $h;
26871 if ($this->progressBar
) { $this
->UpdateProgressBar(7,70,' '); } // *PROGRESS-BAR*
26873 if (count($this->cellBorderBuffer
)) { $this
->printcellbuffer(); }
26876 if ($this->tableClipPath
) { $this
->_out("Q"); }
26877 $this->tableClipPath
= '';
26879 // Advance down page by half width of bottom border
26880 if ($table['borders_separate']) { $this
->y +
= $table
['padding']['B'] + $table
['border_details']['B']['w'] + $table
['border_spacing_V']/2; }
26881 else { $this
->y +
= $table
['max_cell_border_width']['B']/2; }
26883 if ($table['borders_separate'] && $level==1) { $this
->tbrot_h +
= $table
['margin']['B'] + $table
['padding']['B'] + $table
['border_details']['B']['w'] + $table
['border_spacing_V']/2; }
26884 else if ($level==1) { $this
->tbrot_h +
= $table
['margin']['B'] + $table
['max_cell_border_width']['B']/2; }
26888 if ($table['borders_separate']) {
26889 $bx -= ($table['padding']['L'] +
$table['border_details']['L']['w'] +
$table['border_spacing_H']/2);
26890 if ($tablestartpageno != $this->page
) { // IF broken across page
26891 $by +
= $table['max_cell_border_width']['T']/2;
26892 if (empty($tableheader)) { $by
-= ($table
['border_spacing_V']/2); }
26894 else if ($split && $startrow > 0 && empty($tableheader)) {
26895 $by -= ($table['border_spacing_V']/2);
26898 $by -= ($table['padding']['T'] +
$table['border_details']['T']['w'] +
$table['border_spacing_V']/2);
26901 else if ($tablestartpageno != $this->page
&& !empty($tableheader)) { $by +
= $maxbwtop
/2; }
26902 $by -= $tableheaderadj;
26903 $bh = $this->y
- $by;
26904 if (!$table['borders_separate']) { $bh
-= $table
['max_cell_border_width']['B']/2; }
26908 $finalSpread = true;
26909 for($t=$startcol; $t<$numcols; $t++
) {
26910 if ($table['colPg'][$t] == $splitpg) { $bw +
= $table
['wc'][$t
]; }
26911 if ($table['colPg'][$t] > $splitpg) { $finalSpread
= false; break; }
26913 if ($startcol==0) { $firstSpread
= true; }
26914 else { $firstSpread
= false; }
26915 if ($table['borders_separate']) {
26916 $bw +
= $table['border_spacing_H'];
26917 if ($firstSpread) {
26918 $bw +
= $table['padding']['L'] +
$table['border_details']['L']['w'];
26921 $bx +
= ($table['padding']['L'] +
$table['border_details']['L']['w']);
26923 if ($finalSpread) {
26924 $bw +
= $table['padding']['R'] +
$table['border_details']['R']['w'];
26929 $bw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26932 if (!$this->ColActive
) {
26933 if (isset($table['bgcolor'][-1])) {
26934 $color = $this->ConvertColor($table['bgcolor'][-1]);
26936 $this->tableBackgrounds
[$level*9][] = array('gradient'=>false, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'col'=>$color);
26940 /*-- BACKGROUNDS --*/
26941 if (isset($table['gradient'])) {
26942 $g = $this->grad
->parseBackgroundGradient($table['gradient']);
26944 $this->tableBackgrounds
[$level*9+
1][] = array('gradient'=>true, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26948 if (isset($table['background-image'])) {
26949 if ($table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['background-image']['gradient'] )) {
26950 $g = $this->grad
->parseMozGradient( $table['background-image']['gradient'] );
26952 $this->tableBackgrounds
[$level*9+
1][] = array('gradient'=>true, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
26956 $image_id = $table['background-image']['image_id'];
26957 $orig_w = $table['background-image']['orig_w'];
26958 $orig_h = $table['background-image']['orig_h'];
26959 $x_pos = $table['background-image']['x_pos'];
26960 $y_pos = $table['background-image']['y_pos'];
26961 $x_repeat = $table['background-image']['x_repeat'];
26962 $y_repeat = $table['background-image']['y_repeat'];
26963 $resize = $table['background-image']['resize'];
26964 $opacity = $table['background-image']['opacity'];
26965 $itype = $table['background-image']['itype'];
26966 $this->tableBackgrounds
[$level*9+
2][] = array('x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>'', 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
26969 /*-- END BACKGROUNDS --*/
26972 if ($this->tableBackgrounds
&& $level == 1) {
26973 $s = $this->PrintTableBackgrounds();
26974 if ($this->table_rotate
&& !$this->processingHeader
&& !$this->processingFooter
) {
26975 $this->tablebuffer
= preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->tablebuffer
);
26976 if ($level == 1) { $this
->tablebuffer
= preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this
->tablebuffer
); }
26978 else if ($this->bufferoutput
) {
26979 $this->headerbuffer
= preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->headerbuffer
);
26980 if ($level == 1) { $this
->headerbuffer
= preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this
->headerbuffer
); }
26983 $this->pages
[$this->page
] = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', '\\1'."\n".$s."\n", $this->pages
[$this->page
]);
26984 if ($level == 1) { $this
->pages
[$this
->page
] = preg_replace('/(___TABLE___BACKGROUNDS'.date('jY').')/', " ", $this
->pages
[$this
->page
]); }
26986 $this->tableBackgrounds
= array();
26990 // TABLE BOTTOM MARGIN
26991 if ($table['margin']['B']) {
26992 if (!$this->table_rotate
&& $level==1) {
26993 $this->DivLn($table['margin']['B'],$this->blklvl
,true); // collapsible
26996 $this->y +
= ($table['margin']['B']);
27000 if ($this->ColActive
&& $level==1) { $this
->breakpoints
[$this
->CurrCol
][] = $this
->y
; } // *COLUMNS*
27002 if ($this->cacheTables
) { fclose($fh
); }
27005 // Are there more columns to print on a next page?
27006 if ($lastCol < $numcols-1) {
27008 $startcol = $lastCol +
1;
27009 return array(false, $startrow, $startcol, $splitpg, $returny, $y0);
27012 if ($this->cacheTables
) {
27013 unlink($table['cache']);
27014 @unlink($table['cache'].'.bak');
27016 return array(true,0,0,0);
27019 if ($this->cacheTables
) {
27020 unlink($table['cache']);
27021 @unlink($table['cache'].'.bak');
27024 }//END OF FUNCTION _tableWrite()
27027 /////////////////////////END OF TABLE CODE//////////////////////////////////
27028 /*-- END TABLES --*/
27030 function _putextgstates() {
27031 for ($i = 1; $i <= count($this->extgstates
); $i++
) {
27033 $this->extgstates
[$i]['n'] = $this->n
;
27034 $this->_out('<</Type /ExtGState');
27035 foreach ($this->extgstates
[$i]['parms'] as $k=>$v)
27036 $this->_out('/'.$k.' '.$v);
27038 $this->_out('endobj');
27042 function _putocg() {
27043 if ($this->hasOC
) { // mPDF 5.6.01
27045 $this->n_ocg_print
=$this->n
;
27046 $this->_out('<</Type /OCG /Name '.$this->_textstring('Print only'));
27047 $this->_out('/Usage <</Print <</PrintState /ON>> /View <</ViewState /OFF>>>>>>');
27048 $this->_out('endobj');
27050 $this->n_ocg_view
=$this->n
;
27051 $this->_out('<</Type /OCG /Name '.$this->_textstring('Screen only'));
27052 $this->_out('/Usage <</Print <</PrintState /OFF>> /View <</ViewState /ON>>>>>>');
27053 $this->_out('endobj');
27055 $this->n_ocg_hidden
=$this->n
;
27056 $this->_out('<</Type /OCG /Name '.$this->_textstring('Hidden'));
27057 $this->_out('/Usage <</Print <</PrintState /OFF>> /View <</ViewState /OFF>>>>>>');
27058 $this->_out('endobj');
27060 // mPDF 5.6.01 Add Layers
27061 if (count($this->layers
)) {
27062 ksort($this->layers
);
27063 foreach($this->layers
as $id=>$layer) {
27065 $this->layers
[$id]['n'] = $this->n
;
27067 if (isset($this->layerDetails
[$id]['name']) && $this->layerDetails
[$id]['name']) {
27068 $name = $this->layerDetails
[$id]['name'];
27070 else { $name
= $layer
['name']; }
27071 $this->_out('<</Type /OCG /Name '.$this->_UTF16BEtextstring($name).'>>');
27072 $this->_out('endobj');
27081 function _putimportedobjects() {
27082 if (is_array($this->parsers
) && count($this->parsers
) > 0) {
27083 foreach($this->parsers
AS $filename => $p) {
27084 $this->current_parser
=& $this->parsers
[$filename];
27085 if (is_array($this->_obj_stack
[$filename])) {
27086 while($n = key($this->_obj_stack
[$filename])) {
27087 $nObj = $this->current_parser
->pdf_resolve_object($this->current_parser
->c
,$this->_obj_stack
[$filename][$n][1]);
27088 $this->_newobj($this->_obj_stack
[$filename][$n][0]);
27089 if ($nObj[0] == PDF_TYPE_STREAM
) {
27090 $this->pdf_write_value($nObj);
27093 $this->pdf_write_value($nObj[1]);
27095 $this->_out('endobj');
27096 $this->_obj_stack
[$filename][$n] = null; // free memory
27097 unset($this->_obj_stack
[$filename][$n]);
27098 reset($this->_obj_stack
[$filename]);
27106 function _putformxobjects() {
27107 $filter=($this->compress
) ? '/Filter /FlateDecode ' : '';
27108 reset($this->tpls
);
27109 foreach($this->tpls
AS $tplidx => $tpl) {
27110 $p=($this->compress
) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
27112 $this->tpls
[$tplidx]['n'] = $this->n
;
27113 $this->_out('<<'.$filter.'/Type /XObject');
27114 $this->_out('/Subtype /Form');
27115 $this->_out('/FormType 1');
27116 // Left/Bottom/Right/Top
27117 $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]',
27118 $tpl['box']['x']*_MPDFK
,
27119 $tpl['box']['y']*_MPDFK
,
27120 ($tpl['box']['x'] +
$tpl['box']['w'])*_MPDFK
,
27121 ($tpl['box']['y'] +
$tpl['box']['h'])*_MPDFK
)
27125 if (isset($tpl['box']))
27126 $this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]',-$tpl['box']['x']*_MPDFK
, -$tpl['box']['y']*_MPDFK
));
27127 $this->_out('/Resources ');
27129 if (isset($tpl['resources'])) {
27130 $this->current_parser
=& $tpl['parser'];
27131 $this->pdf_write_value($tpl['resources']);
27133 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27134 if (isset($this->_res
['tpl'][$tplidx]['fonts']) && count($this->_res
['tpl'][$tplidx]['fonts'])) {
27135 $this->_out('/Font <<');
27136 foreach($this->_res
['tpl'][$tplidx]['fonts'] as $font)
27137 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27140 if(isset($this->_res
['tpl'][$tplidx]['images']) && count($this->_res
['tpl'][$tplidx]['images']) ||
27141 isset($this->_res
['tpl'][$tplidx]['tpls']) && count($this->_res
['tpl'][$tplidx]['tpls']))
27143 $this->_out('/XObject <<');
27144 if (isset($this->_res
['tpl'][$tplidx]['images']) && count($this->_res
['tpl'][$tplidx]['images'])) {
27145 foreach($this->_res
['tpl'][$tplidx]['images'] as $image)
27146 $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
27148 if (isset($this->_res
['tpl'][$tplidx]['tpls']) && count($this->_res
['tpl'][$tplidx]['tpls'])) {
27149 foreach($this->_res
['tpl'][$tplidx]['tpls'] as $i => $itpl)
27150 $this->_out($this->tplprefix
.$i.' '.$itpl['n'].' 0 R');
27157 $this->_out('/Length '.strlen($p).' >>');
27158 $this->_putstream($p);
27159 $this->_out('endobj');
27163 /*-- END IMPORTS --*/
27166 function _putpatterns() {
27167 for ($i = 1; $i <= count($this->patterns
); $i++
) {
27168 $x = $this->patterns
[$i]['x'];
27169 $y = $this->patterns
[$i]['y'];
27170 $w = $this->patterns
[$i]['w'];
27171 $h = $this->patterns
[$i]['h'];
27172 $pgh = $this->patterns
[$i]['pgh'];
27173 $orig_w = $this->patterns
[$i]['orig_w'];
27174 $orig_h = $this->patterns
[$i]['orig_h'];
27175 $image_id = $this->patterns
[$i]['image_id'];
27176 $itype = $this->patterns
[$i]['itype'];
27177 $bpa = $this->patterns
[$i]['bpa']; // mPDF 5.6.10 background positioning area
27179 if ($this->patterns
[$i]['x_repeat']) { $x_repeat
= true; }
27180 else { $x_repeat
= false; }
27181 if ($this->patterns
[$i]['y_repeat']) { $y_repeat
= true; }
27182 else { $y_repeat
= false; }
27183 $x_pos = $this->patterns
[$i]['x_pos'];
27184 if (stristr($x_pos ,'%') ) {
27187 if (isset($bpa['w']) && $bpa['w']) $x_pos = ($bpa['w'] * $x_pos) - ($orig_w/_MPDFK
* $x_pos); // mPDF 5.6.10
27188 else $x_pos = ($w * $x_pos) - ($orig_w/_MPDFK
* $x_pos);
27190 $y_pos = $this->patterns
[$i]['y_pos'];
27191 if (stristr($y_pos ,'%') ) {
27194 if (isset($bpa['h']) && $bpa['h']) $y_pos = ($bpa['h'] * $y_pos) - ($orig_h/_MPDFK
* $y_pos); // mPDF 5.6.10
27195 else $y_pos = ($h * $y_pos) - ($orig_h/_MPDFK
* $y_pos);
27197 if (isset($bpa['x']) && $bpa['x']) $adj_x = ($x_pos +
$bpa['x']) *_MPDFK
; // mPDF 5.6.10
27198 else $adj_x = ($x_pos +
$x) *_MPDFK
;
27199 if (isset($bpa['y']) && $bpa['y']) $adj_y = (($pgh - $y_pos - $bpa['y'])*_MPDFK
) - $orig_h ; // mPDF 5.6.10
27200 else $adj_y = (($pgh - $y_pos - $y)*_MPDFK
) - $orig_h ;
27202 if ($itype == 'svg' || $itype == 'wmf') {
27203 foreach($this->formobjects
AS $fo) {
27204 if ($fo['i'] == $image_id) {
27205 $img_obj = $fo['n'];
27215 foreach($this->images
AS $img) {
27216 if ($img['i'] == $image_id) { $img_obj
= $img
['n']; break; }
27219 if (!$img_obj ) { echo "Problem: Image object not found for background pattern ".$img
['i']; exit; }
27222 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27223 if ($itype == 'svg' || $itype == 'wmf') {
27224 $this->_out('/XObject <</FO'.$image_id.' '.$img_obj.' 0 R >>');
27225 // ******* ADD ANY ExtGStates, Shading AND Fonts needed for the FormObject
27226 // Set in classes/svg array['fo'] = true
27227 // Required that _putshaders comes before _putpatterns in _putresources
27228 // This adds any resources associated with any FormObject to every Formobject - overkill but works!
27229 if (count($this->extgstates
)) {
27230 $this->_out('/ExtGState <<');
27231 foreach($this->extgstates
as $k=>$extgstate)
27232 if (isset($extgstate['fo']) && $extgstate['fo']) {
27233 if (isset($extgstate['trans'])) $this->_out('/'.$extgstate['trans'].' '.$extgstate['n'].' 0 R');
27234 else $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
27238 /*-- BACKGROUNDS --*/
27239 if (isset($this->gradients
) AND (count($this->gradients
) > 0)) {
27240 $this->_out('/Shading <<');
27241 foreach ($this->gradients
as $id => $grad) {
27242 if (isset($grad['fo']) && $grad['fo']) {
27243 $this->_out('/Sh'.$id.' '.$grad['id'].' 0 R');
27248 /*-- END BACKGROUNDS --*/
27249 $this->_out('/Font <<');
27250 foreach($this->fonts
as $font) {
27251 if (!$font['used'] && $font['type']=='TTF') { continue; }
27252 if (isset($font['fo']) && $font['fo']) {
27253 if ($font['type']=='TTF' && ($font['sip'] || $font['smp'])) {
27254 foreach($font['n'] AS $k => $fid) {
27255 $this->_out('/F'.$font['subsetfontids'][$k].' '.$font['n'][$k].' 0 R');
27259 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27266 $this->_out('/XObject <</I'.$image_id.' '.$img_obj.' 0 R >>');
27269 $this->_out('endobj');
27272 $this->patterns
[$i]['n'] = $this->n
;
27273 $this->_out('<< /Type /Pattern /PatternType 1 /PaintType 1 /TilingType 2');
27274 $this->_out('/Resources '. ($this->n
-1) .' 0 R');
27276 $this->_out(sprintf('/BBox [0 0 %.3F %.3F]',$orig_w,$orig_h));
27277 if ($x_repeat) { $this
->_out(sprintf('/XStep %.3F',$orig_w
)); }
27278 else { $this
->_out(sprintf('/XStep %d',99999)); }
27279 if ($y_repeat) { $this
->_out(sprintf('/YStep %.3F',$orig_h
)); }
27280 else { $this
->_out(sprintf('/YStep %d',99999)); }
27282 if ($itype == 'svg' || $itype == 'wmf') {
27283 $this->_out(sprintf('/Matrix [1 0 0 -1 %.3F %.3F]', $adj_x, ($adj_y+
$orig_h)));
27284 $s = sprintf("q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q",($orig_w/$fo_w), (-$orig_h/$fo_h), -($orig_w/$fo_w)*$wmf_x, ($orig_w/$fo_w)*$wmf_y, $image_id);
27287 $this->_out(sprintf('/Matrix [1 0 0 1 %.3F %.3F]',$adj_x,$adj_y));
27288 $s = sprintf("q %.3F 0 0 %.3F 0 0 cm /I%d Do Q",$orig_w,$orig_h,$image_id);
27291 if ($this->compress
) {
27292 $this->_out('/Filter /FlateDecode');
27293 $s = gzcompress($s);
27295 $this->_out('/Length '.strlen($s).'>>');
27296 $this->_putstream($s);
27297 $this->_out('endobj');
27301 /*-- BACKGROUNDS --*/
27302 function _putshaders() {
27303 $maxid = count($this->gradients
); //index for transparency gradients
27304 foreach ($this->gradients
as $id => $grad) {
27305 if (($grad['type'] == 2 || $grad['type'] == 3) && empty($grad['is_mask'])) {
27308 $this->_out('/FunctionType 3');
27309 $this->_out('/Domain [0 1]');
27313 for($i=0; $i<(count($grad['stops'])-1); $i++
) {
27314 $fn[] = ($this->n+
1+
$i).' 0 R';
27316 if ($i>0) { $bd
[] = sprintf('%.3F', $grad
['stops'][$i
]['offset']); }
27318 $this->_out('/Functions ['.implode(' ',$fn).']');
27319 $this->_out('/Bounds ['.implode(' ',$bd).']');
27320 $this->_out('/Encode ['.implode(' ',$en).']');
27322 $this->_out('endobj');
27324 for($i=0; $i<(count($grad['stops'])-1); $i++
) {
27327 $this->_out('/FunctionType 2');
27328 $this->_out('/Domain [0 1]');
27329 $this->_out('/C0 ['.$grad['stops'][$i]['col'].']');
27330 $this->_out('/C1 ['.$grad['stops'][$i+
1]['col'].']');
27331 $this->_out('/N 1');
27333 $this->_out('endobj');
27336 if ($grad['type'] == 2 || $grad['type'] == 3) {
27337 if (isset($grad['trans']) && $grad['trans']) {
27340 $this->_out('/FunctionType 3');
27341 $this->_out('/Domain [0 1]');
27345 for($i=0; $i<(count($grad['stops'])-1); $i++
) {
27346 $fn[] = ($this->n+
1+
$i).' 0 R';
27348 if ($i>0) { $bd
[] = sprintf('%.3F', $grad
['stops'][$i
]['offset']); }
27350 $this->_out('/Functions ['.implode(' ',$fn).']');
27351 $this->_out('/Bounds ['.implode(' ',$bd).']');
27352 $this->_out('/Encode ['.implode(' ',$en).']');
27354 $this->_out('endobj');
27356 for($i=0; $i<(count($grad['stops'])-1); $i++
) {
27359 $this->_out('/FunctionType 2');
27360 $this->_out('/Domain [0 1]');
27361 $this->_out(sprintf('/C0 [%.3F]', $grad['stops'][$i]['opacity']));
27362 $this->_out(sprintf('/C1 [%.3F]', $grad['stops'][$i+
1]['opacity']));
27363 $this->_out('/N 1');
27365 $this->_out('endobj');
27370 if (empty($grad['is_mask'])) {
27373 $this->_out('/ShadingType '.$grad['type']);
27374 if (isset($grad['colorspace'])) {
27375 $this->_out('/ColorSpace /Device'.$grad['colorspace']); // Can use CMYK if all C0 and C1 above have 4 values
27377 $this->_out('/ColorSpace /DeviceRGB');
27379 if ($grad['type'] == 2) {
27380 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]));
27381 $this->_out('/Function '.$f1.' 0 R');
27382 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27385 else if ($grad['type'] == 3) {
27386 //x0, y0, r0, x1, y1, r1
27387 //at this this time radius of inner circle is 0
27389 if (isset($grad['coords'][5]) && $grad['coords'][5]) { $ir
= $grad
['coords'][5]; }
27390 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $ir, $grad['coords'][2], $grad['coords'][3], $grad['coords'][4]));
27391 $this->_out('/Function '.$f1.' 0 R');
27392 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27395 else if ($grad['type']==6) {
27396 $this->_out('/BitsPerCoordinate 16');
27397 $this->_out('/BitsPerComponent 8');
27398 if ($grad['colorspace'] == 'CMYK') { $this
->_out('/Decode[0 1 0 1 0 1 0 1 0 1 0 1]'); }
27399 else if ($grad['colorspace'] == 'Gray') { $this
->_out('/Decode[0 1 0 1 0 1]'); }
27400 else { $this
->_out('/Decode[0 1 0 1 0 1 0 1 0 1]'); }
27401 $this->_out('/BitsPerFlag 8');
27402 $this->_out('/Length '.strlen($grad['stream']));
27404 $this->_putstream($grad['stream']);
27406 $this->_out('endobj');
27409 $this->gradients
[$id]['id'] = $this->n
;
27411 // set pattern object
27413 $out = '<< /Type /Pattern /PatternType 2';
27414 $out .= ' /Shading '.$this->gradients
[$id]['id'].' 0 R';
27416 $out .= "\n".'endobj';
27420 $this->gradients
[$id]['pattern'] = $this->n
;
27422 if (isset($grad['trans']) && $grad['trans']) {
27423 // luminosity pattern
27424 $transid = $id +
$maxid;
27427 $this->_out('/ShadingType '.$grad['type']);
27428 $this->_out('/ColorSpace /DeviceGray');
27429 if ($grad['type'] == 2) {
27430 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]));
27431 $this->_out('/Function '.$f2.' 0 R');
27432 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27435 else if ($grad['type'] == 3) {
27436 //x0, y0, r0, x1, y1, r1
27437 //at this this time radius of inner circle is 0
27439 if (isset($grad['coords'][5]) && $grad['coords'][5]) { $ir
= $grad
['coords'][5]; }
27440 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $ir, $grad['coords'][2], $grad['coords'][3], $grad['coords'][4]));
27441 $this->_out('/Function '.$f2.' 0 R');
27442 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27445 else if ($grad['type']==6) {
27446 $this->_out('/BitsPerCoordinate 16');
27447 $this->_out('/BitsPerComponent 8');
27448 $this->_out('/Decode[0 1 0 1 0 1]');
27449 $this->_out('/BitsPerFlag 8');
27450 $this->_out('/Length '.strlen($grad['stream_trans']));
27452 $this->_putstream($grad['stream_trans']);
27454 $this->_out('endobj');
27456 $this->gradients
[$transid]['id'] = $this->n
;
27458 $this->_out('<< /Type /Pattern /PatternType 2');
27459 $this->_out('/Shading '.$this->gradients
[$transid]['id'].' 0 R');
27461 $this->_out('endobj');
27462 $this->gradients
[$transid]['pattern'] = $this->n
;
27464 // Need to extend size of viewing box in case of transformations
27465 $str = 'q /a0 gs /Pattern cs /p'.$transid.' scn -'.($this->wPt
/2).' -'.($this->hPt
/2).' '.(2*$this->wPt
).' '.(2*$this->hPt
).' re f Q';
27466 $filter=($this->compress
) ? '/Filter /FlateDecode ' : '';
27467 $p=($this->compress
) ? gzcompress($str) : $str;
27468 $this->_out('<< /Type /XObject /Subtype /Form /FormType 1 '.$filter);
27469 $this->_out('/Length '.strlen($p));
27470 $this->_out('/BBox [-'.($this->wPt
/2).' -'.($this->hPt
/2).' '.(2*$this->wPt
).' '.(2*$this->hPt
).']');
27471 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceGray >>');
27472 $this->_out('/Resources <<');
27473 $this->_out('/ExtGState << /a0 << /ca 1 /CA 1 >> >>');
27474 $this->_out('/Pattern << /p'.$transid.' '.$this->gradients
[$transid]['pattern'].' 0 R >>');
27477 $this->_putstream($p);
27478 $this->_out('endobj');
27480 $this->_out('<< /Type /Mask /S /Luminosity /G '.($this->n
- 1).' 0 R >>'."\n".'endobj');
27482 $this->_out('<< /Type /ExtGState /SMask '.($this->n
- 1).' 0 R /AIS false >>'."\n".'endobj');
27483 if ($grad['fo']) { $this
->extgstates
[] = array('n' => $this
->n
, 'trans' => 'TGS'.$id
, 'fo'=>true); }
27484 else { $this
->extgstates
[] = array('n' => $this
->n
, 'trans' => 'TGS'.$id
); }
27488 /*-- END BACKGROUNDS --*/
27490 function _putspotcolors() {
27491 foreach($this->spotColors
as $name=>$color) {
27493 $this->_out('[/Separation /'.str_replace(' ','#20',$name));
27494 $this->_out('/DeviceCMYK <<');
27495 $this->_out('/Range [0 1 0 1 0 1 0 1] /C0 [0 0 0 0] ');
27496 $this->_out(sprintf('/C1 [%.3F %.3F %.3F %.3F] ',$color['c']/100,$color['m']/100,$color['y']/100,$color['k']/100));
27497 $this->_out('/FunctionType 2 /Domain [0 1] /N 1>>]');
27498 $this->_out('endobj');
27499 $this->spotColors
[$name]['n']=$this->n
;
27504 function _putresources() {
27505 if ($this->hasOC
|| count($this->layers
)) // mPDF 5.6.01
27507 $this->_putextgstates();
27508 $this->_putspotcolors();
27509 if ($this->progressBar
) { $this
->UpdateProgressBar(2,'40','Compiling Fonts'); } // *PROGRESS-BAR*
27510 $this->_putfonts();
27511 if ($this->progressBar
) { $this
->UpdateProgressBar(2,'50','Compiling Images'); } // *PROGRESS-BAR*
27512 $this->_putimages();
27513 $this->_putformobjects(); // *IMAGES-CORE*
27516 if ($this->enableImports
) {
27517 $this->_putformxobjects();
27518 $this->_putimportedobjects();
27520 /*-- END IMPORTS --*/
27522 /*-- BACKGROUNDS --*/
27523 $this->_putshaders();
27524 $this->_putpatterns();
27525 /*-- END BACKGROUNDS --*/
27528 //Resource dictionary
27529 $this->offsets
[2]=strlen($this->buffer
);
27530 $this->_out('2 0 obj');
27531 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27533 $this->_out('/Font <<');
27534 foreach($this->fonts
as $font) {
27535 if (!$font['used'] && $font['type']=='TTF') { continue; }
27536 if ($font['type']=='TTF' && ($font['sip'] || $font['smp'])) {
27537 foreach($font['n'] AS $k => $fid) {
27538 $this->_out('/F'.$font['subsetfontids'][$k].' '.$font['n'][$k].' 0 R');
27542 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27547 if (count($this->spotColors
)) {
27548 $this->_out('/ColorSpace <<');
27549 foreach($this->spotColors
as $color)
27550 $this->_out('/CS'.$color['i'].' '.$color['n'].' 0 R');
27554 if (count($this->extgstates
)) {
27555 $this->_out('/ExtGState <<');
27556 foreach($this->extgstates
as $k=>$extgstate)
27557 if (isset($extgstate['trans'])) $this->_out('/'.$extgstate['trans'].' '.$extgstate['n'].' 0 R');
27558 else $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
27562 /*-- BACKGROUNDS --*/
27563 if (isset($this->gradients
) AND (count($this->gradients
) > 0)) {
27564 $this->_out('/Shading <<');
27565 foreach ($this->gradients
as $id => $grad) {
27566 $this->_out('/Sh'.$id.' '.$grad['id'].' 0 R');
27571 // ??? Not needed !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27572 $this->_out('/Pattern <<');
27573 foreach ($this->gradients as $id => $grad) {
27574 $this->_out('/P'.$id.' '.$grad['pattern'].' 0 R');
27579 /*-- END BACKGROUNDS --*/
27581 if(count($this->images
) || count($this->formobjects
) || ($this->enableImports
&& count($this->tpls
))) {
27582 $this->_out('/XObject <<');
27583 foreach($this->images
as $image)
27584 $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
27585 foreach($this->formobjects
as $formobject)
27586 $this->_out('/FO'.$formobject['i'].' '.$formobject['n'].' 0 R');
27588 if ($this->enableImports
&& count($this->tpls
)) {
27589 foreach($this->tpls
as $tplidx => $tpl) {
27590 $this->_out($this->tplprefix
.$tplidx.' '.$tpl['n'].' 0 R');
27593 /*-- END IMPORTS --*/
27597 /*-- BACKGROUNDS --*/
27599 if (count($this->patterns
)) {
27600 $this->_out('/Pattern <<');
27601 foreach($this->patterns
as $k=>$patterns)
27602 $this->_out('/P'.$k.' '.$patterns['n'].' 0 R');
27605 /*-- END BACKGROUNDS --*/
27608 if ($this->hasOC
|| count($this->layers
)) {
27609 $this->_out('/Properties <<');
27610 if ($this->hasOC
) {
27611 $this->_out('/OC1 '.$this->n_ocg_print
.' 0 R /OC2 '.$this->n_ocg_view
.' 0 R /OC3 '.$this->n_ocg_hidden
.' 0 R ');
27613 if (count($this->layers
)) {
27614 foreach($this->layers
as $id=>$layer)
27615 $this->_out('/ZI'.$id.' '.$layer['n'].' 0 R');
27621 $this->_out('endobj'); // end resource dictionary
27623 $this->_putbookmarks(); // *BOOKMARKS*
27625 if (isset($this->js
) && $this->js
) {
27626 $this->_putjavascript();
27629 /*-- ENCRYPTION --*/
27630 if ($this->encrypted
) {
27632 $this->enc_obj_id
= $this->n
;
27634 $this->_putencryption();
27636 $this->_out('endobj');
27638 /*-- END ENCRYPTION --*/
27642 function _putjavascript() {
27644 $this->n_js
= $this->n
;
27646 $this->_out('/Names [(EmbeddedJS) '.(1 +
$this->n
).' 0 R ]');
27648 $this->_out('endobj');
27652 $this->_out('/S /JavaScript');
27653 $this->_out('/JS '.$this->_textstring($this->js
));
27655 $this->_out('endobj');
27661 /*-- ENCRYPTION --*/
27662 function _putencryption() {
27663 $this->_out('/Filter /Standard');
27664 if ($this->useRC128encryption
) {
27665 $this->_out('/V 2');
27666 $this->_out('/R 3');
27667 $this->_out('/Length 128');
27670 $this->_out('/V 1');
27671 $this->_out('/R 2');
27673 $this->_out('/O ('.$this->_escape($this->Ovalue
).')');
27674 $this->_out('/U ('.$this->_escape($this->Uvalue
).')');
27675 $this->_out('/P '.$this->Pvalue
);
27677 /*-- END ENCRYPTION --*/
27679 function _puttrailer() {
27680 $this->_out('/Size '.($this->n+
1));
27681 $this->_out('/Root '.$this->n
.' 0 R');
27682 $this->_out('/Info '.$this->InfoRoot
.' 0 R');
27683 /*-- ENCRYPTION --*/
27684 if ($this->encrypted
) {
27685 $this->_out('/Encrypt '.$this->enc_obj_id
.' 0 R');
27686 $this->_out('/ID [<'.$this->uniqid
.'> <'.$this->uniqid
.'>]');
27689 /*-- END ENCRYPTION --*/
27690 $uniqid = md5(time() . $this->buffer
);
27691 $this->_out('/ID [<'.$uniqid.'> <'.$uniqid.'>]');
27692 /*-- ENCRYPTION --*/
27694 /*-- END ENCRYPTION --*/
27697 /*-- ENCRYPTION --*/
27698 function SetProtection($permissions=array(),$user_pass='',$owner_pass=null, $length=40) {
27699 $this->encrypted
=false;
27700 if (is_string($permissions) && strlen($permissions)>0) { $permissions
= array($permissions
); }
27701 else if (!is_array($permissions)) { return 0; }
27702 $this->last_rc4_key
='';
27703 $this->padding
="\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08".
27704 "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
27707 'print' => 4, // bit 3
27708 'modify' => 8, // bit 4
27709 'copy' => 16, // bit 5
27710 'annot-forms' => 32, // bit 6
27711 'fill-forms' => 256, // bit 9
27712 'extract' => 512, // bit 10
27713 'assemble' => 1024,// bit 11
27714 'print-highres' => 2048 // bit 12
27716 // bit 31 = 1073741824
27717 // bit 32 = 2147483648
27718 // bits 13-31 = 2147479552
27719 // bits 13-32 = 4294963200 + 192 = 4294963392
27720 $protection = 4294963392; // bits 7,8,13-32
27721 foreach ($permissions as $permission) {
27722 if (!isset($options[$permission]))
27723 $this->Error('Incorrect permission: '.$permission);
27724 if ($options[$permission] > 32) { $this
->useRC128encryption
= true; }
27725 if (isset($options[$permission])) $protection +
= $options[$permission];
27727 if ($length==128) { $this
->useRC128encryption
= true; }
27728 if ($owner_pass === null)
27729 $owner_pass = uniqid(rand());
27730 $this->encrypted
= true;
27731 $this->_generateencryptionkey($user_pass, $owner_pass, $protection);
27735 // Compute key depending on object number where the encrypted data is stored
27736 function _objectkey($n) {
27737 if ($this->useRC128encryption
)
27741 return substr($this->_md5_16($this->encryption_key
.pack('VXxx',$n)),0,$len);
27744 // RC4 is the standard encryption algorithm used in PDF format
27745 function _RC4($key, $text) {
27746 if ($this->last_rc4_key
!= $key) {
27747 $k = str_repeat($key, 256/strlen($key)+
1);
27748 $rc4 = range(0,255);
27750 for ($i=0; $i<256; $i++
){
27752 $j = ($j +
$t +
ord($k[$i])) %
256;
27753 $rc4[$i] = $rc4[$j];
27756 $this->last_rc4_key
= $key;
27757 $this->last_rc4_key_c
= $rc4;
27759 $rc4 = $this->last_rc4_key_c
;
27762 $len = strlen($text);
27766 for ($i=0; $i<$len; $i++
){
27770 $rc4[$a] = $rc4[$b];
27772 $k = $rc4[($rc4[$a]+
$rc4[$b])%
256];
27773 $out.= chr(ord($text[$i]) ^
$k);
27778 // Get MD5 as binary string
27779 function _md5_16($string) {
27780 return pack('H*',md5($string));
27784 function _Ovalue($user_pass, $owner_pass) {
27785 $tmp = $this->_md5_16($owner_pass);
27786 if ($this->useRC128encryption
) {
27787 for ($i = 0; $i < 50; ++
$i) {
27788 $tmp = $this->_md5_16($tmp);
27791 if ($this->useRC128encryption
)
27792 $keybytelen = (128 / 8);
27794 $keybytelen = (40 / 8);
27795 $owner_RC4_key = substr($tmp,0,$keybytelen);
27796 $enc = $this->_RC4($owner_RC4_key, $user_pass);
27797 if ($this->useRC128encryption
) {
27798 $len = strlen($owner_RC4_key);
27799 for ($i = 1; $i <= 19; ++
$i) {
27801 for ($j = 0; $j < $len; ++
$j) {
27802 $key .= chr(ord($owner_RC4_key{$j
}) ^
$i);
27804 $enc = $this->_RC4($key, $enc);
27811 function _Uvalue() {
27812 if ($this->useRC128encryption
) {
27813 $tmp = $this->_md5_16($this->padding
.$this->_hexToString($this->uniqid
));
27814 $enc = $this->_RC4($this->encryption_key
, $tmp);
27815 $len = strlen($tmp);
27816 for ($i=1; $i<=19; ++
$i) {
27818 for ($j=0; $j<$len; ++
$j) {
27819 $key .= chr(ord($this->encryption_key{$j
}) ^
$i);
27821 $enc = $this->_RC4($key, $enc);
27823 $enc .= str_repeat("\x00", 16);
27824 return substr($enc, 0, 32);
27827 return $this->_RC4($this->encryption_key
, $this->padding
);
27831 // Compute encryption key
27832 function _generateencryptionkey($user_pass, $owner_pass, $protection) {
27834 $user_pass = substr($user_pass.$this->padding
,0,32);
27835 $owner_pass = substr($owner_pass.$this->padding
,0,32);
27836 $chars = 'ABCDEF1234567890';
27838 for ($i=0; $i<32; $i++
) { $id
.= $chars
{rand(0, 15)}; }
27839 $this->uniqid
= md5($id);
27841 $this->Ovalue
= $this->_Ovalue($user_pass,$owner_pass);
27842 // Compute encyption key
27843 if ($this->useRC128encryption
)
27844 $keybytelen = (128/8);
27846 $keybytelen = (40/8);
27847 $prot = sprintf('%032b', $protection);
27848 $perms = chr(bindec(substr($prot,24,8)));
27849 $perms .= chr(bindec(substr($prot,16,8)));
27850 $perms .= chr(bindec(substr($prot,8,8)));
27851 $perms .= chr(bindec(substr($prot,0,8)));
27852 $tmp = $this->_md5_16($user_pass.$this->Ovalue
.$perms.$this->_hexToString($this->uniqid
));
27853 if ($this->useRC128encryption
) {
27854 for ($i=0; $i<50; ++
$i) {
27855 $tmp = $this->_md5_16(substr($tmp, 0, $keybytelen));
27858 $this->encryption_key
= substr($tmp,0,$keybytelen);
27860 $this->Uvalue
= $this->_Uvalue();
27862 $this->Pvalue
= $protection;
27866 function _hexToString($hs) {
27868 $len = strlen($hs);
27869 if (($len %
2) != 0) {
27873 for ($i = 0; $i < $len; $i +
= 2) {
27874 $s .= chr(hexdec($hs{$i
}.$hs{($i +
1)}));
27879 /*-- END ENCRYPTION --*/
27881 //=========================================
27882 /*-- BOOKMARKS --*/
27883 // FROM class PDF_Bookmark
27885 function Bookmark($txt,$level=0,$y=0) {
27886 $txt = $this->purify_utf8_text($txt);
27887 if ($this->text_input_as_HTML
) {
27888 $txt = $this->all_entities_to_utf8($txt);
27891 if (!$this->ColActive
){ $y
=$this
->y
; }
27892 else { $y
= $this
->y0
; } // If columns are on - mark top of columns
27894 // else y is used as set, or =0 i.e. top of page
27895 // DIRECTIONALITY RTL
27896 $bmo = array('t'=>$txt,'l'=>$level,'y'=>$y,'p'=>$this->page
);
27897 if ($this->keep_block_together
) {
27898 $this->ktBMoutlines
[]= $bmo;
27901 else if ($this->table_rotate
) {
27902 $this->tbrot_BMoutlines
[]= $bmo;
27904 else if ($this->kwt
) {
27905 $this->kwt_BMoutlines
[]= $bmo;
27907 /*-- END TABLES --*/
27908 else if ($this->ColActive
) { // *COLUMNS*
27909 $this->col_BMoutlines
[]= $bmo; // *COLUMNS*
27912 $this->BMoutlines
[]= $bmo;
27917 function _putbookmarks()
27919 $nb=count($this->BMoutlines
);
27924 $bmo = $this->BMoutlines
;
27925 $this->BMoutlines
= array();
27927 for($i=0;$i<count($bmo);$i++
) {
27928 if ($bmo[$i]['l']>0) {
27929 while($bmo[$i]['l']-$lastlevel > 1) { // If jump down more than one level, insert a new entry
27931 $new['t']="[".$new['t']."]"; // Put [] around text/title to highlight
27932 $new['l']=$lastlevel+
1;
27934 $this->BMoutlines
[] = $new;
27937 $this->BMoutlines
[] = $bmo[$i];
27938 $lastlevel = $bmo[$i]['l'];
27940 $nb=count($this->BMoutlines
);
27944 foreach($this->BMoutlines
as $i=>$o) {
27946 $parent=$lru[$o['l']-1];
27947 //Set parent and last pointers
27948 $this->BMoutlines
[$i]['parent']=$parent;
27949 $this->BMoutlines
[$parent]['last']=$i;
27950 if($o['l']>$level) {
27951 //Level increasing: set first pointer
27952 $this->BMoutlines
[$parent]['first']=$i;
27956 $this->BMoutlines
[$i]['parent']=$nb;
27958 if($o['l']<=$level and $i>0) {
27959 //Set prev and next pointers
27960 $prev=$lru[$o['l']];
27961 $this->BMoutlines
[$prev]['next']=$i;
27962 $this->BMoutlines
[$i]['prev']=$prev;
27971 foreach($this->BMoutlines
as $i=>$o) {
27973 $this->_out('<</Title '.$this->_UTF16BEtextstring($o['t']));
27974 $this->_out('/Parent '.($n+
$o['parent']).' 0 R');
27975 if(isset($o['prev']))
27976 $this->_out('/Prev '.($n+
$o['prev']).' 0 R');
27977 if(isset($o['next']))
27978 $this->_out('/Next '.($n+
$o['next']).' 0 R');
27979 if(isset($o['first']))
27980 $this->_out('/First '.($n+
$o['first']).' 0 R');
27981 if(isset($o['last']))
27982 $this->_out('/Last '.($n+
$o['last']).' 0 R');
27985 if (isset($this->pageDim
[$o['p']]['h'])) { $h
=$this
->pageDim
[$o
['p']]['h']; }
27988 $this->_out(sprintf('/Dest [%d 0 R /XYZ 0 %.3F null]',1+
2*($o['p']),($h-$o['y'])*_MPDFK
));
27989 if (isset($this->bookmarkStyles
) && isset($this->bookmarkStyles
[$o['l']])) {
27991 $bms = $this->bookmarkStyles
[$o['l']]['style'];
27993 if (strpos($bms,'B') !== false) { $style +
= 2; }
27994 if (strpos($bms,'I') !== false) { $style +
= 1; }
27995 $this->_out(sprintf('/F %d', $style));
27997 $col = $this->bookmarkStyles
[$o['l']]['color'];
27998 if (isset($col) && is_array($col) && count($col)==3) {
27999 $this->_out(sprintf('/C [%.3F %.3F %.3F]', ($col[0]/255), ($col[1]/255), ($col[2]/255)));
28003 $this->_out('/Count 0>>');
28004 $this->_out('endobj');
28008 $this->OutlineRoot
=$this->n
;
28009 $this->_out('<</Type /BMoutlines /First '.$n.' 0 R');
28010 $this->_out('/Last '.($n+
$lru[0]).' 0 R>>');
28011 $this->_out('endobj');
28013 /*-- END BOOKMARKS --*/
28017 //======================================================
28020 // DEPRACATED but included for backwards compatability
28021 function startPageNums() {
28024 //======================================================
28026 // ToC TABLE OF CONTENTS
28028 // Initiate, and Mark a place for the Table of Contents to be inserted
28029 function TOC($tocfont='', $tocfontsize=0, $tocindent=0, $resetpagenum='', $pagenumstyle='', $suppress='', $toc_orientation='', $TOCusePaging=true, $TOCuseLinking=false, $toc_id=0, $tocoutdent='') { // mPDF 5.6.19
28030 if (!class_exists('tocontents', false)) { include(_MPDF_PATH
.'classes/tocontents.php'); }
28031 if (empty($this->tocontents
)) { $this
->tocontents
= new tocontents($this
); }
28032 $this->tocontents
->TOC($tocfont, $tocfontsize, $tocindent, $resetpagenum, $pagenumstyle, $suppress, $toc_orientation, $TOCusePaging, $TOCuseLinking, $toc_id, $tocoutdent); // mPDF 5.6.19
28036 function TOCpagebreakByArray($a) {
28037 if (!is_array($a)) { $a
= array(); }
28038 if (!class_exists('tocontents', false)) { include(_MPDF_PATH
.'classes/tocontents.php'); }
28039 if (empty($this->tocontents
)) { $this
->tocontents
= new tocontents($this
); }
28040 $tocoutdent = (isset($a['tocoutdent']) ? $a['tocoutdent'] : (isset($a['outdent']) ? $a['outdent'] : ''));
28041 $TOCusePaging = (isset($a['TOCusePaging']) ? $a['TOCusePaging'] : (isset($a['paging']) ? $a['paging'] : true));
28042 $TOCuseLinking = (isset($a['TOCuseLinking']) ? $a['TOCuseLinking'] : (isset($a['links']) ? $a['links'] : ''));
28043 $toc_orientation = (isset($a['toc_orientation']) ? $a['toc_orientation'] : (isset($a['toc-orientation']) ? $a['toc-orientation'] : ''));
28044 $toc_mgl = (isset($a['toc_mgl']) ? $a['toc_mgl'] : (isset($a['toc-margin-left']) ? $a['toc-margin-left'] : ''));
28045 $toc_mgr = (isset($a['toc_mgr']) ? $a['toc_mgr'] : (isset($a['toc-margin-right']) ? $a['toc-margin-right'] : ''));
28046 $toc_mgt = (isset($a['toc_mgt']) ? $a['toc_mgt'] : (isset($a['toc-margin-top']) ? $a['toc-margin-top'] : ''));
28047 $toc_mgb = (isset($a['toc_mgb']) ? $a['toc_mgb'] : (isset($a['toc-margin-bottom']) ? $a['toc-margin-bottom'] : ''));
28048 $toc_mgh = (isset($a['toc_mgh']) ? $a['toc_mgh'] : (isset($a['toc-margin-header']) ? $a['toc-margin-header'] : ''));
28049 $toc_mgf = (isset($a['toc_mgf']) ? $a['toc_mgf'] : (isset($a['toc-margin-footer']) ? $a['toc-margin-footer'] : ''));
28050 $toc_ohname = (isset($a['toc_ohname']) ? $a['toc_ohname'] : (isset($a['toc-odd-header-name']) ? $a['toc-odd-header-name'] : ''));
28051 $toc_ehname = (isset($a['toc_ehname']) ? $a['toc_ehname'] : (isset($a['toc-even-header-name']) ? $a['toc-even-header-name'] : ''));
28052 $toc_ofname = (isset($a['toc_ofname']) ? $a['toc_ofname'] : (isset($a['toc-odd-footer-name']) ? $a['toc-odd-footer-name'] : ''));
28053 $toc_efname = (isset($a['toc_efname']) ? $a['toc_efname'] : (isset($a['toc-even-footer-name']) ? $a['toc-even-footer-name'] : ''));
28054 $toc_ohvalue = (isset($a['toc_ohvalue']) ? $a['toc_ohvalue'] : (isset($a['toc-odd-header-value']) ? $a['toc-odd-header-value'] : 0));
28055 $toc_ehvalue = (isset($a['toc_ehvalue']) ? $a['toc_ehvalue'] : (isset($a['toc-even-header-value']) ? $a['toc-even-header-value'] : 0));
28056 $toc_ofvalue = (isset($a['toc_ofvalue']) ? $a['toc_ofvalue'] : (isset($a['toc-odd-footer-value']) ? $a['toc-odd-footer-value'] : 0));
28057 $toc_efvalue = (isset($a['toc_efvalue']) ? $a['toc_efvalue'] : (isset($a['toc-even-footer-value']) ? $a['toc-even-footer-value'] : 0));
28058 $toc_preHTML = (isset($a['toc_preHTML']) ? $a['toc_preHTML'] : (isset($a['toc-preHTML']) ? $a['toc-preHTML'] : ''));
28059 $toc_postHTML = (isset($a['toc_postHTML']) ? $a['toc_postHTML'] : (isset($a['toc-postHTML']) ? $a['toc-postHTML'] : ''));
28060 $toc_bookmarkText = (isset($a['toc_bookmarkText']) ? $a['toc_bookmarkText'] : (isset($a['toc-bookmarkText']) ? $a['toc-bookmarkText'] : ''));
28061 $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : '');
28062 $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : '');
28063 $suppress = (isset($a['suppress']) ? $a['suppress'] : '');
28064 $orientation = (isset($a['orientation']) ? $a['orientation'] : '');
28065 $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
28066 $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
28067 $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
28068 $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
28069 $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
28070 $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
28071 $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
28072 $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
28073 $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
28074 $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
28075 $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
28076 $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
28077 $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
28078 $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
28079 $toc_id = (isset($a['toc_id']) ? $a['toc_id'] : (isset($a['name']) ? $a['name'] : 0));
28080 $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : ''));
28081 $toc_pagesel = (isset($a['toc_pagesel']) ? $a['toc_pagesel'] : (isset($a['toc-pageselector']) ? $a['toc-pageselector'] : ''));
28082 $sheetsize = (isset($a['sheetsize']) ? $a['sheetsize'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
28083 $toc_sheetsize = (isset($a['toc_sheetsize']) ? $a['toc_sheetsize'] : (isset($a['toc-sheet-size']) ? $a['toc-sheet-size'] : ''));
28085 $this->TOCpagebreak($tocfont, $tocfontsize, $tocindent, $TOCusePaging, $TOCuseLinking, $toc_orientation, $toc_mgl, $toc_mgr, $toc_mgt, $toc_mgb, $toc_mgh, $toc_mgf, $toc_ohname, $toc_ehname, $toc_ofname, $toc_efname, $toc_ohvalue, $toc_ehvalue, $toc_ofvalue, $toc_efvalue, $toc_preHTML, $toc_postHTML, $toc_bookmarkText, $resetpagenum, $pagenumstyle, $suppress, $orientation, $mgl, $mgr, $mgt, $mgb, $mgh, $mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue, $toc_id, $pagesel, $toc_pagesel, $sheetsize, $toc_sheetsize, $tocoutdent); // mPDF 5.6.19
28089 function TOCpagebreak($tocfont='', $tocfontsize='', $tocindent='', $TOCusePaging=true, $TOCuseLinking='', $toc_orientation='', $toc_mgl='',$toc_mgr='',$toc_mgt='',$toc_mgb='',$toc_mgh='',$toc_mgf='',$toc_ohname='',$toc_ehname='',$toc_ofname='',$toc_efname='',$toc_ohvalue=0,$toc_ehvalue=0,$toc_ofvalue=0, $toc_efvalue=0, $toc_preHTML='', $toc_postHTML='', $toc_bookmarkText='', $resetpagenum='', $pagenumstyle='', $suppress='', $orientation='', $mgl='',$mgr='',$mgt='',$mgb='',$mgh='',$mgf='',$ohname='',$ehname='',$ofname='',$efname='',$ohvalue=0,$ehvalue=0,$ofvalue=0,$efvalue=0, $toc_id=0, $pagesel='', $toc_pagesel='', $sheetsize='', $toc_sheetsize='', $tocoutdent='') { // mPDF 5.6.19) {
28090 if (!class_exists('tocontents', false)) { include(_MPDF_PATH
.'classes/tocontents.php'); }
28091 if (empty($this->tocontents
)) { $this
->tocontents
= new tocontents($this
); }
28093 if($this->state
==0) $this->AddPage();
28094 if ($this->y
== $this->tMargin
&& (!$this->mirrorMargins
||($this->mirrorMargins
&& $this->page %
2==1))) {
28095 // Don't add a page
28096 if ($this->page
==1 && count($this->PageNumSubstitutions
)==0) {
28097 if (!$suppress) { $suppress
= 'off'; }
28098 if (!$resetpagenum) { $resetpagenum
= 1; }
28099 //$this->PageNumSubstitutions[] = array('from'=>1, 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=> $suppress);
28101 $this->PageNumSubstitutions
[] = array('from'=>$this->page
, 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=> $suppress);
28104 $this->AddPage($orientation,'NEXT-ODD', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$sheetsize);
28107 $this->tocontents
->TOCpagebreak($tocfont, $tocfontsize, $tocindent, $TOCusePaging, $TOCuseLinking, $toc_orientation, $toc_mgl, $toc_mgr, $toc_mgt, $toc_mgb, $toc_mgh, $toc_mgf, $toc_ohname, $toc_ehname, $toc_ofname, $toc_efname, $toc_ohvalue, $toc_ehvalue, $toc_ofvalue, $toc_efvalue, $toc_preHTML, $toc_postHTML, $toc_bookmarkText, $resetpagenum, $pagenumstyle, $suppress, $orientation, $mgl, $mgr, $mgt, $mgb, $mgh, $mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue, $toc_id, $pagesel, $toc_pagesel, $sheetsize, $toc_sheetsize, $tocoutdent); // mPDF 5.6.19
28110 function TOC_Entry($txt, $level=0, $toc_id=0) {
28111 $txt = $this->purify_utf8_text($txt);
28112 if ($this->text_input_as_HTML
) {
28113 $txt = $this->all_entities_to_utf8($txt);
28115 if ($this->usingCoreFont
) { $txt
= mb_convert_encoding($txt
,$this
->mb_enc
,'UTF-8'); }
28116 if ($this->ColActive
) { $ily
= $this
->y0
; } else { $ily
= $this
->y
; } // use top of columns
28118 // mPDF 5.6.19 mPDF 5.6.25 mPDF 5.6.37
28119 if (!class_exists('tocontents', false)) { include(_MPDF_PATH
.'classes/tocontents.php'); }
28120 if (empty($this->tocontents
)) { $this
->tocontents
= new tocontents($this
); }
28121 $linkn = $this->AddLink();
28122 $uid = '__mpdfinternallink_' . $linkn ;
28123 if ($this->keep_block_together
) { $this
->internallink
[$uid
] = array("Y"=>$ily
,"PAGE"=>$this
->page
, "kt"=>true ); }
28124 else if ($this->table_rotate
) { $this
->internallink
[$uid
] = array("Y"=>$ily
,"PAGE"=>$this
->page
, "tbrot"=>true ); }
28125 else if ($this->kwt
) { $this
->internallink
[$uid
] = array("Y"=>$ily
,"PAGE"=>$this
->page
, "kwt"=>true ); }
28126 else if ($this->ColActive
) { $this
->internallink
[$uid
] = array("Y"=>$ily
,"PAGE"=>$this
->page
, "col"=>$this
->CurrCol
); }
28127 else $this->internallink
[$uid] = array("Y"=>$ily,"PAGE"=>$this->page
);
28128 $this->internallink
['#'.$uid] = $linkn;
28129 $this->SetLink($linkn,$ily,$this->page
);
28132 if ($this->biDirectional
) {
28133 $txt = preg_replace("/([".$this->pregRTLchars
."]+)/ue", '$this->ArabJoin(stripslashes(\'\\1\'))', $txt );
28136 if (strtoupper($toc_id)=='ALL') { $toc_id
= '_mpdf_all'; }
28137 else if (!$toc_id) { $toc_id
= 0; }
28138 else { $toc_id
= strtolower($toc_id
); }
28139 $btoc = array('t'=>$txt,'l'=>$level,'p'=>$this->page
, 'link'=>$linkn, 'toc_id'=>$toc_id);
28140 if ($this->keep_block_together
) {
28141 $this->_kttoc
[]= $btoc;
28144 else if ($this->table_rotate
) {
28145 $this->tbrot_toc
[]= $btoc;
28147 else if ($this->kwt
) {
28148 $this->kwt_toc
[]= $btoc;
28150 /*-- END TABLES --*/
28151 else if ($this->ColActive
) { // *COLUMNS*
28152 $this->col_toc
[]= $btoc; // *COLUMNS*
28155 $this->tocontents
->_toc
[]= $btoc;
28161 //======================================================
28162 function MovePages($target_page, $start_page, $end_page=-1) {
28163 // move a page/pages EARLIER in the document
28164 if ($end_page<1) { $end_page
= $start_page
; }
28165 $n_toc = $end_page - $start_page +
1;
28167 // Set/Update PageNumSubstitutions changes before moving anything
28168 if (count($this->PageNumSubstitutions
)) {
28169 $tp_present = false;
28170 $sp_present = false;
28171 $ep_present = false;
28172 foreach($this->PageNumSubstitutions
AS $k=>$v) {
28173 if ($this->PageNumSubstitutions
[$k]['from']==$target_page) {
28174 $tp_present = true;
28175 if ($this->PageNumSubstitutions
[$k]['suppress']!='on' && $this->PageNumSubstitutions
[$k]['suppress']!=1) {
28176 $this->PageNumSubstitutions
[$k]['suppress']='off';
28179 if ($this->PageNumSubstitutions
[$k]['from']==$start_page) {
28180 $sp_present = true;
28181 if ($this->PageNumSubstitutions
[$k]['suppress']!='on' && $this->PageNumSubstitutions
[$k]['suppress']!=1) {
28182 $this->PageNumSubstitutions
[$k]['suppress']='off';
28185 if ($this->PageNumSubstitutions
[$k]['from']==($end_page+
1)) {
28186 $ep_present = true;
28187 if ($this->PageNumSubstitutions
[$k]['suppress']!='on' && $this->PageNumSubstitutions
[$k]['suppress']!=1) {
28188 $this->PageNumSubstitutions
[$k]['suppress']='off';
28193 if (!$tp_present) {
28194 list($tp_type, $tp_suppress, $tp_reset) = $this->docPageSettings($target_page);
28196 if (!$sp_present) {
28197 list($sp_type, $sp_suppress, $sp_reset) = $this->docPageSettings($start_page);
28199 if (!$ep_present) {
28200 list($ep_type, $ep_suppress, $ep_reset) = $this->docPageSettings($start_page-1);
28207 for($i = $start_page;$i <= $end_page ;$i++
)
28208 $last[]=$this->pages
[$i];
28210 for($i=$start_page - 1;$i>=($target_page);$i--) {
28211 $this->pages
[$i+
$n_toc]=$this->pages
[$i];
28213 //Put toc pages at insert point
28214 for($i = 0;$i < $n_toc;$i++
) {
28215 $this->pages
[$target_page +
$i]=$last[$i];
28218 /*-- BOOKMARKS --*/
28219 // Update Bookmarks
28220 foreach($this->BMoutlines
as $i=>$o) {
28221 if($o['p']>=$target_page) {
28222 $this->BMoutlines
[$i]['p'] +
= $n_toc;
28225 /*-- END BOOKMARKS --*/
28227 // Update Page Links
28228 if (count($this->PageLinks
)) {
28230 foreach($this->PageLinks
as $i=>$o) {
28231 foreach($this->PageLinks
[$i] as $key => $pl) {
28232 if (strpos($pl[4],'@')===0) {
28233 $p=substr($pl[4],1);
28234 if($p>=$start_page && $p<=$end_page) {
28235 $this->PageLinks
[$i][$key][4] = '@'.($p +
($target_page - $start_page));
28237 else if($p>=$target_page && $p<$start_page) {
28238 $this->PageLinks
[$i][$key][4] = '@'.($p+
$n_toc);
28242 if($i>=$start_page && $i<=$end_page) {
28243 $newarr[($i +
($target_page - $start_page))] = $this->PageLinks
[$i];
28245 else if($i>=$target_page && $i<$start_page) {
28246 $newarr[($i +
$n_toc)] = $this->PageLinks
[$i];
28249 $newarr[$i] = $this->PageLinks
[$i];
28252 $this->PageLinks
= $newarr;
28255 // OrientationChanges
28256 if (count($this->OrientationChanges
)) {
28258 foreach($this->OrientationChanges
AS $p=>$v) {
28259 if($p>=$start_page && $p<=$end_page) { $newarr
[($p +
($target_page
- $start_page
))] = $this
->OrientationChanges
[$p
]; }
28260 else if($p>=$target_page && $p<$start_page) { $newarr
[$p+$n_toc
] = $this
->OrientationChanges
[$p
]; }
28261 else { $newarr
[$p
] = $this
->OrientationChanges
[$p
]; }
28264 $this->OrientationChanges
= $newarr;
28268 if (count($this->pageDim
)) {
28270 foreach($this->pageDim
AS $p=>$v) {
28271 if($p>=$start_page && $p<=$end_page) { $newarr
[($p +
($target_page
- $start_page
))] = $this
->pageDim
[$p
]; }
28272 else if($p>=$target_page && $p<$start_page) { $newarr
[$p+$n_toc
] = $this
->pageDim
[$p
]; }
28273 else { $newarr
[$p
] = $this
->pageDim
[$p
]; }
28276 $this->pageDim
= $newarr;
28279 // HTML Headers & Footers
28280 if (count($this->saveHTMLHeader
)) {
28282 foreach($this->saveHTMLHeader
AS $p=>$v) {
28283 if($p>=$start_page && $p<=$end_page) { $newarr
[($p +
($target_page
- $start_page
))] = $this
->saveHTMLHeader
[$p
]; }
28284 else if($p>=$target_page && $p<$start_page) { $newarr
[$p+$n_toc
] = $this
->saveHTMLHeader
[$p
]; }
28285 else { $newarr
[$p
] = $this
->saveHTMLHeader
[$p
]; }
28288 $this->saveHTMLHeader
= $newarr;
28290 if (count($this->saveHTMLFooter
)) {
28292 foreach($this->saveHTMLFooter
AS $p=>$v) {
28293 if($p>=$start_page && $p<=$end_page) { $newarr
[($p +
($target_page
- $start_page
))] = $this
->saveHTMLFooter
[$p
]; }
28294 else if($p>=$target_page && $p<$start_page) { $newarr
[$p+$n_toc
] = $this
->saveHTMLFooter
[$p
]; }
28295 else { $newarr
[$p
] = $this
->saveHTMLFooter
[$p
]; }
28298 $this->saveHTMLFooter
= $newarr;
28301 // Update Internal Links
28302 if (count($this->internallink
)) {
28303 foreach($this->internallink
as $key=>$o) {
28304 if($o['PAGE']>=$start_page && $o['PAGE']<=$end_page) {
28305 $this->internallink
[$key]['PAGE'] +
= ($target_page - $start_page);
28307 else if($o['PAGE']>=$target_page && $o['PAGE']<$start_page) {
28308 $this->internallink
[$key]['PAGE'] +
= $n_toc;
28314 if (count($this->links
)) {
28315 foreach($this->links
as $key=>$o) {
28316 if($o[0]>=$start_page && $o[0]<=$end_page) {
28317 $this->links
[$key][0] +
= ($target_page - $start_page);
28319 if($o[0]>=$target_page && $o[0]<$start_page) {
28320 $this->links
[$key][0] +
= $n_toc;
28325 // Update Form fields
28326 if (count($this->form
->forms
)) {
28327 foreach($this->form
->forms
as $key=>$f) {
28328 if($f['page']>=$start_page && $f['page']<=$end_page) {
28329 $this->form
->forms
[$key]['page'] +
= ($target_page - $start_page);
28331 if($f['page']>=$target_page && $f['page']<$start_page) {
28332 $this->form
->forms
[$key]['page'] +
= $n_toc;
28337 /*-- ANNOTATIONS --*/
28338 // Update Annotations
28339 if (count($this->PageAnnots
)) {
28341 foreach($this->PageAnnots
as $p=>$anno) {
28342 if($p>=$start_page && $p<=$end_page) {
28343 $np = $p +
($target_page - $start_page);
28344 foreach($anno as $o) {
28345 $newarr[$np][] = $o;
28348 else if($p>=$target_page && $p<$start_page) {
28350 foreach($anno as $o) {
28351 $newarr[$np][] = $o;
28355 $newarr[$p] = $this->PageAnnots
[$p];
28358 $this->PageAnnots
= $newarr;
28361 /*-- END ANNOTATIONS --*/
28363 // Update PageNumSubstitutions
28364 if (count($this->PageNumSubstitutions
)) {
28366 foreach($this->PageNumSubstitutions
AS $k=>$v) {
28367 if($this->PageNumSubstitutions
[$k]['from']>=$start_page && $this->PageNumSubstitutions
[$k]['from']<=$end_page) {
28368 $this->PageNumSubstitutions
[$k]['from'] +
= ($target_page - $start_page);
28369 $newarr[$this->PageNumSubstitutions
[$k]['from']] = $this->PageNumSubstitutions
[$k];
28371 else if($this->PageNumSubstitutions
[$k]['from']>=$target_page && $this->PageNumSubstitutions
[$k]['from']<$start_page) {
28372 $this->PageNumSubstitutions
[$k]['from'] +
= $n_toc;
28373 $newarr[$this->PageNumSubstitutions
[$k]['from']] = $this->PageNumSubstitutions
[$k];
28376 $newarr[$this->PageNumSubstitutions
[$k]['from']] = $this->PageNumSubstitutions
[$k];
28380 if (!$sp_present) {
28381 $newarr[$target_page] = array('from'=>$target_page, 'suppress'=>$sp_suppress, 'reset'=>$sp_reset, 'type'=>$sp_type);
28383 if (!$tp_present) {
28384 $newarr[($target_page +
$n_toc)] = array('from'=>($target_page+
$n_toc), 'suppress'=>$tp_suppress, 'reset'=>$tp_reset, 'type'=>$tp_type);
28386 if (!$ep_present && $end_page>count($this->pages
)) {
28387 $newarr[($end_page+
1)] = array('from'=>($end_page+
1), 'suppress'=>$ep_suppress, 'reset'=>$ep_reset, 'type'=>$ep_type);
28390 $this->PageNumSubstitutions
= array();
28391 foreach($newarr as $v) {
28392 $this->PageNumSubstitutions
[] = $v;
28397 //======================================================
28398 function DeletePages($start_page, $end_page=-1) {
28399 // move a page/pages EARLIER in the document
28400 if ($end_page<1) { $end_page
= $start_page
; }
28401 $n_tod = $end_page - $start_page +
1;
28402 $last_page = count($this->pages
);
28403 $n_atend = $last_page - $end_page +
1;
28406 for($i=0;$i<$n_atend;$i++
) {
28407 $this->pages
[$start_page+
$i]=$this->pages
[$end_page+
1+
$i];
28410 for($i = 0;$i < $n_tod ;$i++
)
28411 unset($this->pages
[$last_page-$i]);
28414 /*-- BOOKMARKS --*/
28415 // Update Bookmarks
28416 foreach($this->BMoutlines
as $i=>$o) {
28417 if($o['p']>=$end_page) { $this
->BMoutlines
[$i
]['p'] -= $n_tod
; }
28418 else if($p<$start_page) { unset($this
->BMoutlines
[$i
]); }
28420 /*-- END BOOKMARKS --*/
28422 // Update Page Links
28423 if (count($this->PageLinks
)) {
28425 foreach($this->PageLinks
as $i=>$o) {
28426 foreach($this->PageLinks
[$i] as $key => $pl) {
28427 if (strpos($pl[4],'@')===0) {
28428 $p=substr($pl[4],1);
28429 if($p>$end_page) { $this
->PageLinks
[$i
][$key
][4] = '@'.($p
- $n_tod
); }
28430 else if($p<$start_page) { unset($this
->PageLinks
[$i
][$key
]); }
28433 if($i>$end_page) { $newarr
[($i
- $n_tod
)] = $this
->PageLinks
[$i
]; }
28434 else if($p<$start_page) { $newarr
[$i
] = $this
->PageLinks
[$i
]; }
28436 $this->PageLinks
= $newarr;
28439 // OrientationChanges
28440 if (count($this->OrientationChanges
)) {
28442 foreach($this->OrientationChanges
AS $p=>$v) {
28443 if($p>$end_page) { $newarr
[($p
- $t_tod
)] = $this
->OrientationChanges
[$p
]; }
28444 else if($p<$start_page) { $newarr
[$p
] = $this
->OrientationChanges
[$p
]; }
28447 $this->OrientationChanges
= $newarr;
28451 if (count($this->pageDim
)) {
28453 foreach($this->pageDim
AS $p=>$v) {
28454 if($p>$end_page) { $newarr
[($p
- $n_tod
)] = $this
->pageDim
[$p
]; }
28455 else if($p<$start_page) { $newarr
[$p
] = $this
->pageDim
[$p
]; }
28458 $this->pageDim
= $newarr;
28461 // HTML Headers & Footers
28462 if (count($this->saveHTMLHeader
)) {
28463 foreach($this->saveHTMLHeader
AS $p=>$v) {
28464 if($p>end_page
) { $newarr
[($p
- $n_tod
)] = $this
->saveHTMLHeader
[$p
]; }
28465 else if($p<$start_page) { $newarr
[$p
] = $this
->saveHTMLHeader
[$p
]; }
28468 $this->saveHTMLHeader
= $newarr;
28470 if (count($this->saveHTMLFooter
)) {
28472 foreach($this->saveHTMLFooter
AS $p=>$v) {
28473 if($p>$end_page) { $newarr
[($p
- $n_tod
)] = $this
->saveHTMLFooter
[$p
]; }
28474 else if($p<$start_page) { $newarr
[$p
] = $this
->saveHTMLFooter
[$p
]; }
28477 $this->saveHTMLFooter
= $newarr;
28480 // Update Internal Links
28481 foreach($this->internallink
as $key=>$o) {
28482 if($o['PAGE']>$end_page) { $this
->internallink
[$key
]['PAGE'] -= $n_tod
; }
28483 else if($o['PAGE']<$start_page) { unset($this
->internallink
[$key
]); }
28487 foreach($this->links
as $key=>$o) {
28488 if($o[0]>$end_page) { $this
->links
[$key
][0] -= $n_tod
; }
28489 else if($o[0]<$start_page) { unset($this
->links
[$key
]); }
28492 // Update Form fields
28493 foreach($this->form
->forms
as $key=>$f) {
28494 if($f['page']>$end_page) { $this
->form
->forms
[$key
]['page'] -= $n_tod
; }
28495 else if($f['page']<$start_page) { unset($this
->form
->forms
[$key
]); }
28498 /*-- ANNOTATIONS --*/
28499 // Update Annotations
28500 if (count($this->PageAnnots
)) {
28502 foreach($this->PageAnnots
as $p=>$anno) {
28503 if($p>$end_page) { foreach($anno
as $o
) { $newarr
[($p
- $n_tod
)][] = $o
; } }
28504 else if($p<$start_page) { $newarr
[$p
] = $this
->PageAnnots
[$p
]; }
28507 $this->PageAnnots
= $newarr;
28509 /*-- END ANNOTATIONS --*/
28511 // Update PageNumSubstitutions
28512 foreach($this->PageNumSubstitutions
AS $k=>$v) {
28513 if($this->PageNumSubstitutions
[$k]['from']>$end_page) { $this
->PageNumSubstitutions
[$k
]['from'] -= $n_tod
; }
28514 else if($this->PageNumSubstitutions
[$k]['from']<$start_page) { unset($this
->PageNumSubstitutions
[$k
]); }
28518 $this->page
= count($this->pages
);
28522 //======================================================
28524 // FROM class PDF_Ref == INDEX
28526 function Reference($txt) {
28527 $this->IndexEntry($txt);
28531 function IndexEntry($txt, $xref='') {
28533 $this->IndexEntrySee($txt,$xref);
28536 $txt = strip_tags($txt);
28537 $txt = $this->purify_utf8_text($txt);
28538 if ($this->text_input_as_HTML
) {
28539 $txt = $this->all_entities_to_utf8($txt);
28541 if ($this->usingCoreFont
) { $txt
= mb_convert_encoding($txt
,$this
->mb_enc
,'UTF-8'); }
28544 $size=sizeof($this->Reference
);
28546 if ($this->directionality
== 'rtl') { // *RTL*
28547 $txt = str_replace(':',' - ',$txt); // *RTL*
28550 $txt = str_replace(':',', ',$txt);
28554 //Search the reference (AND Ref/PageNo) in the array
28555 for ($i=0;$i<$size;$i++
){
28556 if ($this->keep_block_together
) {
28557 if (isset($this->ktReference
[$i]['t']) && $this->ktReference
[$i]['t']==$txt){
28559 if (!in_array($this->page
,$this->ktReference
[$i]['p'])) {
28560 $this->ktReference
[$i]['op'] = $this->page
;
28565 else if ($this->table_rotate
) {
28566 if (isset($this->tbrot_Reference
[$i]['t']) && $this->tbrot_Reference
[$i]['t']==$txt){
28568 if (!in_array($this->page
,$this->tbrot_Reference
[$i]['p'])) {
28569 $this->tbrot_Reference
[$i]['op'] = $this->page
;
28573 else if ($this->kwt
) {
28574 if (isset($this->kwt_Reference
[$i]['t']) && $this->kwt_Reference
[$i]['t']==$txt){
28576 if (!in_array($this->page
,$this->kwt_Reference
[$i]['p'])) {
28577 $this->kwt_Reference
[$i]['op'] = $this->page
;
28581 /*-- END TABLES --*/
28583 else if ($this->ColActive
) {
28584 if (isset($this->col_Reference
[$i]['t']) && $this->col_Reference
[$i]['t']==$txt){
28586 if (!in_array($this->page
,$this->col_Reference
[$i]['p'])) {
28587 $this->col_Reference
[$i]['op'] = $this->page
;
28591 /*-- END COLUMNS --*/
28593 if (isset($this->Reference
[$i]['t']) && $this->Reference
[$i]['t']==$txt){
28595 if (!in_array($this->page
,$this->Reference
[$i]['p'])) {
28596 $this->Reference
[$i]['p'][] = $this->page
;
28601 //If not found, add it
28603 $opr = array('t'=>$txt, 'op'=>$this->page
);
28604 if ($this->keep_block_together
) {
28605 $this->ktReference
[]= $opr;
28608 else if ($this->table_rotate
) {
28609 $this->tbrot_Reference
[]= $opr;
28611 else if ($this->kwt
) {
28612 $this->kwt_Reference
[]= $opr;
28614 /*-- END TABLES --*/
28616 else if ($this->ColActive
) {
28617 $this->col_Reference
[]= $opr;
28619 /*-- END COLUMNS --*/
28621 $this->Reference
[]=array('t'=>$txt,'p'=>array($this->page
));
28626 // Added function to add a reference "Elephants. See Chickens"
28627 function ReferenceSee($txta,$txtb) {
28628 $this->IndexEntrySee($txta,$txtb);
28631 function IndexEntrySee($txta,$txtb) {
28632 $txta = strip_tags($txta);
28633 $txtb = strip_tags($txtb);
28634 $txta = $this->purify_utf8_text($txta);
28635 $txtb = $this->purify_utf8_text($txtb);
28636 if ($this->text_input_as_HTML
) {
28637 $txta = $this->all_entities_to_utf8($txta);
28638 $txtb = $this->all_entities_to_utf8($txtb);
28640 if ($this->usingCoreFont
) {
28641 $txta = mb_convert_encoding($txta,$this->mb_enc
,'UTF-8');
28642 $txtb = mb_convert_encoding($txtb,$this->mb_enc
,'UTF-8');
28644 if ($this->directionality
== 'rtl') { // *RTL*
28645 $txta = str_replace(':',' - ',$txta); // *RTL*
28646 $txtb = str_replace(':',' - ',$txtb); // *RTL*
28649 $txta = str_replace(':',', ',$txta);
28650 $txtb = str_replace(':',', ',$txtb);
28652 $this->Reference
[]=array('t'=>$txta.' - see '.$txtb,'p'=>array());
28655 function CreateReference($NbCol=1, $reffontsize='', $linespacing='', $offset=3, $usedivletters=1, $divlettfontsize='', $gap=5, $reffont='',$divlettfont='', $useLinking=false) {
28656 $this->CreateIndex($NbCol, $reffontsize, $linespacing, $offset, $usedivletters, $divlettfontsize, $gap, $reffont, $divlettfont, $useLinking);
28659 function CreateIndex($NbCol=1, $reffontsize='', $linespacing='', $offset=3, $usedivletters=1, $divlettfontsize='', $gap=5, $reffont='',$divlettfont='', $useLinking=false) {
28660 if (!$reffontsize) { $reffontsize
= $this
->default_font_size
; }
28661 if (!$divlettfontsize) { $divlettfontsize
= ($this
->default_font_size
* 1.8); }
28662 if (!$reffont) { $reffont
= $this
->default_font
; }
28663 if (!$divlettfont) { $divlettfont
= $reffont
; }
28664 if (!$linespacing) { $linespacing
= $this
->default_lineheight_correction
; }
28665 if ($this->ColActive
) { $this
->SetColumns(0); } // *COLUMNS*
28666 $size=sizeof($this->Reference
);
28667 if ($size == 0) { return false; }
28672 $colWidth = $this->pgwidth
;
28675 $this->SetColumns($NbCol,'',$gap);
28676 $colWidth = $this->ColWidth
;
28678 if ($this->directionality
== 'rtl') { $align
= 'R'; }
28679 else { $align
= 'L'; }
28681 if (!function_exists('cmp')) {
28682 function cmp ($a, $b) {
28683 return strnatcmp(strtolower($a['t']), strtolower($b['t']));
28686 //Alphabetic sort of the references
28687 usort($this->Reference
, 'cmp');
28688 $size=sizeof($this->Reference
);
28689 $this->breakpoints
[$this->CurrCol
][] = $this->y
; // *COLUMNS*
28691 $divlettjuststarted = false;
28693 $this->OpenTag('DIV',array('STYLE'=>'line-height: '.$linespacing.'; font-family: '.$reffont.'; font-size: '.$reffontsize.'pt; '));
28696 for ($i=0;$i<$size;$i++
){
28697 if ($this->Reference
[$i]['t']) {
28698 if ($usedivletters) {
28700 $lett = mb_strtoupper(mb_substr($this->Reference
[$i]['t'],0,1,$this->mb_enc
),$this->mb_enc
);
28701 if ($lett != $last_lett) {
28703 $save_bp = $this->breakpoints
[$this->CurrCol
]; // *COLUMNS*
28704 $divlettjuststarted = true;
28707 $this->OpenTag('DIV',array('STYLE'=>'line-height: '.$linespacing.'; font-family: '.$divlettfont.'; font-size: '.$divlettfontsize.'pt; font-weight: bold; page-break-after: avoid; margin-top: 0.5em; margin-collapse: collapse; '));
28710 $this->OpenTag('DIV',array('STYLE'=>'line-height: '.$linespacing.'; font-family: '.$divlettfont.'; font-size: '.$divlettfontsize.'pt; font-weight: bold; page-break-after: avoid; '));
28712 $this->_saveTextBuffer($lett);
28713 $this->CloseTag('DIV');
28717 $this->OpenTag('DIV',array('STYLE'=>'text-indent: -'.$offset.'mm; line-height: '.$linespacing.'; font-family: '.$reffont.'; font-size: '.$reffontsize.'pt; '));
28720 // Change Arabic + Persian. to Presentation Forms
28721 if ($this->biDirectional
) {
28722 $this->Reference
[$i]['t'] = preg_replace("/([".$this->pregRTLchars
."]+)/ue", '$this->ArabJoin(stripslashes(\'\\1\'))', $this->Reference
[$i]['t'] );
28726 // Font-specific ligature substitution for Indic fonts
28727 if (isset($this->CurrentFont
['indic']) && $this->CurrentFont
['indic']) $this->ConvertIndic($this->Reference
[$i]['t']); // *INDIC*
28729 $this->_saveTextBuffer($this->Reference
[$i]['t']);
28730 $ppp = $this->Reference
[$i]['p']; // = array of page numbers to point to
28734 $range_start = $ppp[0];
28737 if (!$this->usingCoreFont
) { $spacer
= "\xc2\xa0 "; }
28738 else { $spacer
= chr(160).' '; }
28739 $this->_saveTextBuffer($spacer);
28740 if ($this->directionality
== 'rtl') { $sep
= '.'; $joiner
= '-'; }
28741 else { $sep
= ', '; $joiner
= '-'; }
28742 for ($zi=1;$zi<count($ppp);$zi++
) {
28743 // RTL - Each number separately
28744 if ($this->directionality
== 'rtl') {
28746 if ($zi<count($ppp)-1) {
28747 $txt = $sep . $this->docPageNum($ppp[$zi]);
28748 if ($useLinking) { $href
= '@'.$ppp
[$zi
]; }
28749 else { $href
= ''; }
28750 $this->_saveTextBuffer($txt, $href);
28755 else if ($ppp[$zi] == ($ppp[($zi-1)]+
1)) {
28756 $range_end = $ppp[$zi];
28760 if ($range_end == $range_start+
1) {
28761 if ($useLinking) { $href
= '@'.$range_start
; }
28762 else { $href
= ''; }
28763 $txt = $this->docPageNum($range_start) . $sep;
28764 $this->_saveTextBuffer($txt, $href);
28765 if ($useLinking) { $href
= '@'.$ppp
[$zi
-1]; }
28766 else { $href
= ''; }
28767 $txt = $this->docPageNum($ppp[$zi-1]) . $sep;
28768 $this->_saveTextBuffer($txt, $href);
28771 if ($useLinking) { $href
= '@'.$range_start
; }
28772 else { $href
= ''; }
28776 if ($useLinking) { $href
= '@'.$ppp
[$zi
-1]; }
28777 else { $href
= ''; }
28778 $txt = $this->docPageNum($ppp[$zi-1]) . $sep;
28779 $this->_saveTextBuffer($txt, $href);
28781 $range_start = $ppp[$zi];
28787 if ($range_end == $range_start+
1) {
28788 if ($useLinking) { $href
= '@'.$range_start
; }
28789 else { $href
= ''; }
28790 $txt = $this->docPageNum($range_start) . $sep;
28791 $this->_saveTextBuffer($txt, $href);
28792 if ($useLinking) { $href
= '@'.$range_end
; }
28793 else { $href
= ''; }
28794 $txt = $this->docPageNum($range_end);
28795 $this->_saveTextBuffer($txt, $href);
28798 if ($useLinking) { $href
= '@'.$range_start
; }
28799 else { $href
= ''; }
28800 $txt = $this->docPageNum($range_start) . $joiner;
28801 $this->_saveTextBuffer($txt, $href);
28802 if ($useLinking) { $href
= '@'.$range_end
; }
28803 else { $href
= ''; }
28804 $txt = $this->docPageNum($range_end);
28805 $this->_saveTextBuffer($txt, $href);
28809 if ($useLinking) { $href
= '@'.$ppp
[(count($ppp
)-1)]; }
28810 else { $href
= ''; }
28811 $txt = $this->docPageNum($ppp[(count($ppp)-1)]);
28812 $this->_saveTextBuffer($txt, $href);
28816 $this->CloseTag('DIV');
28818 if ($divlettjuststarted) { $this
->breakpoints
[$this
->CurrCol
] = $save_bp
; } // *COLUMNS*
28819 $divlettjuststarted = false;
28821 $this->breakpoints
[$this->CurrCol
][] = $this->y
; // *COLUMNS*
28822 $last_lett = $lett;
28824 $this->CloseTag('DIV');
28825 $this->breakpoints
[$this->CurrCol
][] = $this->y
; // *COLUMNS*
28826 if ($this->ColActive
) { $this
->SetColumns(0); } // *COLUMNS*
28828 /*-- END INDEX --*/
28831 function AcceptPageBreak() {
28832 if (count($this->cellBorderBuffer
)) { $this
->printcellbuffer(); } // *TABLES*
28834 if ($this->ColActive
==1) {
28835 if($this->CurrCol
<$this->NbCol
-1) {
28836 //Go to the next column
28838 $this->SetCol($this->CurrCol
);
28839 $this->y
=$this->y0
;
28840 $this->ChangeColumn
=1; // Number (and direction) of columns changed +1, +2, -2 etc.
28841 // DIRECTIONALITY RTL
28842 if ($this->directionality
== 'rtl') { $this
->ChangeColumn
= -($this
->ChangeColumn
); } // *RTL*
28848 //Go back to the first column - NEW PAGE
28849 if (count($this->columnbuffer
)) { $this
->printcolumnbuffer(); }
28851 $this->y0
= $this->tMargin
;
28852 $this->ChangeColumn
= -($this->NbCol
-1);
28853 // DIRECTIONALITY RTL
28854 if ($this->directionality
== 'rtl') { $this
->ChangeColumn
= -($this
->ChangeColumn
); } // *RTL*
28859 /*-- END COLUMNS --*/
28861 else if ($this->table_rotate
) {
28862 if ($this->tablebuffer
) { $this
->printtablebuffer(); }
28865 /*-- END TABLES --*/
28866 else { // *COLUMNS*
28867 $this->ChangeColumn
=0;
28868 return $this->autoPageBreak
;
28870 return $this->autoPageBreak
;
28874 //----------- COLUMNS ---------------------
28877 function SetColumns($NbCol,$vAlign='',$gap=5) {
28878 // NbCol = number of columns
28879 // CurrCol = Number of the current column starting at 0
28880 // Called externally to set columns on/off and number
28881 // Integer 2 upwards sets columns on to that number
28882 // Anything less than 2 turns columns off
28883 if ($NbCol<2) { // SET COLUMNS OFF
28884 if ($this->ColActive
) {
28885 $this->ColActive
=0;
28886 if (count($this->columnbuffer
)) { $this
->printcolumnbuffer(); }
28888 $this->ResetMargins();
28889 $this->pgwidth
= $this->w
- $this->lMargin
- $this->rMargin
;
28890 $this->divwidth
= 0;
28893 $this->ColActive
=0;
28894 $this->columnbuffer
= array();
28895 $this->ColDetails
= array();
28896 $this->columnLinks
= array();
28897 $this->columnAnnots
= array();
28898 $this->columnForms
= array();
28899 $this->col_Reference
= array();
28900 $this->col_BMoutlines
= array();
28901 $this->col_toc
= array();
28902 $this->breakpoints
= array();
28904 else { // SET COLUMNS ON
28905 if ($this->ColActive
) {
28906 $this->ColActive
=0;
28907 if (count($this->columnbuffer
)) { $this
->printcolumnbuffer(); }
28908 $this->ResetMargins();
28910 if (isset($this->y
) && $this->y
>$this->tMargin
) $this->Ln();
28911 $this->NbCol
=$NbCol;
28912 $this->ColGap
= $gap;
28913 $this->divwidth
= 0;
28914 $this->ColActive
=1;
28915 $this->ColumnAdjust
= true; // enables column height adjustment for the page
28916 $this->columnbuffer
= array();
28917 $this->ColDetails
= array();
28918 $this->columnLinks
= array();
28919 $this->columnAnnots
= array();
28920 $this->columnForms
= array();
28921 $this->col_Reference
= array();
28922 $this->col_BMoutlines
= array();
28923 $this->col_toc
= array();
28924 $this->breakpoints
= array();
28925 if ((strtoupper($vAlign) == 'J') || (strtoupper($vAlign) == 'JUSTIFY')) { $vAlign
= 'J'; }
28926 else { $vAlign
= ''; }
28927 $this->colvAlign
= $vAlign;
28928 //Save the ordinate
28929 $absL = $this->DeflMargin
-($gap/2);
28930 $absR = $this->DefrMargin
-($gap/2);
28931 $PageWidth = $this->w
-$absL-$absR; // virtual pagewidth for calculation only
28932 $ColWidth = (($PageWidth - ($gap * ($NbCol)))/$NbCol);
28933 $this->ColWidth
= $ColWidth;
28936 if ($this->directionality
== 'rtl') {
28937 for ($i=0;$i<$this->NbCol
;$i++
) {
28938 $this->ColL
[$i] = $absL +
($gap/2) +
(($NbCol - ($i+
1))*($PageWidth/$NbCol)) ;
28939 $this->ColR
[$i] = $this->ColL
[$i] +
$ColWidth; // NB This is not R margin -> R pos
28944 for ($i=0;$i<$this->NbCol
;$i++
) {
28945 $this->ColL
[$i] = $absL +
($gap/2) +
($i* ($PageWidth/$NbCol) );
28946 $this->ColR
[$i] = $this->ColL
[$i] +
$ColWidth; // NB This is not R margin -> R pos
28949 $this->pgwidth
= $ColWidth;
28951 $this->y0
=$this->y
;
28953 $this->x
= $this->lMargin
;
28956 function SetCol($CurrCol) {
28957 // Used internally to set column by number: 0 is 1st column
28958 //Set position on a column
28959 $this->CurrCol
=$CurrCol;
28960 $x = $this->ColL
[$CurrCol];
28961 $xR = $this->ColR
[$CurrCol]; // NB This is not R margin -> R pos
28962 if (($this->mirrorMargins
) && (($this->page
)%
2==0)) { // EVEN
28963 $x +
= $this->MarginCorrection
;
28964 $xR +
= $this->MarginCorrection
;
28966 $this->SetMargins($x,($this->w
- $xR),$this->tMargin
);
28969 function AddColumn() {
28970 $this->NewColumn();
28971 $this->ColumnAdjust
= false; // disables all column height adjustment for the page.
28973 function NewColumn() {
28974 if ($this->ColActive
==1) {
28975 if($this->CurrCol
<$this->NbCol
-1) {
28976 //Go to the next column
28978 $this->SetCol($this->CurrCol
);
28979 $this->y
= $this->y0
;
28980 $this->ChangeColumn
=1;
28981 // DIRECTIONALITY RTL
28982 if ($this->directionality
== 'rtl') { $this
->ChangeColumn
= -($this
->ChangeColumn
); } // *RTL*
28986 //Go back to the first column
28988 if (count($this->columnbuffer
)) { $this
->printcolumnbuffer(); }
28989 $this->AddPage($this->CurOrientation
);
28991 $this->y0
= $this->tMargin
;
28992 $this->ChangeColumn
= -($this->NbCol
-1);
28993 // DIRECTIONALITY RTL
28994 if ($this->directionality
== 'rtl') { $this
->ChangeColumn
= -($this
->ChangeColumn
); } // *RTL*
28996 $this->x
= $this->lMargin
;
28999 $this->AddPage($this->CurOrientation
);
29003 function printcolumnbuffer() {
29004 // Columns ended (but page not ended) -> try to match all columns - unless disabled by using a custom column-break
29005 if (!$this->ColActive
&& $this->ColumnAdjust
&& !$this->keepColumns
) {
29006 // Calculate adjustment to add to each column to calculate rel_y value
29007 $this->ColDetails
[0]['add_y'] = 0;
29009 // Recursively add previous column's height
29010 for($i=1;$i<$this->NbCol
;$i++
) {
29011 if (isset($this->ColDetails
[$i]['bottom_margin']) && $this->ColDetails
[$i]['bottom_margin']) { // If any entries in the column
29012 $this->ColDetails
[$i]['add_y'] = ($this->ColDetails
[$i-1]['bottom_margin'] - $this->y0
) +
$this->ColDetails
[$i-1]['add_y'];
29013 $last_col = $i; // Last column actually printed
29017 // Calculate value for each position sensitive entry as though for one column
29018 foreach($this->columnbuffer
AS $key=>$s) {
29020 if ($t == 'ACROFORM') {
29021 $this->columnbuffer
[$key]['rel_y'] = $s['y'] +
$this->ColDetails
[$s['col']]['add_y'] - $this->y0
;
29022 $this->columnbuffer
[$key]['s'] = '';
29024 else if (preg_match('/BT \d+\.\d\d+ (\d+\.\d\d+) Td/',$t)) {
29025 $this->columnbuffer
[$key]['rel_y'] = $s['y'] +
$this->ColDetails
[$s['col']]['add_y'] - $this->y0
;
29027 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/',$t)) {
29028 $this->columnbuffer
[$key]['rel_y'] = $s['y'] +
$this->ColDetails
[$s['col']]['add_y'] - $this->y0
;
29030 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) {
29031 $this->columnbuffer
[$key]['rel_y'] = $s['y'] +
$this->ColDetails
[$s['col']]['add_y'] - $this->y0
;
29033 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) {
29034 $this->columnbuffer
[$key]['rel_y'] = $s['y'] +
$this->ColDetails
[$s['col']]['add_y'] - $this->y0
;
29036 else if (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/',$t)) {
29037 $this->columnbuffer
[$key]['rel_y'] = $s['y'] +
$this->ColDetails
[$s['col']]['add_y'] - $this->y0
;
29039 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) {
29040 $this->columnbuffer
[$key]['rel_y'] = $s['y'] +
$this->ColDetails
[$s['col']]['add_y'] - $this->y0
;
29043 foreach($this->internallink
AS $key => $f) {
29044 if (is_array($f) && isset($f['col'])) {
29045 $this->internallink
[$key]['rel_y'] = $f['Y'] +
$this->ColDetails
[$f['col']]['add_y'] - $this->y0
;
29050 foreach($this->breakpoints
AS $c => $bpa) {
29051 foreach($bpa AS $rely) {
29052 $breaks[] = $rely +
$this->ColDetails
[$c]['add_y'] - $this->y0
;
29056 if (isset($this->ColDetails
[$last_col]['bottom_margin'])) { $lcbm
= $this
->ColDetails
[$last_col
]['bottom_margin']; }
29057 else { $lcbm
= 0; }
29058 $sum_h = $this->ColDetails
[$last_col]['add_y'] +
$lcbm - $this->y0
;
29059 //$sum_h = max($this->ColDetails[$last_col]['add_y'] + $this->ColDetails[$last_col]['bottom_margin'] - $this->y0, end($breaks));
29060 $target_h = ($sum_h / $this->NbCol
);
29063 for($i=1;$i<$this->NbCol
;$i++
) {
29064 $th = ($sum_h * $i / $this->NbCol
);
29065 foreach($breaks AS $bk=>$val) {
29067 if (($val-$th) < ($th-$breaks[$bk-1])) { $cbr
[$i
-1] = $val
; }
29068 else { $cbr
[$i
-1] = $breaks
[$bk
-1]; }
29073 $cbr[($this->NbCol
-1)] = $sum_h;
29075 // Now update the columns - divide into columns of approximately equal value
29079 $last_col_bottom = 0;
29080 $lowest_bottom_y = 0;
29083 foreach($this->columnbuffer
AS $key=>$s) {
29084 if (isset($s['rel_y'])) { // only process position sensitive data
29085 if ($s['rel_y'] >= $cbr[$newcolumn]) {
29089 $newcolumn = $last_new_col ;
29093 $block_bottom = max($block_bottom,($s['rel_y']+
$s['h']));
29095 if ($this->directionality
== 'rtl') { // *RTL*
29096 $xadj = -(($newcolumn - $s['col']) * ($this->ColWidth +
$this->ColGap
)); // *RTL*
29099 $xadj = ($newcolumn - $s['col']) * ($this->ColWidth +
$this->ColGap
);
29102 if ($last_new_col != $newcolumn) { // Added new column
29103 $last_col_bottom = $this->columnbuffer
[$key]['rel_y'];
29106 $yadj = ($s['rel_y'] - $s['y']) - ($last_col_bottom)+
$this->y0
;
29107 // callback function
29109 $t = preg_replace('/BT (\d+\.\d\d+) (\d+\.\d\d+) Td/e',"\$this->columnAdjustAdd('Td',_MPDFK,$xadj,$yadj,'\\1','\\2')",$t);
29110 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) ([\-]{0,1}\d+\.\d\d+) re/e',"\$this->columnAdjustAdd('re',_MPDFK,$xadj,$yadj,'\\1','\\2','\\3','\\4')",$t);
29111 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) l/e',"\$this->columnAdjustAdd('l',_MPDFK,$xadj,$yadj,'\\1','\\2')",$t);
29112 $t = preg_replace('/q (\d+\.\d\d+) 0 0 (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) cm \/(I|FO)/e',"\$this->columnAdjustAdd('img',_MPDFK,$xadj,$yadj,'\\1','\\2','\\3','\\4','\\5')",$t);
29113 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) m/e',"\$this->columnAdjustAdd('draw',_MPDFK,$xadj,$yadj,'\\1','\\2')",$t);
29114 $t = preg_replace('/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) c/e',"\$this->columnAdjustAdd('bezier',_MPDFK,$xadj,$yadj,'\\1','\\2','\\3','\\4','\\5','\\6')",$t);
29116 $this->columnbuffer
[$key]['s'] = $t;
29117 $this->columnbuffer
[$key]['newcol'] = $newcolumn;
29118 $this->columnbuffer
[$key]['newy'] = $s['y'] +
$yadj;
29119 $last_new_col = $newcolumn;
29120 $clb = $s['y'] +
$yadj +
$s['h'] ; // bottom_margin of current
29121 if ((isset($this->ColDetails
[$newcolumn]['max_bottom']) && $clb > $this->ColDetails
[$newcolumn]['max_bottom']) || (!isset($this->ColDetails
[$newcolumn]['max_bottom']) && $clb)) { $this
->ColDetails
[$newcolumn
]['max_bottom'] = $clb
; }
29122 if ($clb > $lowest_bottom_y) { $lowest_bottom_y
= $clb
; }
29124 if (isset($this->columnLinks
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29125 $ref = $this->columnLinks
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29126 $this->PageLinks
[$this->page
][$ref][0] +
= ($xadj*_MPDFK
);
29127 $this->PageLinks
[$this->page
][$ref][1] -= ($yadj*_MPDFK
);
29128 unset($this->columnLinks
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29130 // Adjust FORM FIELDS
29131 if (isset($this->columnForms
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29132 $ref = $this->columnForms
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29133 $this->form
->forms
[$ref]['x'] +
= ($xadj);
29134 $this->form
->forms
[$ref]['y'] +
= ($yadj);
29135 unset($this->columnForms
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29137 /*-- ANNOTATIONS --*/
29138 if (isset($this->columnAnnots
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29139 $ref = $this->columnAnnots
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29140 if ($this->PageAnnots
[$this->page
][$ref]['x'] < 0) {
29141 $this->PageAnnots
[$this->page
][$ref]['x'] -= ($xadj);
29144 $this->PageAnnots
[$this->page
][$ref]['x'] +
= ($xadj);
29146 $this->PageAnnots
[$this->page
][$ref]['y'] +
= ($yadj); // unlike PageLinks, Page annots has y values from top in mm
29147 unset($this->columnAnnots
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29149 /*-- END ANNOTATIONS --*/
29153 /*-- BOOKMARKS --*/
29154 // Adjust Bookmarks
29155 foreach($this->col_BMoutlines
AS $v) {
29156 $this->BMoutlines
[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$this->y0
,'p'=>$v['p']);
29158 /*-- END BOOKMARKS --*/
29161 // Adjust Reference (index)
29162 foreach($this->col_Reference
AS $v) {
29164 //Search the reference (AND Ref/PageNo) in the array
29165 for ($i=0;$i<count($this->Reference
);$i++
){
29166 if ($this->Reference
[$i]['t']==$v['t']){
29168 if (!in_array($v['op'],$this->Reference
[$i]['p'])) {
29169 $this->Reference
[$i]['p'][] = $v['op'];
29174 $this->Reference
[]=array('t'=>$v['t'],'p'=>array($v['op']));
29177 /*-- END INDEX --*/
29182 foreach($this->col_toc
AS $v) {
29183 $this->tocontents
->_toc
[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29184 $this->links
[$v['link']][1] = $this->y0
;
29188 // Adjust column length to be equal
29189 if ($this->colvAlign
== 'J') {
29190 foreach($this->columnbuffer
AS $key=>$s) {
29191 if (isset($s['rel_y'])) { // only process position sensitive data
29192 // Set ratio to expand y values or heights
29193 if (isset($this->ColDetails
[$s['newcol']]['max_bottom']) && $this->ColDetails
[$s['newcol']]['max_bottom'] && $this->ColDetails
[$s['newcol']]['max_bottom']!=$this->y0
) {
29194 $ratio = ($lowest_bottom_y - ($this->y0
)) / ($this->ColDetails
[$s['newcol']]['max_bottom'] - ($this->y0
));
29196 else { $ratio
= 1; }
29197 if (($ratio > 1) && ($ratio <= $this->max_colH_correction
)) {
29198 $yadj = ($s['newy'] - $this->y0
) * ($ratio - 1);
29201 if (isset($this->columnLinks
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29202 $ref = $this->columnLinks
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29203 $this->PageLinks
[$this->page
][$ref][1] -= ($yadj*_MPDFK
); // y value
29204 $this->PageLinks
[$this->page
][$ref][3] *= $ratio; // height
29205 unset($this->columnLinks
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29207 // Adjust FORM FIELDS
29208 if (isset($this->columnForms
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29209 $ref = $this->columnForms
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29210 $this->form
->forms
[$ref]['x'] +
= ($xadj);
29211 $this->form
->forms
[$ref]['y'] +
= ($yadj);
29212 unset($this->columnForms
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29214 /*-- ANNOTATIONS --*/
29215 if (isset($this->columnAnnots
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29216 $ref = $this->columnAnnots
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29217 $this->PageAnnots
[$this->page
][$ref]['y'] +
= ($yadj);
29218 unset($this->columnAnnots
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29220 /*-- END ANNOTATIONS --*/
29224 foreach($this->internallink
AS $key => $f) {
29225 if (is_array($f) && isset($f['col'])) {
29226 $last_col_bottom = 0;
29227 for ($nbc=0; $nbc<$this->NbCol
; $nbc++
) {
29228 if ($f['rel_y'] >= $cbr[$nbc]) { $last_col_bottom
= $cbr
[$nbc
]; }
29230 $yadj = ($f['rel_y'] - $f['Y']) - $last_col_bottom +
$this->y0
;
29233 unset($f['rel_y']);
29234 $this->internallink
[$key] = $f;
29240 foreach($this->columnbuffer
AS $key=>$s) {
29241 if (isset($s['rel_y'])) { // only process position sensitive data
29242 // Set ratio to expand y values or heights
29243 if (isset($this->ColDetails
[$s['newcol']]['max_bottom']) && $this->ColDetails
[$s['newcol']]['max_bottom'] && $this->ColDetails
[$s['newcol']]['max_bottom']!=$this->y0
) {
29244 $ratio = ($lowest_bottom_y - ($this->y0
)) / ($this->ColDetails
[$s['newcol']]['max_bottom'] - ($this->y0
));
29246 else { $ratio
= 1; }
29247 if (($ratio > 1) && ($ratio <= $this->max_colH_correction
)) {
29248 //Start Transformation
29249 $this->pages
[$this->page
] .= $this->StartTransform(true)."\n";
29250 $this->pages
[$this->page
] .= $this->transformScale(100, $ratio*100, $x='', $this->y0
, true)."\n";
29254 // Now output the adjusted values
29255 $this->pages
[$this->page
] .= $s['s']."\n";
29256 if (isset($s['rel_y']) && ($ratio > 1) && ($ratio <= $this->max_colH_correction
)) { // only process position sensitive data
29257 //Stop Transformation
29258 $this->pages
[$this->page
] .= $this->StopTransform(true)."\n";
29262 if ($trans_on) { $this
->pages
[$this
->page
] .= $this
->StopTransform(true)."\n"; }
29264 else { // if NOT $this->colvAlign == 'J'
29265 // Now output the adjusted values
29266 foreach($this->columnbuffer
AS $s) {
29267 $this->pages
[$this->page
] .= $s['s']."\n";
29270 if ($lowest_bottom_y > 0) { $this
->y
= $lowest_bottom_y
; }
29273 // Columns not ended but new page -> align columns (can leave the columns alone - just tidy up the height)
29274 else if ($this->colvAlign
== 'J' && $this->ColumnAdjust
&& !$this->keepColumns
) {
29275 // calculate the lowest bottom margin
29276 $lowest_bottom_y = 0;
29277 foreach($this->columnbuffer
AS $key=>$s) {
29278 // Only process output data
29280 if ($t == 'ACROFORM' || (preg_match('/BT \d+\.\d\d+ (\d+\.\d\d+) Td/',$t)) || (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/',$t)) ||
29281 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) ||
29282 (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/',$t)) ||
29283 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) ||
29284 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) ) {
29286 $clb = $s['y'] +
$s['h'];
29287 if ((isset($this->ColDetails
[$s['col']]['max_bottom']) && $clb > $this->ColDetails
[$s['col']]['max_bottom']) || !isset($this->ColDetails
[$s['col']]['max_bottom'])) { $this
->ColDetails
[$s
['col']]['max_bottom'] = $clb
; }
29288 if ($clb > $lowest_bottom_y) { $lowest_bottom_y
= $clb
; }
29289 $this->columnbuffer
[$key]['rel_y'] = $s['y']; // Marks position sensitive data to process later
29290 if ($t == 'ACROFORM') { $this
->columnbuffer
[$key
]['s'] = ''; }
29293 // Adjust column length equal
29294 foreach($this->columnbuffer
AS $key=>$s) {
29295 // Set ratio to expand y values or heights
29296 if (isset($this->ColDetails
[$s['col']]['max_bottom']) && $this->ColDetails
[$s['col']]['max_bottom']) {
29297 $ratio = ($lowest_bottom_y - ($this->y0
)) / ($this->ColDetails
[$s['col']]['max_bottom'] - ($this->y0
));
29299 else { $ratio
= 1; }
29300 if (($ratio > 1) && ($ratio <= $this->max_colH_correction
)) {
29301 $yadj = ($s['y'] - $this->y0
) * ($ratio - 1);
29304 if (isset($s['rel_y'])) { // only process position sensitive data
29305 // otherwise triggers for all entries in column buffer (.e.g. formatting) and makes below adjustments more than once
29306 if (isset($this->columnLinks
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29307 $ref = $this->columnLinks
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29308 $this->PageLinks
[$this->page
][$ref][1] -= ($yadj*_MPDFK
); // y value
29309 $this->PageLinks
[$this->page
][$ref][3] *= $ratio; // height
29310 unset($this->columnLinks
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29312 // Adjust FORM FIELDS
29313 if (isset($this->columnForms
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29314 $ref = $this->columnForms
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29315 $this->form
->forms
[$ref]['x'] +
= ($xadj);
29316 $this->form
->forms
[$ref]['y'] +
= ($yadj);
29317 unset($this->columnForms
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29319 /*-- ANNOTATIONS --*/
29320 if (isset($this->columnAnnots
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29321 $ref = $this->columnAnnots
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29322 $this->PageAnnots
[$this->page
][$ref]['y'] +
= ($yadj);
29323 unset($this->columnAnnots
[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29325 /*-- END ANNOTATIONS --*/
29330 /*-- BOOKMARKS --*/
29332 // Adjust Bookmarks
29333 foreach($this->col_BMoutlines
AS $v) {
29334 $this->BMoutlines
[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$this->y0
,'p'=>$v['p']);
29336 /*-- END BOOKMARKS --*/
29340 // Adjust Reference (index)
29341 foreach($this->col_Reference
AS $v) {
29343 //Search the reference (AND Ref/PageNo) in the array
29344 for ($i=0;$i<count($this->Reference
);$i++
){
29345 if ($this->Reference
[$i]['t']==$v['t']){
29347 if (!in_array($v['op'],$this->Reference
[$i]['p'])) {
29348 $this->Reference
[$i]['p'][] = $v['op'];
29353 $this->Reference
[]=array('t'=>$v['t'],'p'=>array($v['op']));
29356 /*-- END INDEX --*/
29361 foreach($this->col_toc
AS $v) {
29362 $this->tocontents
->_toc
[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29363 $this->links
[$v['link']][1] = $this->y0
;
29367 foreach($this->columnbuffer
AS $key=>$s) {
29368 if (isset($s['rel_y'])) { // only process position sensitive data
29369 // Set ratio to expand y values or heights
29370 if ($this->ColDetails
[$s['col']]['max_bottom']) {
29371 $ratio = ($lowest_bottom_y - ($this->y0
)) / ($this->ColDetails
[$s['col']]['max_bottom'] - ($this->y0
));
29373 else { $ratio
= 1; }
29374 if (($ratio > 1) && ($ratio <= $this->max_colH_correction
)) {
29375 //Start Transformation
29376 $this->pages
[$this->page
] .= $this->StartTransform(true)."\n";
29377 $this->pages
[$this->page
] .= $this->transformScale(100, $ratio*100, $x='', $this->y0
, true)."\n";
29381 // Now output the adjusted values
29382 $this->pages
[$this->page
] .= $s['s']."\n";
29383 if (isset($s['rel_y']) && ($ratio > 1) && ($ratio <= $this->max_colH_correction
)) {
29384 //Stop Transformation
29385 $this->pages
[$this->page
] .= $this->StopTransform(true)."\n";
29386 $trans_on = false; // mPDF 5.1.001
29389 if ($trans_on) { $this
->pages
[$this
->page
] .= $this
->StopTransform(true)."\n"; }
29391 if ($lowest_bottom_y > 0) { $this
->y
= $lowest_bottom_y
; }
29395 // Just reproduce the page as it was
29397 // If page has not ended but height adjustment was disabled by custom column-break - adjust y
29398 $lowest_bottom_y = 0;
29399 if (!$this->ColActive
&& (!$this->ColumnAdjust
|| $this->keepColumns
)) {
29400 // calculate the lowest bottom margin
29401 foreach($this->columnbuffer
AS $key=>$s) {
29402 // Only process output data
29404 if ($t == 'ACROFORM' || (preg_match('/BT \d+\.\d\d+ (\d+\.\d\d+) Td/',$t)) || (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/',$t)) ||
29405 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) ||
29406 (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/',$t)) ||
29407 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) ||
29408 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) ) {
29410 $clb = $s['y'] +
$s['h'];
29411 if ($clb > $this->ColDetails
[$s['col']]['max_bottom']) { $this
->ColDetails
[$s
['col']]['max_bottom'] = $clb
; }
29412 if ($clb > $lowest_bottom_y) { $lowest_bottom_y
= $clb
; }
29416 foreach($this->columnbuffer
AS $key=>$s) {
29417 if ($s['s'] != 'ACROFORM')
29418 $this->pages
[$this->page
] .= $s['s']."\n";
29420 if ($lowest_bottom_y > 0) { $this
->y
= $lowest_bottom_y
; }
29423 // Output Reference (index)
29424 foreach($this->col_Reference
AS $v) {
29426 for ($i=0;$i<count($this->Reference
);$i++
){
29427 if ($this->Reference
[$i]['t']==$v['t']){
29429 if (!in_array($v['op'],$this->Reference
[$i]['p'])) {
29430 $this->Reference
[$i]['p'][] = $v['op'];
29435 $this->Reference
[]=array('t'=>$v['t'],'p'=>array($v['op']));
29438 /*-- END INDEX --*/
29439 /*-- BOOKMARKS --*/
29440 // Output Bookmarks
29441 foreach($this->col_BMoutlines
AS $v) {
29442 $this->BMoutlines
[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29444 /*-- END BOOKMARKS --*/
29447 foreach($this->col_toc
AS $v) {
29448 $this->tocontents
->_toc
[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29452 foreach($this->internallink
AS $key => $f) {
29453 if (isset($this->internallink
[$key]['col'])) unset($this->internallink
[$key]['col']);
29454 if (isset($this->internallink
[$key]['rel_y'])) unset($this->internallink
[$key]['rel_y']);
29457 $this->columnbuffer
= array();
29458 $this->ColDetails
= array();
29459 $this->columnLinks
= array();
29460 $this->columnAnnots
= array();
29461 $this->columnForms
= array();
29463 $this->col_Reference
= array();
29464 $this->col_BMoutlines
= array();
29465 $this->col_toc
= array();
29466 $this->breakpoints
= array();
29469 /*-- END COLUMNS --*/
29472 //==================================================================
29474 function printcellbuffer() {
29475 if (count($this->cellBorderBuffer
)) {
29476 sort($this->cellBorderBuffer
);
29477 foreach($this->cellBorderBuffer
AS $cbb) {
29478 $cba = unpack("A16dom/nbord/A1side/ns/dbw/a6ca/A10style/dx/dy/dw/dh/dmbl/dmbr/dmrt/dmrb/dmtl/dmtr/dmlt/dmlb/dcpd/dover/", $cbb);
29479 $side = $cba['side'];
29480 $details = array();
29481 $details[$side]['dom'] = (float) $cba['dom'];
29482 $details[$side]['s'] = $cba['s'];
29483 $details[$side]['w'] = $cba['bw'];
29484 $details[$side]['c'] = $cba['ca'];
29485 $details[$side]['style'] = trim($cba['style']);
29486 $details['mbw']['BL'] = $cba['mbl'];
29487 $details['mbw']['BR'] = $cba['mbr'];
29488 $details['mbw']['RT'] = $cba['mrt'];
29489 $details['mbw']['RB'] = $cba['mrb'];
29490 $details['mbw']['TL'] = $cba['mtl'];
29491 $details['mbw']['TR'] = $cba['mtr'];
29492 $details['mbw']['LT'] = $cba['mlt'];
29493 $details['mbw']['LB'] = $cba['mlb'];
29494 $details['cellposdom'] = $cba['cpd'];
29495 $details['p'] = $side;
29496 if ($cba['over']==1) { $details
[$side
]['overlay'] = true; }
29497 else { $details
[$side
]['overlay'] = false; }
29498 $this->_tableRect($cba['x'],$cba['y'],$cba['w'],$cba['h'],$cba['bord'],$details, false, false);
29501 $this->cellBorderBuffer
= array();
29504 //==================================================================
29505 function printtablebuffer() {
29507 if (!$this->table_rotate
) {
29508 $this->pages
[$this->page
] .= $this->tablebuffer
;
29509 foreach($this->tbrot_Links
AS $p => $l) {
29510 foreach($l AS $v) {
29511 $this->PageLinks
[$p][] = $v;
29514 $this->tbrot_Links
= array();
29515 /*-- ANNOTATIONS --*/
29516 foreach($this->tbrot_Annots
AS $p => $l) {
29517 foreach($l AS $v) {
29518 $this->PageAnnots
[$p][] = $v;
29521 $this->tbrot_Annots
= array();
29522 /*-- END ANNOTATIONS --*/
29525 // Output Reference (index)
29526 foreach($this->tbrot_Reference
AS $v) {
29528 for ($i=0;$i<count($this->Reference
);$i++
){
29529 if ($this->Reference
[$i]['t']==$v['t']){
29531 if (!in_array($v['op'],$this->Reference
[$i]['p'])) {
29532 $this->Reference
[$i]['p'][] = $v['op'];
29537 $this->Reference
[]=array('t'=>$v['t'],'p'=>array($v['op']));
29540 $this->tbrot_Reference
= array();
29541 /*-- END INDEX --*/
29543 /*-- BOOKMARKS --*/
29544 // Output Bookmarks
29545 foreach($this->tbrot_BMoutlines
AS $v) {
29546 $this->BMoutlines
[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29548 $this->tbrot_BMoutlines
= array();
29549 /*-- END BOOKMARKS --*/
29553 foreach($this->tbrot_toc
AS $v) {
29554 $this->tocontents
->_toc
[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29556 $this->tbrot_toc
= array();
29562 $lm = $this->lMargin +
$this->blk
[$this->blklvl
]['outer_left_margin'] +
$this->blk
[$this->blklvl
]['border_left']['w'] +
$this->blk
[$this->blklvl
]['padding_left'];
29563 $pw = $this->blk
[$this->blklvl
]['inner_width'];
29564 //Start Transformation
29565 $this->pages
[$this->page
] .= $this->StartTransform(true)."\n";
29567 if ($this->table_rotate
> 1) { // clockwise
29568 if ($this->tbrot_align
== 'L') {
29569 $xadj = $this->tbrot_h
; // align L (as is)
29571 else if ($this->tbrot_align
== 'R') {
29572 $xadj = $lm-$this->tbrot_x0+
($pw) ; // align R
29575 $xadj = $lm-$this->tbrot_x0+
(($pw +
$this->tbrot_h
)/2) ; // align C
29579 else { // anti-clockwise
29580 if ($this->tbrot_align
== 'L') {
29581 $xadj = 0 ; // align L (as is)
29583 else if ($this->tbrot_align
== 'R') {
29584 $xadj = $lm-$this->tbrot_x0+
($pw - $this->tbrot_h
) ; // align R
29587 $xadj = $lm-$this->tbrot_x0+
(($pw - $this->tbrot_h
)/2) ; // align C
29589 $yadj = $this->tbrot_w
;
29593 $this->pages
[$this->page
] .= $this->transformTranslate($xadj, $yadj , true)."\n";
29594 $this->pages
[$this->page
] .= $this->transformRotate($this->table_rotate
, $this->tbrot_x0
, $this->tbrot_y0
, true)."\n";
29596 // Now output the adjusted values
29597 $this->pages
[$this->page
] .= $this->tablebuffer
;
29600 foreach($this->tbrot_Links
AS $p => $l) {
29601 foreach($l AS $v) {
29604 $ax = ($v[0]/_MPDFK
) - $this->tbrot_x0
;
29605 $ay = (($this->hPt
-$v[1])/_MPDFK
) - $this->tbrot_y0
;
29606 if ($this->table_rotate
> 1) { // clockwise
29607 $bx = $this->tbrot_x0+
$xadj-$ay-$h;
29608 $by = $this->tbrot_y0+
$yadj+
$ax;
29611 $bx = $this->tbrot_x0+
$xadj+
$ay;
29612 $by = $this->tbrot_y0+
$yadj-$ax-$w;
29614 $v[0] = $bx*_MPDFK
;
29615 $v[1] = ($this->h
-$by)*_MPDFK
;
29616 $v[2] = $h*_MPDFK
; // swap width and height
29618 $this->PageLinks
[$p][] = $v;
29621 $this->tbrot_Links
= array();
29622 foreach($this->internallink
AS $key => $f) {
29623 if (is_array($f) && isset($f['tbrot'])) {
29624 $f['Y'] = $this->tbrot_y0
;
29625 $f['PAGE'] = $this->page
;
29626 unset($f['tbrot']);
29627 $this->internallink
[$key] = $f;
29630 /*-- ANNOTATIONS --*/
29631 foreach($this->tbrot_Annots
AS $p => $l) {
29632 foreach($l AS $v) {
29633 $ax = abs($v['x']) - $this->tbrot_x0
; // abs because -ve values are internally set and held for reference if annotMargin set
29634 $ay = $v['y'] - $this->tbrot_y0
;
29635 if ($this->table_rotate
> 1) { // clockwise
29636 $bx = $this->tbrot_x0+
$xadj-$ay;
29637 $by = $this->tbrot_y0+
$yadj+
$ax;
29640 $bx = $this->tbrot_x0+
$xadj+
$ay;
29641 $by = $this->tbrot_y0+
$yadj-$ax;
29650 $this->PageAnnots
[$p][] = $v;
29653 $this->tbrot_Annots
= array();
29654 /*-- END ANNOTATIONS --*/
29657 /*-- BOOKMARKS --*/
29659 // Adjust Bookmarks
29660 foreach($this->tbrot_BMoutlines
AS $v) {
29661 $v['y'] = $this->tbrot_y0
;
29662 $this->BMoutlines
[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$this->page
);
29664 /*-- END BOOKMARKS --*/
29668 // Adjust Reference (index)
29669 foreach($this->tbrot_Reference
AS $v) {
29671 //Search the reference (AND Ref/PageNo) in the array
29672 for ($i=0;$i<count($this->Reference
);$i++
){
29673 if ($this->Reference
[$i]['t']==$v['t']){
29675 if (!in_array($this->page
,$this->Reference
[$i]['p'])) {
29676 $this->Reference
[$i]['p'][] = $this->page
;
29681 $this->Reference
[]=array('t'=>$v['t'],'p'=>array($this->page
));
29684 /*-- END INDEX --*/
29688 // Adjust ToC - uses document page number
29689 foreach($this->tbrot_toc
AS $v) {
29690 $this->tocontents
->_toc
[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$this->page
,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29691 $this->links
[$v['link']][1] = $this->tbrot_y0
;
29697 $this->tbrot_Reference
= array();
29698 $this->tbrot_BMoutlines
= array();
29699 $this->tbrot_toc
= array();
29701 //Stop Transformation
29702 $this->pages
[$this->page
] .= $this->StopTransform(true)."\n";
29705 $this->y
= $this->tbrot_y0 +
$this->tbrot_w
;
29706 $this->x
= $this->lMargin
;
29708 $this->tablebuffer
= '';
29711 //==================================================================
29712 // Keep-with-table This buffers contents of h1-6 to keep on page with table
29713 function printkwtbuffer() {
29714 if (!$this->kwt_moved
) {
29715 foreach($this->kwt_buffer
AS $s) { $this
->pages
[$this
->page
] .= $s
['s']."\n"; }
29716 foreach($this->kwt_Links
AS $p => $l) {
29717 foreach($l AS $v) {
29718 $this->PageLinks
[$p][] = $v;
29721 $this->kwt_Links
= array();
29722 /*-- ANNOTATIONS --*/
29723 foreach($this->kwt_Annots
AS $p => $l) {
29724 foreach($l AS $v) {
29725 $this->PageAnnots
[$p][] = $v;
29728 $this->kwt_Annots
= array();
29729 /*-- END ANNOTATIONS --*/
29732 // Output Reference (index)
29733 foreach($this->kwt_Reference
AS $v) {
29735 for ($i=0;$i<count($this->Reference
);$i++
){
29736 if ($this->Reference
[$i]['t']==$v['t']){
29738 if (!in_array($v['op'],$this->Reference
[$i]['p'])) {
29739 $this->Reference
[$i]['p'][] = $v['op'];
29744 $this->Reference
[]=array('t'=>$v['t'],'p'=>array($v['op']));
29747 $this->kwt_Reference
= array();
29748 /*-- END INDEX --*/
29750 /*-- BOOKMARKS --*/
29751 // Output Bookmarks
29752 foreach($this->kwt_BMoutlines
AS $v) {
29753 $this->BMoutlines
[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29755 $this->kwt_BMoutlines
= array();
29756 /*-- END BOOKMARKS --*/
29760 foreach($this->kwt_toc
AS $v) {
29761 $this->tocontents
->_toc
[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29763 $this->kwt_toc
= array();
29769 //Start Transformation
29770 $this->pages
[$this->page
] .= $this->StartTransform(true)."\n";
29771 $xadj = $this->lMargin
- $this->kwt_x0
;
29772 //$yadj = $this->y - $this->kwt_y0 ;
29773 $yadj = $this->tMargin
- $this->kwt_y0
;
29775 $this->pages
[$this->page
] .= $this->transformTranslate($xadj, $yadj , true)."\n";
29777 // Now output the adjusted values
29778 foreach($this->kwt_buffer
AS $s) { $this
->pages
[$this
->page
] .= $s
['s']."\n"; }
29780 // Adjust hyperLinks
29781 foreach($this->kwt_Links
AS $p => $l) {
29782 foreach($l AS $v) {
29783 $bx = $this->kwt_x0+
$xadj;
29784 $by = $this->kwt_y0+
$yadj;
29785 $v[0] = $bx*_MPDFK
;
29786 $v[1] = ($this->h
-$by)*_MPDFK
;
29787 $this->PageLinks
[$p][] = $v;
29790 foreach($this->internallink
AS $key => $f) {
29791 if (is_array($f) && isset($f['kwt'])) {
29793 $f['PAGE'] = $this->page
;
29795 $this->internallink
[$key] = $f;
29798 /*-- ANNOTATIONS --*/
29799 foreach($this->kwt_Annots
AS $p => $l) {
29800 foreach($l AS $v) {
29801 $bx = $this->kwt_x0+
$xadj;
29802 $by = $this->kwt_y0+
$yadj;
29810 $this->PageAnnots
[$p][] = $v;
29813 /*-- END ANNOTATIONS --*/
29815 /*-- BOOKMARKS --*/
29817 // Adjust Bookmarks
29818 foreach($this->kwt_BMoutlines
AS $v) {
29819 if ($v['y'] != 0) { $v
['y'] +
= $yadj
; }
29820 $this->BMoutlines
[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$this->page
);
29822 /*-- END BOOKMARKS --*/
29826 // Adjust Reference (index)
29827 foreach($this->kwt_Reference
AS $v) {
29829 //Search the reference (AND Ref/PageNo) in the array
29830 for ($i=0;$i<count($this->Reference
);$i++
){
29831 if ($this->Reference
[$i]['t']==$v['t']){
29833 if (!in_array($this->page
,$this->Reference
[$i]['p'])) {
29834 $this->Reference
[$i]['p'][] = $this->page
;
29839 $this->Reference
[]=array('t'=>$v['t'],'p'=>array($this->page
));
29842 /*-- END INDEX --*/
29847 foreach($this->kwt_toc
AS $v) {
29848 $this->tocontents
->_toc
[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$this->page
,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29849 $this->links
[$v['link']][0] = $this->page
;
29850 $this->links
[$v['link']][1] +
= $yadj;
29855 $this->kwt_Links
= array();
29856 $this->kwt_Annots
= array();
29858 $this->kwt_Reference
= array();
29859 $this->kwt_BMoutlines
= array();
29860 $this->kwt_toc
= array();
29861 //Stop Transformation
29862 $this->pages
[$this->page
] .= $this->StopTransform(true)."\n";
29864 $this->kwt_buffer
= array();
29866 $this->y +
= $this->kwt_height
;
29869 /*-- END TABLES --*/
29872 //==================================================================
29874 function printfloatbuffer() {
29875 if (count($this->floatbuffer
)) {
29876 $this->objectbuffer
= $this->floatbuffer
;
29877 $this->printobjectbuffer(false);
29878 $this->objectbuffer
= array();
29879 $this->floatbuffer
= array();
29880 $this->floatmargins
= array();
29883 //==================================================================
29885 function printdivbuffer() {
29886 $p1 = $this->blk
[$this->blklvl
]['startpage'];
29888 $bottom[$p1] = $this->ktBlock
[$p1]['bottom_margin'];
29889 $bottom[$p2] = $this->y
; // $this->ktBlock[$p2]['bottom_margin'];
29890 $top[$p1] = $this->kt_y00
;
29893 foreach($this->divbuffer
AS $key=>$s) {
29894 if ($s['page'] == $p2) {
29895 $top2 = MIN($s['y'], $top2);
29899 $height[$p1] = ($bottom[$p1] - $top[$p1]);
29900 $height[$p2] = ($bottom[$p2] - $top[$p2]);
29901 $xadj[$p1] = $this->MarginCorrection
;
29902 $yadj[$p1] = -($top[$p1] - $top[$p2]);
29904 $yadj[$p2] = $height[$p1];
29906 // Output without any transformation
29907 if ($this->ColActive
|| !$this->keep_block_together
|| $this->blk
[$this->blklvl
]['startpage'] == $this->page
|| ($this->page
- $this->blk
[$this->blklvl
]['startpage']) > 1 || ($height[$p1]+
$height[$p2]) > $this->h
) {
29908 foreach($this->divbuffer
AS $s) { $this
->pages
[$s
['page']] .= $s
['s']."\n"; }
29909 foreach($this->ktLinks
AS $p => $l) {
29910 foreach($l AS $v) {
29911 $this->PageLinks
[$p][] = $v;
29914 foreach($this->ktForms
AS $key => $f) {
29915 $this->form
->forms
[$f['n']] = $f;
29917 /*-- ANNOTATIONS --*/
29918 foreach($this->ktAnnots
AS $p => $l) {
29919 foreach($l AS $v) {
29920 $this->PageAnnots
[$p][] = $v;
29923 /*-- END ANNOTATIONS --*/
29925 // Adjust Reference (index)
29926 foreach($this->ktReference
AS $v) {
29928 //Search the reference (AND Ref/PageNo) in the array
29929 for ($i=0;$i<count($this->Reference
);$i++
){
29930 if ($this->Reference
[$i]['t']==$v['t']){
29932 if (!in_array($p2,$this->Reference
[$i]['p'])) {
29933 $this->Reference
[$i]['p'][] = $p2;
29937 //If not found, add it
29939 $this->Reference
[]=array('t'=>$v['t'],'p'=>array($p2));
29942 /*-- END INDEX --*/
29944 /*-- BOOKMARKS --*/
29945 // Adjust Bookmarks
29946 foreach($this->ktBMoutlines
AS $v) {
29947 $this->BMoutlines
[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29949 /*-- END BOOKMARKS --*/
29953 foreach($this->_kttoc
AS $v) {
29954 $this->tocontents
->_toc
[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29958 $this->divbuffer
= array();
29959 $this->ktLinks
= array();
29960 $this->ktAnnots
= array();
29961 $this->ktForms
= array();
29962 $this->ktBlock
= array();
29963 $this->ktReference
= array();
29964 $this->ktBMoutlines
= array();
29965 $this->_kttoc
= array();
29966 $this->keep_block_together
= 0;
29970 // Output with transformation
29974 foreach($this->divbuffer
AS $key=>$s) {
29975 // callback function
29978 if ($p != $lastpage) {
29980 if ($lastpage != -1) { $q
= ' Q'."\n"; }
29981 $t = $q . $this->StartTransform(true)."\n" . $this->transformTranslate($xadj[$p], $yadj[$p] , true)."\n" . $t;
29986 if ($lastpage != -1) { $np
.= ' Q'."\n"; }
29988 $this->pages
[$this->page
] .= $np;
29990 // Adjust hyperLinks
29991 foreach($this->ktLinks
AS $p => $l) {
29992 foreach($l AS $v) {
29993 $v[0] +
= ($xadj[$p]*_MPDFK
);
29994 $v[1] -= ($yadj[$p]*_MPDFK
);
29995 $this->PageLinks
[$p2][] = $v;
29998 foreach($this->ktForms
AS $key => $f) {
30000 $f['x'] +
= ($xadj[$p]);
30001 $f['y'] +
= ($yadj[$p]);
30003 $this->form
->forms
[$f['n']] = $f;
30005 foreach($this->internallink
AS $key => $f) {
30006 if (is_array($f) && isset($f['kt'])) {
30007 $f['Y'] +
= ($yadj[$f['PAGE']]);
30010 $this->internallink
[$key] = $f;
30013 /*-- ANNOTATIONS --*/
30014 foreach($this->ktAnnots
AS $p => $l) {
30015 foreach($l AS $v) {
30016 if ($v['x']>0) { $v
['x'] +
= $xadj
[$p
]; }
30017 else if ($v['x']<0) { $v
['x'] -= $xadj
[$p
]; }
30018 $v['y'] +
= $yadj[$p];
30019 $this->PageAnnots
[$p2][] = $v;
30022 /*-- END ANNOTATIONS --*/
30024 /*-- BOOKMARKS --*/
30025 // Adjust Bookmarks
30026 foreach($this->ktBMoutlines
AS $v) {
30027 if ($v['y'] != 0) { $v
['y'] +
= ($yadj
[$v
['p']]); }
30028 $this->BMoutlines
[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$p2);
30030 /*-- END BOOKMARKS --*/
30033 // Adjust Reference (index)
30034 foreach($this->ktReference
AS $v) {
30036 //Search the reference (AND Ref/PageNo) in the array
30037 for ($i=0;$i<count($this->Reference
);$i++
){
30038 if ($this->Reference
[$i]['t']==$v['t']){
30040 if (!in_array($p2,$this->Reference
[$i]['p'])) {
30041 $this->Reference
[$i]['p'][] = $p2;
30045 //If not found, add it
30047 $this->Reference
[]=array('t'=>$v['t'],'p'=>array($p2));
30050 /*-- END INDEX --*/
30054 foreach($this->_kttoc
AS $v) {
30055 $this->tocontents
->_toc
[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$p2,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
30056 $this->links
[$v['link']][0] = $p2;
30057 $this->links
[$v['link']][1] +
= $yadj[$v['p']];
30061 $this->y
= $top[$p2] +
$height[$p1] +
$height[$p2];
30062 $this->x
= $this->lMargin
;
30064 $this->divbuffer
= array();
30065 $this->ktLinks
= array();
30066 $this->ktAnnots
= array();
30067 $this->ktForms
= array();
30068 $this->ktBlock
= array();
30069 $this->ktReference
= array();
30070 $this->ktBMoutlines
= array();
30071 $this->_kttoc
= array();
30072 $this->keep_block_together
= 0;
30077 //==================================================================
30078 // Added ELLIPSES and CIRCLES
30079 function Circle($x,$y,$r,$style='S') {
30080 $this->Ellipse($x,$y,$r,$r,$style);
30083 function Ellipse($x,$y,$rx,$ry,$style='S') {
30084 if($style=='F') { $op
='f'; }
30085 elseif($style=='FD' or $style=='DF') { $op
='B'; }
30087 $lx=4/3*(M_SQRT2
-1)*$rx;
30088 $ly=4/3*(M_SQRT2
-1)*$ry;
30090 $this->_out(sprintf('%.3F %.3F m %.3F %.3F %.3F %.3F %.3F %.3F c', ($x+
$rx)*_MPDFK
,($h-$y)*_MPDFK
, ($x+
$rx)*_MPDFK
,($h-($y-$ly))*_MPDFK
, ($x+
$lx)*_MPDFK
,($h-($y-$ry))*_MPDFK
, $x*_MPDFK
,($h-($y-$ry))*_MPDFK
));
30091 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c', ($x-$lx)*_MPDFK
,($h-($y-$ry))*_MPDFK
, ($x-$rx)*_MPDFK
,($h-($y-$ly))*_MPDFK
, ($x-$rx)*_MPDFK
,($h-$y)*_MPDFK
));
30092 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c', ($x-$rx)*_MPDFK
,($h-($y+
$ly))*_MPDFK
, ($x-$lx)*_MPDFK
,($h-($y+
$ry))*_MPDFK
, $x*_MPDFK
,($h-($y+
$ry))*_MPDFK
));
30093 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c %s', ($x+
$lx)*_MPDFK
,($h-($y+
$ry))*_MPDFK
, ($x+
$rx)*_MPDFK
,($h-($y+
$ly))*_MPDFK
, ($x+
$rx)*_MPDFK
,($h-$y)*_MPDFK
, $op));
30097 // Added adaptation of shaded_box = AUTOSIZE-TEXT
30098 function AutosizeText($text,$w,$font,$style,$szfont=72) {
30099 $text = $this->purify_utf8_text($text);
30100 if ($this->text_input_as_HTML
) {
30101 $text = $this->all_entities_to_utf8($text);
30103 if ($this->usingCoreFont
) { $text
= mb_convert_encoding($text
,$this
->mb_enc
,'UTF-8'); }
30104 $text = ' '.$text.' ';
30105 $width = $this->ConvertSize($w);
30107 while ( $loop == 0 ) {
30108 $this->SetFont($font,$style,$szfont);
30109 $sz = $this->GetStringWidth( $text );
30110 if ( $sz > $w ) { $szfont
--; }
30113 $this->SetFont($font,$style,$szfont);
30114 $this->Cell($w, 0, $text, 0, 0, "C");
30116 /*-- END DIRECTW --*/
30122 // ====================================================
30123 // ====================================================
30125 function reverse_letters($str) {
30126 $str = strtr($str, '{}[]()', '}{][)(');
30127 return $this->mb_strrev($str, $this->mb_enc
);
30130 function magic_reverse_dir(&$chunk, $join=true, $dir) {
30131 if ($this->usingCoreFont
) { return 0; }
30132 if ($this->biDirectional
) {
30133 // mPDF 5.4.05 Include PUA for non-indexed Arabic glyphs
30134 $pregRTLchars = $this->pregRTLchars
;
30135 if ($this->CurrentFont
['unAGlyphs']) { $pregRTLchars
.= "\x{F500}-\x{F7FF}"; }
30137 // Change Arabic + Persian. to Presentation Forms
30139 $chunk = preg_replace("/([".$pregRTLchars."]+)/ue", '$this->ArabJoin(stripslashes(\'\\1\'))', $chunk );
30141 $contains_rtl = false;
30143 $initSpace = false;
30145 $nonDirchars = "\x{A0}\"\'\(\)\{\}\[\].,:\\/-="; // mPDF 5.6.32
30148 preg_match_all('/([\x{202A}\x{202B}])(.*?)([\x{202C}])/u',$chunk,$m);
30149 if (count($m[0])) {
30150 for($i=0;$i<count($m[0]);$i++
) {
30151 if ($m[1][$i]=="\xe2\x80\xab") { // Right-to-Left Embedding [RLE] U+202B ‫
30152 $mark = code2utf(0xf800+
$i);
30153 $bdo[$i] = $this->reverse_letters($m[2][$i]);
30155 else if ($m[1][$i]=="\xe2\x80\xaa") { // Left-to-Right Embedding [LRE] U+202A ‪
30156 $mark = code2utf(0xf880+
$i);
30157 $bdo[$i] = $m[2][$i];
30159 $chunk = preg_replace('/'.preg_quote($m[0][$i],'/').'/u',$mark,$chunk);
30161 $pregRTLchars .= "\x{F800}-\x{F87F}";
30163 if (preg_match("/[".$pregRTLchars."]/u",$chunk)) { // Chunk contains RTL characters
30164 if (preg_match("/^[ ]/",$chunk)) { $initSpace
= true; $chunk
= preg_replace("/^[ ]/",'',$chunk
); }
30165 if (preg_match("/[ ]$/",$chunk)) { $endSpace
= true; $chunk
= preg_replace("/[ ]$/",'',$chunk
); }
30167 if (preg_match("/[^".$pregRTLchars.$nonDirchars." ]/u",$chunk)) { // Chunk also contains LTR characters
30169 if ($dir == 'rtl') {
30170 $chunk = preg_replace("/([^".$pregRTLchars.$nonDirchars."][".$nonDirchars."]*) ([".$nonDirchars."]*[^".$pregRTLchars.$nonDirchars."])/u","\\1\x07\\2",$chunk);
30172 $chunk = preg_replace("/([".$pregRTLchars."][".$nonDirchars."]*) ([".$nonDirchars."]*[".$pregRTLchars."])/u","\\1\x07\\2",$chunk);
30173 $bits = explode(' ',$chunk);
30174 foreach($bits AS $bitkey=>$bit) {
30175 $bit = preg_replace("/\x07/"," ",$bit);
30176 if (preg_match("/^[".$pregRTLchars.$nonDirchars." ]*$/u",$bit)) {
30177 $bits[$bitkey] = $this->reverse_letters($bit);
30179 else if (preg_match("/[".$pregRTLchars."]/u",$bit)) {
30180 if ($dir == 'rtl') {
30181 $bit = preg_replace("/([^".$pregRTLchars.$nonDirchars." ])([".$nonDirchars."]*[".$pregRTLchars."])/u","\\1\x07\\2",$bit );
30182 $bit = preg_replace("/([".$pregRTLchars."][".$nonDirchars."]*)([^".$pregRTLchars.$nonDirchars." ])/u","\\1\x07\\2",$bit );
30185 $bit = preg_replace("/([^".$pregRTLchars." ][".$nonDirchars."]*)([".$pregRTLchars." ])/u","\\1\x07\\2",$bit );
30186 $bit = preg_replace("/([".$pregRTLchars." ])([".$nonDirchars."]*[^".$pregRTLchars." ])/u","\\1\x07\\2",$bit );
30188 $sbits = explode("\x07",$bit );
30189 foreach($sbits AS $sbitkey=>$sbit) {
30190 $sbit = preg_replace("/\x07/","",$sbit);
30191 if (preg_match("/^[".$pregRTLchars.$nonDirchars." ]*$/u",$sbit)) {
30192 $sbits[$sbitkey] = $this->reverse_letters($sbit);
30194 else if (preg_match("/[".$pregRTLchars."]/u",$sbit) && $dir=='rtl') {
30195 $sbits[$sbitkey] = $this->reverse_letters($sbit);
30198 // Reverse numerals only to RTL
30199 $sbit = preg_replace("/([\x{0660}-\x{066C}0-9]+[\x{0660}-\x{066C}0-9\.,:\/]*[\x{0660}-\x{066C}0-9]+)/ue", '$this->reverse_letters(\'\\1\')', $sbit ); // mPDF 5.6.32 // mPDF 5.6.46
30200 $sbits[$sbitkey] = $sbit;
30203 if ($dir == 'rtl') { $sbits
= array_reverse($sbits
,false); }
30204 $bits[$bitkey] = implode('',$sbits);
30206 else if (preg_match("/[".$pregRTLchars."]/u",$bit) && $dir=='rtl') {
30207 $bits[$bitkey] = $this->reverse_letters($bit);
30210 // Reverse numerals only to RTL
30211 $bit = preg_replace("/([\x{0660}-\x{066C}0-9]+[\x{0660}-\x{066C}0-9\.,:\/]*[\x{0660}-\x{066C}0-9]+)/ue", '$this->reverse_letters(\'\\1\')', $bit ); // mPDF 5.6.32 // mPDF 5.6.46
30212 $bits[$bitkey] = $bit;
30215 if ($dir == 'rtl') { $bits
= array_reverse($bits
,false); }
30216 $chunk = implode(' ',$bits);
30218 else { $chunk
= $this
->reverse_letters($chunk
); }
30219 $contains_rtl = true;
30221 // Un-Reverse numerals back to ltr
30222 $chunk = preg_replace("/([\x{0660}-\x{066C}0-9]+[\x{0660}-\x{066C}0-9\.,:\/]*[\x{0660}-\x{066C}0-9]+)/ue", '$this->reverse_letters(\'\\1\')', $chunk ); // mPDF 5.6.13 // mPDF 5.6.32 // mPDF 5.6.46
30223 if ($dir == 'rtl') {
30224 if ($endSpace) { $chunk
= ' '.$chunk
; }
30225 if ($initSpace) { $chunk
.= ' '; }
30228 if ($initSpace) { $chunk
= ' '.$chunk
; }
30229 if ($endSpace) { $chunk
.= ' '; }
30232 else { $all_rtl
= false; }
30236 for($i=0;$i<count($bdo);$i++
) {
30237 $chunk = preg_replace('/[\x{'.dechex(intval(0xf800+$i)).'}\x{'.dechex(intval(0xf880+$i)).'}]/u',$bdo[$i],$chunk);
30241 if ($all_rtl) { return 2; }
30242 else if ($contains_rtl) { return 1; }
30250 // ****************************
30251 // ****************************
30254 function SetSubstitutions() {
30255 $subsarray = array();
30256 @include(_MPDF_PATH
.'includes/subs_win-1252.php');
30257 $this->substitute
= array();
30258 foreach($subsarray AS $key => $val) {
30259 $this->substitute
[code2utf($key)] = $val;
30264 function SubstituteChars($html) {
30265 // only substitute characters between tags
30266 if (count($this->substitute
)) {
30267 $a=preg_split('/(<.*?>)/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE
);
30269 foreach($a as $i => $e) {
30271 $e = strtr($e, $this->substitute
);
30280 function SubstituteCharsSIP(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30281 if (preg_match("/^(.*?)([\x{20000}-\x{2FFFF}]+)(.*)/u", $writehtml_e, $m)) {
30282 if (isset($this->CurrentFont
['sipext']) && $this->CurrentFont
['sipext']) {
30283 $font = $this->CurrentFont
['sipext'];
30284 if (!in_array($font, $this->available_unifonts
)) { return 0; }
30285 $writehtml_a[$writehtml_i] = $writehtml_e = $m[1];
30286 array_splice($writehtml_a, $writehtml_i+
1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30287 $this->subPos
= $writehtml_i;
30294 // If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
30295 function SubstituteCharsNonCore(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30296 if (mb_convert_encoding(mb_convert_encoding($writehtml_e, $this->mb_enc
, "UTF-8"), "UTF-8", $this->mb_enc
) == $writehtml_e) {
30299 $cw = &$this->CurrentFont
['cw'];
30300 $unicode = $this->UTF8StringToArray($writehtml_e, false);
30306 if (!$this->subArrMB
) {
30307 include(_MPDF_PATH
.'includes/subs_core.php');
30308 $this->subArrMB
['a'] = $aarr;
30309 $this->subArrMB
['s'] = $sarr;
30310 $this->subArrMB
['z'] = $zarr;
30312 foreach($unicode AS $c => $char) {
30313 if (($char> 127 || ($flag==1 && $char==32)) && $char != 173 && (!isset($this->subArrMB
['a'][$char]) || ($flag==1 && $char==32)) && ($char<1536 || ($char>1791 && $char < 2304) || $char>3455)) {
30314 if ($flag==0) { $start
=$c
; }
30318 else if ($flag>0) { $end
=$c
-1; break; }
30320 if ($flag>0 && !$end) { $end
=count($unicode
)-1; }
30321 if ($start==-1) { return 0; }
30322 // TRY IN BACKUP SUBS FONT
30323 if (!is_array($this->backupSubsFont
)) { $this
->backupSubsFont
= array("$this->backupSubsFont"); }
30324 foreach($this->backupSubsFont
AS $bsfctr=>$bsf) {
30325 if ($this->fonttrans
[$bsf] == 'chelvetica' || $this->fonttrans
[$bsf] == 'ctimes' || $this->fonttrans
[$bsf] == 'ccourier') { continue; }
30329 if (isset($this->fonts
[$font])) { $cw
= &$this
->fonts
[$font
]['cw']; }
30330 else if (file_exists(_MPDF_TTFONTDATAPATH
.$font.'.cw.dat')) { $cw
= @file_get_contents(_MPDF_TTFONTDATAPATH
.$font
.'.cw.dat'); }
30333 $prevFontFamily = $this->FontFamily
;
30334 $prevFontStyle = $this->currentfontstyle
;
30335 $prevFontSizePt = $this->FontSizePt
;
30336 $this->SetFont($bsf, '', '', false);
30337 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH
.$font.'.cw.dat');
30338 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30340 if (!$cw) { continue; }
30342 foreach($u AS $char) {
30343 if ($char == 173 || $this->_charDefined($cw,$char) || ($char>1536 && $char<1791) || ($char>2304 && $char<3455 )) {
30347 if ($l==0 && $bsfctr == (count($this->backupSubsFont
)-1)) { // Not found even in last backup font
30348 $cont = mb_substr($writehtml_e, $start+
1);
30349 $writehtml_e = mb_substr($writehtml_e, 0, $start+
1, 'UTF-8');
30350 array_splice($writehtml_a, $writehtml_i+
1, 0, array('', $cont));
30351 $this->subPos
= $writehtml_i+
1;
30358 $patt = mb_substr($writehtml_e, $start, $l, 'UTF-8');
30359 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30360 $writehtml_e = $m[1];
30361 array_splice($writehtml_a, $writehtml_i+
1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30362 $this->subPos
= $writehtml_i+
3;
30373 function SubstituteCharsMB(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30374 $cw = &$this->CurrentFont
['cw'];
30375 $unicode = $this->UTF8StringToArray($writehtml_e, false);
30381 foreach($unicode AS $c => $char) {
30382 if (($flag == 0 || $flag==2) && (!$this->_charDefined($cw,$char) || ($flag==2 && $char==32)) && $this->checkSIP
&& $char > 131071) { // Unicode Plane 2 (SIP)
30383 if (in_array($this->FontFamily
,$this->available_CJK_fonts
)) { return 0; }
30384 if ($flag==0) { $start
=$c
; }
30388 //else if (($flag == 0 || $flag==1) && $char != 173 && !$this->_charDefined($cw,$char) && ($char<1423 || ($char>3583 && $char < 11263))) {
30389 else if (($flag == 0 || $flag==1) && $char != 173 && (!$this->_charDefined($cw,$char) || ($flag==1 && $char==32)) && ($char<1536 || ($char>1791 && $char < 2304) || $char>3455)) {
30390 if ($flag==0) { $start
=$c
; }
30394 else if ($flag>0) { $end
=$c
-1; break; }
30396 if ($flag>0 && !$end) { $end
=count($unicode
)-1; }
30397 if ($start==-1) { return 0; }
30398 if ($flag == 2) { // SIP
30399 // Check if current CJK font has a ext-B related font
30400 if (isset($this->CurrentFont
['sipext']) && $this->CurrentFont
['sipext']) {
30401 $font = $this->CurrentFont
['sipext'];
30404 if (isset($this->fonts
[$font])) { $cw
= &$this
->fonts
[$font
]['cw']; }
30405 else if (file_exists(_MPDF_TTFONTDATAPATH
.$font.'.cw.dat')) { $cw
= @file_get_contents(_MPDF_TTFONTDATAPATH
.$font
.'.cw.dat'); }
30407 $prevFontFamily = $this->FontFamily
;
30408 $prevFontStyle = $this->currentfontstyle
;
30409 $prevFontSizePt = $this->FontSizePt
;
30410 $this->SetFont($font, '', '', false);
30411 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH
.$font.'.cw.dat');
30412 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30414 if (!$cw) { return 0; }
30416 foreach($u AS $char) {
30417 if ($this->_charDefined($cw,$char) || $char > 131071) {
30423 $patt = mb_substr($writehtml_e, $start, $l);
30424 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30425 $writehtml_e = $m[1];
30426 array_splice($writehtml_a, $writehtml_i+
1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30427 $this->subPos
= $writehtml_i+
3;
30432 // Check Backup SIP font (defined in config_fonts.php)
30433 if (isset($this->backupSIPFont
) && $this->backupSIPFont
) {
30434 if ($this->currentfontfamily
!= $this->backupSIPFont
) { $font
= $this
->backupSIPFont
; }
30435 else {
unset($cw
); return 0; }
30438 if (isset($this->fonts
[$font])) { $cw
= &$this
->fonts
[$font
]['cw']; }
30439 else if (file_exists(_MPDF_TTFONTDATAPATH
.$font.'.cw.dat')) { $cw
= @file_get_contents(_MPDF_TTFONTDATAPATH
.$font
.'.cw.dat'); }
30441 $prevFontFamily = $this->FontFamily
;
30442 $prevFontStyle = $this->currentfontstyle
;
30443 $prevFontSizePt = $this->FontSizePt
;
30444 $this->SetFont($this->backupSIPFont
, '', '', false);
30445 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH
.$font.'.cw.dat');
30446 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30448 if (!$cw) { return 0; }
30450 foreach($u AS $char) {
30451 if ($this->_charDefined($cw,$char) || $char > 131071) {
30457 $patt = mb_substr($writehtml_e, $start, $l);
30458 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30459 $writehtml_e = $m[1];
30460 array_splice($writehtml_a, $writehtml_i+
1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30461 $this->subPos
= $writehtml_i+
3;
30470 // FIRST TRY CORE FONTS
30471 if (!$this->PDFA
&& !$this->PDFX
) {
30473 if (!$this->subArrMB
) {
30474 include(_MPDF_PATH
.'includes/subs_core.php');
30475 $this->subArrMB
['a'] = $aarr;
30476 $this->subArrMB
['s'] = $sarr;
30477 $this->subArrMB
['z'] = $zarr;
30479 if (isset($this->subArrMB
['a'][$u[0]])) {
30480 $font = 'tta'; $ftype = 'C';
30481 foreach($u AS $char) {
30482 if ($this->subArrMB
['a'][$char]) { $repl
[] = $this
->subArrMB
['a'][$char
]; }
30486 else if (isset($this->subArrMB
['z'][$u[0]])) {
30487 $font = 'ttz'; $ftype = 'C';
30488 foreach($u AS $char) {
30489 if ($this->subArrMB
['z'][$char]) { $repl
[] = $this
->subArrMB
['z'][$char
]; }
30493 else if (isset($this->subArrMB
['s'][$u[0]])) {
30494 $font = 'tts'; $ftype = 'C';
30495 foreach($u AS $char) {
30496 if ($this->subArrMB
['s'][$char]) { $repl
[] = $this
->subArrMB
['s'][$char
]; }
30501 $patt = mb_substr($writehtml_e, $start, count($repl));
30502 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30503 $writehtml_e = $m[1];
30504 array_splice($writehtml_a, $writehtml_i+
1, 0, array($font, implode('|', $repl), '/'.$font, $m[3])); // e.g. <tts>
30505 $this->subPos
= $writehtml_i+
3;
30512 // FIND IN DEFAULT FONT - removed mPDF 5.0
30514 // LASTLY TRY IN BACKUP SUBS FONT
30515 if (!is_array($this->backupSubsFont
)) { $this
->backupSubsFont
= array("$this->backupSubsFont"); }
30516 foreach($this->backupSubsFont
AS $bsfctr=>$bsf) {
30517 if ($this->currentfontfamily
!= $bsf) { $font
= $bsf
; }
30521 if (isset($this->fonts
[$font])) { $cw
= &$this
->fonts
[$font
]['cw']; }
30522 else if (file_exists(_MPDF_TTFONTDATAPATH
.$font.'.cw.dat')) { $cw
= @file_get_contents(_MPDF_TTFONTDATAPATH
.$font
.'.cw.dat'); }
30524 $prevFontFamily = $this->FontFamily
;
30525 $prevFontStyle = $this->currentfontstyle
;
30526 $prevFontSizePt = $this->FontSizePt
;
30527 $this->SetFont($bsf, '', '', false);
30528 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH
.$font.'.cw.dat');
30529 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30531 if (!$cw) { continue; }
30533 foreach($u AS $char) {
30534 if ($char == 173 || $this->_charDefined($cw,$char) || ($char>1536 && $char<1791) || ($char>2304 && $char<3455 )) { // Arabic and Indic
30538 if ($l==0 && $bsfctr == (count($this->backupSubsFont
)-1)) { // Not found even in last backup font
30539 $cont = mb_substr($writehtml_e, $start+
1);
30540 $writehtml_e = mb_substr($writehtml_e, 0, $start+
1);
30541 array_splice($writehtml_a, $writehtml_i+
1, 0, array('', $cont));
30542 $this->subPos
= $writehtml_i+
1;
30549 $patt = mb_substr($writehtml_e, $start, $l);
30550 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30551 $writehtml_e = $m[1];
30552 array_splice($writehtml_a, $writehtml_i+
1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30553 $this->subPos
= $writehtml_i+
3;
30564 function setHiEntitySubstitutions() {
30566 'nbsp' => '160', 'iexcl' => '161', 'cent' => '162', 'pound' => '163', 'curren' => '164', 'yen' => '165', 'brvbar' => '166', 'sect' => '167',
30567 'uml' => '168', 'copy' => '169', 'ordf' => '170', 'laquo' => '171', 'not' => '172', 'shy' => '173', 'reg' => '174', 'macr' => '175',
30568 'deg' => '176', 'plusmn' => '177', 'sup2' => '178', 'sup3' => '179', 'acute' => '180', 'micro' => '181', 'para' => '182', 'middot' => '183',
30569 'cedil' => '184', 'sup1' => '185', 'ordm' => '186', 'raquo' => '187', 'frac14' => '188', 'frac12' => '189', 'frac34' => '190',
30570 'iquest' => '191', 'Agrave' => '192', 'Aacute' => '193', 'Acirc' => '194', 'Atilde' => '195', 'Auml' => '196', 'Aring' => '197',
30571 'AElig' => '198', 'Ccedil' => '199', 'Egrave' => '200', 'Eacute' => '201', 'Ecirc' => '202', 'Euml' => '203', 'Igrave' => '204',
30572 'Iacute' => '205', 'Icirc' => '206', 'Iuml' => '207', 'ETH' => '208', 'Ntilde' => '209', 'Ograve' => '210', 'Oacute' => '211',
30573 'Ocirc' => '212', 'Otilde' => '213', 'Ouml' => '214', 'times' => '215', 'Oslash' => '216', 'Ugrave' => '217', 'Uacute' => '218',
30574 'Ucirc' => '219', 'Uuml' => '220', 'Yacute' => '221', 'THORN' => '222', 'szlig' => '223', 'agrave' => '224', 'aacute' => '225',
30575 'acirc' => '226', 'atilde' => '227', 'auml' => '228', 'aring' => '229', 'aelig' => '230', 'ccedil' => '231', 'egrave' => '232',
30576 'eacute' => '233', 'ecirc' => '234', 'euml' => '235', 'igrave' => '236', 'iacute' => '237', 'icirc' => '238', 'iuml' => '239',
30577 'eth' => '240', 'ntilde' => '241', 'ograve' => '242', 'oacute' => '243', 'ocirc' => '244', 'otilde' => '245', 'ouml' => '246',
30578 'divide' => '247', 'oslash' => '248', 'ugrave' => '249', 'uacute' => '250', 'ucirc' => '251', 'uuml' => '252', 'yacute' => '253',
30579 'thorn' => '254', 'yuml' => '255', 'OElig' => '338', 'oelig' => '339', 'Scaron' => '352', 'scaron' => '353', 'Yuml' => '376',
30580 'fnof' => '402', 'circ' => '710', 'tilde' => '732', 'Alpha' => '913', 'Beta' => '914', 'Gamma' => '915', 'Delta' => '916',
30581 'Epsilon' => '917', 'Zeta' => '918', 'Eta' => '919', 'Theta' => '920', 'Iota' => '921', 'Kappa' => '922', 'Lambda' => '923',
30582 'Mu' => '924', 'Nu' => '925', 'Xi' => '926', 'Omicron' => '927', 'Pi' => '928', 'Rho' => '929', 'Sigma' => '931', 'Tau' => '932',
30583 'Upsilon' => '933', 'Phi' => '934', 'Chi' => '935', 'Psi' => '936', 'Omega' => '937', 'alpha' => '945', 'beta' => '946', 'gamma' => '947',
30584 'delta' => '948', 'epsilon' => '949', 'zeta' => '950', 'eta' => '951', 'theta' => '952', 'iota' => '953', 'kappa' => '954',
30585 'lambda' => '955', 'mu' => '956', 'nu' => '957', 'xi' => '958', 'omicron' => '959', 'pi' => '960', 'rho' => '961', 'sigmaf' => '962',
30586 'sigma' => '963', 'tau' => '964', 'upsilon' => '965', 'phi' => '966', 'chi' => '967', 'psi' => '968', 'omega' => '969',
30587 'thetasym' => '977', 'upsih' => '978', 'piv' => '982', 'ensp' => '8194', 'emsp' => '8195', 'thinsp' => '8201', 'zwnj' => '8204',
30588 'zwj' => '8205', 'lrm' => '8206', 'rlm' => '8207', 'ndash' => '8211', 'mdash' => '8212', 'lsquo' => '8216', 'rsquo' => '8217',
30589 'sbquo' => '8218', 'ldquo' => '8220', 'rdquo' => '8221', 'bdquo' => '8222', 'dagger' => '8224', 'Dagger' => '8225', 'bull' => '8226',
30590 'hellip' => '8230', 'permil' => '8240', 'prime' => '8242', 'Prime' => '8243', 'lsaquo' => '8249', 'rsaquo' => '8250', 'oline' => '8254',
30591 'frasl' => '8260', 'euro' => '8364', 'image' => '8465', 'weierp' => '8472', 'real' => '8476', 'trade' => '8482', 'alefsym' => '8501',
30592 'larr' => '8592', 'uarr' => '8593', 'rarr' => '8594', 'darr' => '8595', 'harr' => '8596', 'crarr' => '8629', 'lArr' => '8656',
30593 'uArr' => '8657', 'rArr' => '8658', 'dArr' => '8659', 'hArr' => '8660', 'forall' => '8704', 'part' => '8706', 'exist' => '8707',
30594 'empty' => '8709', 'nabla' => '8711', 'isin' => '8712', 'notin' => '8713', 'ni' => '8715', 'prod' => '8719', 'sum' => '8721',
30595 'minus' => '8722', 'lowast' => '8727', 'radic' => '8730', 'prop' => '8733', 'infin' => '8734', 'ang' => '8736', 'and' => '8743',
30596 'or' => '8744', 'cap' => '8745', 'cup' => '8746', 'int' => '8747', 'there4' => '8756', 'sim' => '8764', 'cong' => '8773',
30597 'asymp' => '8776', 'ne' => '8800', 'equiv' => '8801', 'le' => '8804', 'ge' => '8805', 'sub' => '8834', 'sup' => '8835', 'nsub' => '8836',
30598 'sube' => '8838', 'supe' => '8839', 'oplus' => '8853', 'otimes' => '8855', 'perp' => '8869', 'sdot' => '8901', 'lceil' => '8968',
30599 'rceil' => '8969', 'lfloor' => '8970', 'rfloor' => '8971', 'lang' => '9001', 'rang' => '9002', 'loz' => '9674', 'spades' => '9824',
30600 'clubs' => '9827', 'hearts' => '9829', 'diams' => '9830',
30602 foreach($entarr AS $key => $val) {
30603 $this->entsearch
[] = '&'.$key.';';
30604 $this->entsubstitute
[] = code2utf($val);
30608 function SubstituteHiEntities($html) {
30609 // converts html_entities > ASCII 127 to unicode
30610 // Leaves in particular < to distinguish from tag marker
30611 if (count($this->entsearch
)) {
30612 $html = str_replace($this->entsearch
,$this->entsubstitute
,$html);
30618 // Edited v1.2 Pass by reference; option to continue if invalid UTF-8 chars
30619 function is_utf8(&$string) {
30620 if ($string === mb_convert_encoding(mb_convert_encoding($string, "UTF-32", "UTF-8"), "UTF-8", "UTF-32")) {
30624 if ($this->ignore_invalid_utf8
) {
30625 $string = mb_convert_encoding(mb_convert_encoding($string, "UTF-32", "UTF-8"), "UTF-8", "UTF-32") ;
30635 function purify_utf8($html,$lo=true) {
30637 // Checks string is valid UTF-8 encoded
30638 // converts html_entities > ASCII 127 to UTF-8
30639 // Only exception - leaves low ASCII entities e.g. < & etc.
30640 // Leaves in particular < to distinguish from tag marker
30641 if (!$this->is_utf8($html)) {
30642 echo "<p><b>HTML contains invalid UTF-8 character(s)</b></p>";
30643 while (mb_convert_encoding(mb_convert_encoding($html, "UTF-32", "UTF-8"), "UTF-8", "UTF-32") != $html) {
30644 $a = iconv('UTF-8', 'UTF-8', $html);
30646 $pos = $start = strlen($a);
30648 while ( ord(substr($html,$pos,1)) > 128 ) {
30649 $err .= '[[#'.ord(substr($html,$pos,1)).']]';
30652 echo '<span style="color:red; font-weight:bold">'.$err.'</span>';
30653 $html = substr($html, $pos);
30658 $html = preg_replace("/\r/", "", $html );
30660 // converts html_entities > ASCII 127 to UTF-8
30661 // Leaves in particular < to distinguish from tag marker
30662 $html = $this->SubstituteHiEntities($html);
30664 // converts all &#nnn; or &#xHHH; to UTF-8 multibyte
30665 // If $lo==true then includes ASCII < 128
30666 $html = strcode2utf($html,$lo);
30670 function purify_utf8_text($txt) {
30672 // Make sure UTF-8 string of characters
30673 if (!$this->is_utf8($txt)) { $this
->Error("Text contains invalid UTF-8 character(s)"); }
30675 $txt = preg_replace("/\r/", "", $txt );
30679 function all_entities_to_utf8($txt) {
30680 // converts txt_entities > ASCII 127 to UTF-8
30681 // Leaves in particular < to distinguish from tag marker
30682 $txt = $this->SubstituteHiEntities($txt);
30684 // converts all &#nnn; or &#xHHH; to UTF-8 multibyte
30685 $txt = strcode2utf($txt);
30687 $txt = $this->lesser_entity_decode($txt);
30692 // ====================================================
30695 // EAN13, EAN8, UPCA, UPCE, ISBN, ISSN
30696 // Accepts 12 or 13 digits with or without - hyphens
30697 function WriteBarcode($code, $showtext=1, $x='', $y='', $size=1, $border=0, $paddingL=1, $paddingR=1, $paddingT=2, $paddingB=2, $height=1, $bgcol=false, $col=false, $btype='ISBN', $supplement='0', $supplement_code='', $k=1) {
30698 if (empty($code)) {
30702 $code = preg_replace('/\-/','',$code);
30704 if (!class_exists('PDFBarcode', false)) {
30705 include(_MPDF_PATH
.'classes/barcode.php');
30707 $this->barcode
= new PDFBarcode();
30708 if ($btype == 'ISSN' || $btype == 'ISBN') {
30709 $arrcode = $this->barcode
->getBarcodeArray($code, 'EAN13');
30711 else { $arrcode
= $this
->barcode
->getBarcodeArray($code
, $btype
); }
30713 if ($arrcode === false) { $this
->Error('Error in barcode string: '.$codestr
); }
30714 if((($btype=='EAN13' || $btype=='ISBN' || $btype=='ISSN') && strlen($code) == 12) || ($btype=='UPCA' && strlen($code) == 11)
30715 || ($btype=='UPCE' && strlen($code) == 11) || ($btype=='EAN8' && strlen($code) == 7)) {
30716 $code .= $arrcode['checkdigit'];
30717 if (stristr($codestr,'-')) { $codestr
.= '-' . $arrcode
['checkdigit']; }
30718 else { $codestr
.= $arrcode
['checkdigit']; }
30720 if ($btype == 'ISBN') { $codestr
= 'ISBN '.$codestr
; }
30721 if ($btype == 'ISSN') { $codestr
= 'ISSN '.$codestr
; }
30729 // set foreground color
30730 $prevDrawColor = $this->DrawColor
;
30731 $prevTextColor = $this->TextColor
;
30732 $prevFillColor = $this->FillColor
;
30733 $lw = $this->LineWidth
;
30734 $this->SetLineWidth(0.01);
30736 $size /= $k; // in case resized in a table
30738 $xres = $arrcode['nom-X'] * $size;
30739 $llm = $arrcode['lightmL'] * $arrcode['nom-X'] * $size; // Left Light margin
30740 $rlm = $arrcode['lightmR'] * $arrcode['nom-X'] * $size; // Right Light margin
30742 $bcw = ($arrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size
30744 $fbw = $bcw +
$llm +
$rlm; // Full barcode width incl. light margins
30745 $ow = $fbw +
$paddingL +
$paddingR; // Full overall width incl. user-defined padding
30747 $fbwi = $fbw - 2; // Full barcode width incl. light margins - 2mm - for isbn string
30749 // cf. http://www.gs1uk.org/downloads/bar_code/Bar coding getting it right.pdf
30750 $num_height = 3 * $size; // Height of numerals
30751 $fbh = $arrcode['nom-H'] * $size * $height; // Full barcode height incl. numerals
30752 $bch = $fbh - (1.5 * $size); // Barcode height of bars (3mm for numerals)
30754 if (($btype=='EAN13' && $showtext) || $btype == 'ISSN' || $btype == 'ISBN') { // Add height for ISBN string + margin from top of bars
30755 $tisbnm = 1.5 * $size; // Top margin between isbn (if shown) & bars
30756 $codestr_fontsize = 2.1 * $size;
30757 $paddingT +
= $codestr_fontsize +
$tisbnm ;
30759 $oh = $fbh +
$paddingT +
$paddingB; // Full overall height incl. user-defined padding
30761 // PRINT border background color
30765 $this->SetDColor($col);
30766 $this->SetTColor($col);
30769 $this->SetDColor($this->ConvertColor(0));
30770 $this->SetTColor($this->ConvertColor(0));
30773 $this->SetFColor($bgcol);
30775 else { $this
->SetFColor($this
->ConvertColor(255)); }
30776 if (!$bgcol && !$col) { // fn. called directly - not via HTML
30777 if ($border) { $fillb
= 'DF'; } else { $fillb
= 'F'; }
30778 $this->Rect($xpos, $ypos, $ow, $oh, $fillb);
30783 $xpos = $x +
$paddingL +
$llm ;
30784 $ypos = $y +
$paddingT;
30785 if ($col) { $this
->SetFColor($col
); }
30786 else { $this
->SetFColor($this
->ConvertColor(0)); }
30787 if ($arrcode !== false) {
30788 foreach ($arrcode["bcode"] AS $v) {
30789 $bw = ($v["w"] * $xres);
30791 // draw a vertical bar
30792 $this->Rect($xpos, $ypos, $bw, $bch, 'F');
30800 $prevFontFamily = $this->FontFamily
;
30801 $prevFontStyle = $this->FontStyle
;
30802 $prevFontSizePt = $this->FontSizePt
;
30805 if (($btype=='EAN13' && $showtext) || $btype=='ISBN' || $btype=='ISSN') {
30806 if ($this->onlyCoreFonts
) {
30807 $this->SetFont('chelvetica');
30810 $this->SetFont('sans');
30813 if ($bgcol) { $this
->SetFColor($bgcol
); }
30814 else { $this
->SetFColor($this
->ConvertColor(255)); }
30815 $this->x
= $x +
$paddingL +
1; // 1mm left margin (cf. $fbwi above)
30816 // max width is $fbwi
30818 while ( $loop == 0 ) {
30819 $this->SetFontSize($codestr_fontsize*1.4*_MPDFK
, false); // don't write
30820 $sz = $this->GetStringWidth( $codestr );
30822 $codestr_fontsize -= 0.1;
30826 $this->SetFont('','',$codestr_fontsize*1.4*_MPDFK
, true, true); // * 1.4 because font height is only 7/10 of given mm
30829 $xtra = $fbwi - $sz;
30830 $charspacing = $xtra / (strlen($codestr)-1);
30831 if ($charspacing) { $this
->_out(sprintf('BT %.3F Tc ET',$charspacing
*_MPDFK
)); }
30833 $this->y
= $y +
$paddingT - ($codestr_fontsize ) - $tisbnm ;
30834 $this->Cell($fbw , $codestr_fontsize, $codestr);
30835 if ($charspacing) { $this
->_out('BT 0 Tc ET'); }
30840 if ($this->onlyCoreFonts
) {
30841 $this->SetFont('mono');
30844 if (in_array('ocrb',$this->available_unifonts
)) { $this
->SetFont('ocrb'); }
30845 else { $this
->SetFont('mono'); }
30847 if (isset($this->CurrentFont
['desc']['CapHeight'])) { $fh
= (1000/$this
->CurrentFont
['desc']['CapHeight']); }
30848 else if (isset($this->CurrentFont
['desc']['Ascent'])) { $fh
= (1000/$this
->CurrentFont
['desc']['Ascent']); }
30849 else { $fh
= 1.2; }
30852 if ($btype=='EAN13' || $btype=='ISBN' || $btype=='ISSN') {
30853 $outerfontsize = 3; // Inner fontsize = 3
30854 $outerp = $xres * 4;
30855 $innerp = $xres * 2.5;
30856 $textw = ($bcw*0.5) - $outerp - $innerp;
30857 $chars = 6; // number of numerals in each half
30858 $charLO = substr($code,0,1); // Left Outer
30859 $charLI = substr($code,1,6); // Left Inner
30860 $charRI = substr($code,7,6); // Right Inner
30861 if (!$supplement) $charRO = '>'; // Right Outer
30863 else if ($btype=='UPCA') {
30864 $outerfontsize = 2.3; // Inner fontsize = 3
30865 $outerp = $xres * 10;
30866 $innerp = $xres * 2.5;
30867 $textw = ($bcw*0.5) - $outerp - $innerp;
30869 $charLO = substr($code,0,1); // Left Outer
30870 $charLI = substr($code,1,5); // Left Inner
30871 $charRI = substr($code,6,5); // Right Inner
30872 $charRO = substr($code,11,1); // Right Outer
30874 else if ($btype=='UPCE') {
30875 $outerfontsize = 2.3; // Inner fontsize = 3
30876 $outerp = $xres * 4;
30878 $textw = ($bcw*0.5) - $outerp - $innerp;
30880 $upce_code = $arrcode['code'];
30881 $charLO = substr($code,0,1); // Left Outer
30882 $charLI = substr($upce_code,0,3); // Left Inner
30883 $charRI = substr($upce_code,3,3); // Right Inner
30884 $charRO = substr($code,11,1); // Right Outer
30886 else if ($btype=='EAN8') {
30887 $outerfontsize = 3; // Inner fontsize = 3
30888 $outerp = $xres * 4;
30889 $innerp = $xres * 2.5;
30890 $textw = ($bcw*0.5) - $outerp - $innerp;
30892 $charLO = '<'; // Left Outer
30893 $charLI = substr($code,0,4); // Left Inner
30894 $charRI = substr($code,4,4); // Right Inner
30895 if (!$supplement) $charRO = '>'; // Right Outer
30898 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK
); // 3mm numerals (FontSize is larger to account for space above/below characters)
30900 if (!$this->usingCoreFont
) { $cw
= $this
->_getCharWidth($this
->CurrentFont
['cw'],32)*3*$fh
*$size
/1000; } // character width at 3mm
30901 else { $cw
= $this
->_getCharWidth($this
->CurrentFont
['cw'],48)*3*$fh
*$size
/1000; } // 48 == char "0"
30903 // Outer left character
30904 $y_text = $y +
$paddingT +
$bch - ($num_height/2);
30905 $y_text_outer = $y +
$paddingT +
$bch - ($num_height*($outerfontsize/3)/2);
30907 $this->x
= $x +
$paddingL - ($cw*($outerfontsize/3)*0.1); // 0.1 is correction as char does not fill full width;
30908 $this->y
= $y_text_outer;
30909 $this->Cell($cw, $num_height, $charLO );
30911 // WORD SPACING for inner chars
30912 $xtra = $textw - ($cw*$chars);
30913 $charspacing = $xtra / ($chars-1);
30914 if ($charspacing) { $this
->_out(sprintf('BT %.3F Tc ET',$charspacing
*_MPDFK
)); }
30916 if ($bgcol) { $this
->SetFColor($bgcol
); }
30917 else { $this
->SetFColor($this
->ConvertColor(255)); }
30919 $this->SetFontSize(3*$fh*$size*_MPDFK
); // 3mm numerals (FontSize is larger to account for space above/below characters)
30921 // Inner left half characters
30922 $this->x
= $x +
$paddingL +
$llm +
$outerp;
30923 $this->y
= $y_text;
30924 $this->Cell($textw, $num_height, $charLI , 0, 0, '', 1);
30926 // Inner right half characters
30927 $this->x
= $x +
$paddingL +
$llm +
($bcw*0.5) +
$innerp;
30928 $this->y
= $y_text;
30929 $this->Cell($textw, $num_height, $charRI , 0, 0, '', 1);
30931 if ($charspacing) { $this
->_out('BT 0 Tc ET'); }
30933 // Outer Right character
30934 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK
); // 3mm numerals (FontSize is larger to account for space above/below characters)
30936 $this->x
= $x +
$paddingL +
$llm +
$bcw +
$rlm - ($cw*($outerfontsize/3)*0.9); // 0.9 is correction as char does not fill full width
30937 $this->y
= $y_text_outer;
30938 $this->Cell($cw*($outerfontsize/3), $num_height, $charRO , 0, 0, 'R');
30940 if ($supplement) { // EAN-2 or -5 Supplement
30942 $supparrcode = $this->barcode
->getBarcodeArray($supplement_code, 'EAN'.$supplement);
30943 if ($supparrcode === false) { $this
->Error('Error in barcode string (supplement): '.$codestr
.' '.$supplement_code
); }
30944 if(strlen($supplement_code) != $supplement) {
30945 $this->Error('Barcode supplement incorrect: '.$supplement_code);
30947 $llm = $fbw - (($arrcode['lightmR'] - $supparrcode['sepM']) * $arrcode['nom-X'] * $size); // Left Light margin
30948 $rlm = $arrcode['lightmR'] * $arrcode['nom-X'] * $size; // Right Light margin
30950 $bcw = ($supparrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size
30952 $fbw = $bcw +
$llm +
$rlm; // Full barcode width incl. light margins
30953 $ow = $fbw +
$paddingL +
$paddingR; // Full overall width incl. user-defined padding
30954 $bch = $fbh - (1.5 * $size) - ($num_height +
0.5); // Barcode height of bars (3mm for numerals)
30956 $xpos = $x +
$paddingL +
$llm ;
30957 $ypos = $y +
$paddingT +
$num_height +
0.5;
30958 if ($col) { $this
->SetFColor($col
); }
30959 else { $this
->SetFColor($this
->ConvertColor(0)); }
30960 if ($supparrcode !== false) {
30961 foreach ($supparrcode["bcode"] AS $v) {
30962 $bw = ($v["w"] * $xres);
30964 // draw a vertical bar
30965 $this->Rect($xpos, $ypos, $bw, $bch, 'F');
30972 if ($bgcol) { $this
->SetFColor($bgcol
); }
30973 else { $this
->SetFColor($this
->ConvertColor(255)); }
30974 $this->SetFontSize(3*$fh*$size*_MPDFK
); // 3mm numerals (FontSize is larger to account for space above/below characters)
30975 $this->x
= $x +
$paddingL +
$llm;
30976 $this->y
= $y +
$paddingT;
30977 $this->Cell($bcw, $num_height, $supplement_code, 0, 0, 'C');
30979 // Outer Right character (light margin)
30980 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK
); // 3mm numerals (FontSize is larger to account for space above/below characters)
30981 $this->x
= $x +
$paddingL +
$llm +
$bcw +
$rlm - ($cw*0.9); // 0.9 is correction as char does not fill full width
30982 $this->y
= $y +
$paddingT;
30983 $this->Cell($cw*($outerfontsize/3), $num_height, '>', 0, 0, 'R');
30988 // Restore **************
30989 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt);
30990 $this->DrawColor
= $prevDrawColor;
30991 $this->TextColor
= $prevTextColor;
30992 $this->FillColor
= $prevFillColor;
30993 $this->SetLineWidth($lw);
30999 // ====================================================
31000 // POSTAL and OTHER barcodes
31001 function WriteBarcode2($code, $x='', $y='', $size=1, $height=1, $bgcol=false, $col=false, $btype='IMB', $print_ratio='', $k=1) {
31002 if (empty($code)) { return; }
31003 if (!class_exists('PDFBarcode', false)) {
31004 include(_MPDF_PATH
.'classes/barcode.php');
31006 $this->barcode
= new PDFBarcode();
31007 $arrcode = $this->barcode
->getBarcodeArray($code, $btype, $print_ratio);
31009 if ($arrcode === false) { $this
->Error('Error in barcode string: '.$code
); }
31010 if (empty($x)) { $x
= $this
->x
; }
31011 if (empty($y)) { $y
= $this
->y
; }
31012 $prevDrawColor = $this->DrawColor
;
31013 $prevTextColor = $this->TextColor
;
31014 $prevFillColor = $this->FillColor
;
31015 $lw = $this->LineWidth
;
31016 $this->SetLineWidth(0.01);
31017 $size /= $k; // in case resized in a table
31018 $xres = $arrcode['nom-X'] * $size;
31020 if ($btype == 'IMB' || $btype == 'RM4SCC' || $btype == 'KIX' || $btype == 'POSTNET' || $btype == 'PLANET') {
31021 $llm = $arrcode['quietL'] / $k; // Left Quiet margin
31022 $rlm = $arrcode['quietR'] / $k; // Right Quiet margin
31023 $tlm = $blm = $arrcode['quietTB'] / $k;
31024 $height=1; // Overrides
31026 else if (in_array($btype, array('C128A','C128B','C128C','EAN128A','EAN128B','EAN128C','C39','C39+','C39E','C39E+','S25','S25+','I25','I25+','I25B','I25B+','C93','MSI','MSI+','CODABAR','CODE11'))) {
31027 $llm = $arrcode['lightmL'] * $xres; // Left Quiet margin
31028 $rlm = $arrcode['lightmR'] * $xres; // Right Quiet margin
31029 $tlm = $blm = $arrcode['lightTB'] * $xres * $height;
31033 $bcw = ($arrcode["maxw"] * $xres);
31034 $fbw = $bcw +
$llm +
$rlm; // Full barcode width incl. light margins
31036 $bch = ($arrcode["nom-H"] * $size * $height);
31037 $fbh = $bch +
$tlm +
$blm; // Full barcode height
31039 // PRINT border background color
31043 $this->SetDColor($col);
31044 $this->SetTColor($col);
31047 $this->SetDColor($this->ConvertColor(0));
31048 $this->SetTColor($this->ConvertColor(0));
31051 $this->SetFColor($bgcol);
31053 else { $this
->SetFColor($this
->ConvertColor(255)); }
31056 if ($col) { $this
->SetFColor($col
); }
31057 else { $this
->SetFColor($this
->ConvertColor(0)); }
31058 $xpos = $x +
$llm ;
31060 if ($arrcode !== false) {
31061 foreach ($arrcode["bcode"] AS $v) {
31062 $bw = ($v["w"] * $xres);
31064 $ypos = $y +
$tlm +
($bch * $v['p'] / $arrcode['maxh']);
31065 $this->Rect($xpos, $ypos, $bw, ($v['h'] * $bch / $arrcode['maxh']), 'F');
31071 // PRINT BEARER BARS
31072 if ($btype == 'I25B' || $btype == 'I25B+') {
31073 $this->Rect($x, $y, $fbw, ($arrcode['lightTB'] * $xres * $height), 'F');
31074 $this->Rect($x, $y+
$tlm+
$bch, $fbw, ($arrcode['lightTB'] * $xres * $height), 'F');
31077 // Restore **************
31078 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt);
31079 $this->DrawColor
= $prevDrawColor;
31080 $this->TextColor
= $prevTextColor;
31081 $this->FillColor
= $prevFillColor;
31082 $this->SetLineWidth($lw);
31086 /*-- END BARCODES --*/
31088 // ====================================================
31089 // ====================================================
31091 function StartTransform($returnstring=false) {
31092 if ($returnstring) { return('q'); }
31093 else { $this
->_out('q'); }
31095 function StopTransform($returnstring=false) {
31096 if ($returnstring) { return('Q'); }
31097 else { $this
->_out('Q'); }
31099 function transformScale($s_x, $s_y, $x='', $y='', $returnstring=false) {
31106 if (($s_x == 0) OR ($s_y == 0)) {
31107 $this->Error('Please do not use values equal to zero for scaling');
31109 $y = ($this->h
- $y) * _MPDFK
;
31111 //calculate elements of transformation matrix
31118 $tm[4] = $x * (1 - $s_x);
31119 $tm[5] = $y * (1 - $s_y);
31120 //scale the coordinate system
31121 if ($returnstring) { return($this
->_transform($tm
, true)); }
31122 else { $this
->_transform($tm
); }
31124 function transformTranslate($t_x, $t_y, $returnstring=false) {
31125 //calculate elements of transformation matrix
31130 $tm[4] = $t_x * _MPDFK
;
31131 $tm[5] = -$t_y * _MPDFK
;
31132 //translate the coordinate system
31133 if ($returnstring) { return($this
->_transform($tm
, true)); }
31134 else { $this
->_transform($tm
); }
31136 function transformRotate($angle, $x='', $y='', $returnstring=false) {
31144 $y = ($this->h
- $y) * _MPDFK
;
31146 //calculate elements of transformation matrix
31147 $tm[0] = cos(deg2rad($angle));
31148 $tm[1] = sin(deg2rad($angle));
31151 $tm[4] = $x +
$tm[1] * $y - $tm[0] * $x;
31152 $tm[5] = $y - $tm[0] * $y - $tm[1] * $x;
31153 //rotate the coordinate system around ($x,$y)
31154 if ($returnstring) { return($this
->_transform($tm
, true)); }
31155 else { $this
->_transform($tm
); }
31157 function _transform($tm, $returnstring=false) {
31158 if ($returnstring) { return(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm', $tm
[0], $tm
[1], $tm
[2], $tm
[3], $tm
[4], $tm
[5])); }
31159 else { $this
->_out(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm', $tm
[0], $tm
[1], $tm
[2], $tm
[3], $tm
[4], $tm
[5])); }
31165 // INDIC ============================
31166 // This conversion can only be done when font is set
31167 function ConvertIndic(&$str) {
31168 if (preg_match('/^ind_([a-z]{2})_/',$this->currentfontfamily
, $m)) {
31169 if (!class_exists('indic', false)) { include(_MPDF_PATH
.'classes/indic.php'); }
31170 if (empty($this->indic
)) { $this
->indic
= new indic($this
); }
31171 $earr = $this->UTF8StringToArray($str, false);
31172 $str = $this->indic
->substituteIndic($earr, $m[1], $this->currentfontfamily
);
31175 /*-- END INDIC --*/
31177 // AUTOFONT =========================
31178 function AutoFont($html) {
31179 if ($this->onlyCoreFonts
) { return $html
; }
31180 $this->useLang
= true;
31181 if ($this->autoFontGroupSize
== 1) { $extra
= $this
->pregASCIIchars1
; }
31182 else if ($this->autoFontGroupSize
== 3) { $extra
= $this
->pregASCIIchars3
; }
31183 else { $extra
= $this
->pregASCIIchars2
; }
31185 $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE
);
31186 foreach($a as $i => $e) {
31188 $e = strcode2utf($e);
31189 $e = $this->lesser_entity_decode($e);
31191 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31192 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31194 /*-- CJK-FONTS --*/
31195 if ($this->autoFontGroups
& AUTOFONT_CJK
) {
31196 $e = preg_replace("/([".$this->pregCJKchars
.$extra."]*[".$this->pregCJKchars
."][".$this->pregCJKchars
.$extra."]*)/ue", '$this->replaceCJK(stripslashes(\'\\1\'))', $e);
31198 /*-- END CJK-FONTS --*/
31201 if ($this->autoFontGroups
& AUTOFONT_RTL
) {
31203 $e = preg_replace("/([".$this->pregHEBchars
.$extra."]*[".$this->pregHEBchars
."][".$this->pregHEBchars
.$extra."]*)/u", "\xef\xbf\xb0span lang=\"he\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31205 $e = preg_replace("/([".$this->pregARABICchars
.$extra."]*[".$this->pregARABICchars
."][".$this->pregARABICchars
.$extra."]*)/ue", '$this->replaceArabic(stripslashes(\'\\1\'))', $e);
31211 if ($this->autoFontGroups
& AUTOFONT_INDIC
) {
31213 $e = preg_replace("/([".$this->pregBNchars
.$this->pregINDextra
."]*[".$this->pregBNchars
."][".$this->pregBNchars
.$this->pregINDextra
."]*)/u", "\xef\xbf\xb0span lang=\"bn\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31214 // Devanagari (= script for Hindi, Nepali + Sindhi)
31215 $e = preg_replace("/([".$this->pregHIchars
.$this->pregINDextra
."]*[".$this->pregHIchars
."][".$this->pregHIchars
.$this->pregINDextra
."]*)/u", "\xef\xbf\xb0span lang=\"hi\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31217 $e = preg_replace("/([".$this->pregGUchars
.$this->pregINDextra
."]*[".$this->pregGUchars
."][".$this->pregGUchars
.$this->pregINDextra
."]*)/u", "\xef\xbf\xb0span lang=\"gu\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31219 $e = preg_replace("/([".$this->pregMLchars
.$this->pregINDextra
."]*[".$this->pregMLchars
."][".$this->pregMLchars
.$this->pregINDextra
."]*)/u", "\xef\xbf\xb0span lang=\"ml\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31221 $e = preg_replace("/([".$this->pregKNchars
.$this->pregINDextra
."]*[".$this->pregKNchars
."][".$this->pregKNchars
.$this->pregINDextra
."]*)/u", "\xef\xbf\xb0span lang=\"kn\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31223 $e = preg_replace("/([".$this->pregORchars
.$this->pregINDextra
."]*[".$this->pregORchars
."][".$this->pregORchars
.$this->pregINDextra
."]*)/u", "\xef\xbf\xb0span lang=\"or\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31224 // Punjabi ?= Gurmuhki
31225 $e = preg_replace("/([".$this->pregPAchars
.$this->pregINDextra
."]*[".$this->pregPAchars
."][".$this->pregPAchars
.$this->pregINDextra
."]*)/u", "\xef\xbf\xb0span lang=\"pa\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31227 $e = preg_replace("/([".$this->pregTAchars
.$this->pregINDextra
."]*[".$this->pregTAchars
."][".$this->pregTAchars
.$this->pregINDextra
."]*)/u", "\xef\xbf\xb0span lang=\"ta\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31229 $e = preg_replace("/([".$this->pregTEchars
.$this->pregINDextra
."]*[".$this->pregTEchars
."][".$this->pregTEchars
.$this->pregINDextra
."]*)/u", "\xef\xbf\xb0span lang=\"te\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31231 /*-- END INDIC --*/
31234 if ($this->autoFontGroups
& AUTOFONT_THAIVIET
) {
31236 $e = preg_replace("/([\x{0E00}-\x{0E7F}".$extra."]*[\x{0E00}-\x{0E7F}][\x{0E00}-\x{0E7F}".$extra."]*)/u", "\xef\xbf\xb0span lang=\"th\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31238 $e = preg_replace("/([".$this->pregVIETchars
.$this->pregVIETPluschars
."]*[".$this->pregVIETchars
."][".$this->pregVIETchars
.$this->pregVIETPluschars
."]*)/u", "\xef\xbf\xb0span lang=\"vi\"\xef\xbf\xb1\\1\xef\xbf\xb0/span\xef\xbf\xb1", $e);
31241 $e = preg_replace('/[&]/','&',$e);
31242 $e = preg_replace('/[<]/','<',$e);
31243 $e = preg_replace('/[>]/','>',$e);
31244 $e = preg_replace("/(\xef\xbf\xb0span lang=\"([a-z\-A-Z]{2,5})\"\xef\xbf\xb1)\s+/",' \\1',$e);
31245 $e = preg_replace("/[ ]+(\xef\xbf\xb0\/span\xef\xbf\xb1)/",'\\1 ',$e);
31247 $e = preg_replace("/\xef\xbf\xb0span lang=\"([a-z\-A-Z]{2,5})\"\xef\xbf\xb1/","\xef\xbf\xb0span lang=\"\\1\" class=\"lang_\\1\"\xef\xbf\xb1",$e);
31249 $e = preg_replace("/\xef\xbf\xb0/",'<',$e);
31250 $e = preg_replace("/\xef\xbf\xb1/",'>',$e);
31255 $a[$i] = '<'.$e.'>';
31258 $n = implode('',$a);
31263 /*-- CJK-FONTS --*/
31264 function replaceCJK($str) {
31265 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31266 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31267 if (preg_match("/[".$this->pregUHCchars
."]/u", $str)) {
31268 return "\xef\xbf\xb0span lang=\"ko\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31270 else if (preg_match("/[".$this->pregSJISchars
."]/u", $str)) {
31271 return "\xef\xbf\xb0span lang=\"ja\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31273 // if in Unicode Plane 2, probably HKCS (incl in BIG5) if not Japanese
31274 else if (preg_match("/[\x{20000}-\x{2FFFF}]/u", $str)) {
31275 return "\xef\xbf\xb0span lang=\"zh-HK\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31278 return "\xef\xbf\xb0span lang=\"zh-CN\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31282 /*-- END CJK-FONTS --*/
31285 function replaceArabic($str) {
31286 // PASHTO, SINDHI, URDU, ARABIC, PERSIAN
31287 $persian = "\x{067E}\x{0686}\x{0698}\x{06AF}";
31289 $urdu = "\x{0679}\x{0688}\x{0691}\x{06BA}\x{06BE}\x{06C1}\x{06D2}";
31290 $pashto = "\x{067C}\x{0681}\x{0685}\x{0689}\x{0693}\x{0696}\x{069A}\x{06BC}\x{06D0}"; // ? and U+06AB, U+06CD
31291 $sindhi = "\x{067A}\x{067B}\x{067D}\x{067F}\x{0680}\x{0684}\x{068D}\x{068A}\x{068F}\x{068C}\x{0687}\x{0683}\x{0699}\x{06AA}\x{06A6}\x{06BB}\x{06B1}\x{06B3}";
31292 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31293 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31295 if (preg_match("/[".$this->pregNonARABICchars
."]/u", $str) ) {
31296 if (preg_match("/[".$sindhi ."]/u", $str) ) {
31297 return "\xef\xbf\xb0span lang=\"sd\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31299 else if (preg_match("/[".$urdu ."]/u", $str) ) {
31300 return "\xef\xbf\xb0span lang=\"ur\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31302 else if (preg_match("/[".$pashto ."]/u", $str) ) {
31303 return "\xef\xbf\xb0span lang=\"ps\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31305 else if (preg_match("/[".$persian ."]/u", $str) ) {
31306 return "\xef\xbf\xb0span lang=\"fa\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31309 return "\xef\xbf\xb0span lang=\"ar\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31312 if (preg_match("/[".$persian ."]/u", $str) ) {
31313 return "\xef\xbf\xb0span lang=\"fa\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31316 return "\xef\xbf\xb0span lang=\"ar\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31321 // ARABIC ===========================
31323 function InitArabic() {
31325 // JOIN TO FOLLOWING LETTER IN LOGICAL ORDER (i.e. AS INITIAL)
31326 $this->arabPrevLink
= "";
31327 // U+060c; U+061b; U+061f; U+0626; U+0628;
31328 $this->arabPrevLink
.= "\xd8\x8c\xd8\x9b\xd8\x9f\xd8\xa6\xd8\xa8";
31329 // U+062a; U+062b; U+062c; U+062d; U+062e;
31330 $this->arabPrevLink
.= "\xd8\xaa\xd8\xab\xd8\xac\xd8\xad\xd8\xae";
31331 // U+0633; U+0634; U+0635; U+0636; U+0637; U+0638; U+0639; U+063a;
31332 $this->arabPrevLink
.= "\xd8\xb3\xd8\xb4\xd8\xb5\xd8\xb6\xd8\xb7\xd8\xb8\xd8\xb9\xd8\xba";
31333 // U+0640; U+0641; U+0642; U+0643; U+0644; U+0645; U+0646; U+0647; U+0649; U+064a;
31334 $this->arabPrevLink
.= "\xd9\x80\xd9\x81\xd9\x82\xd9\x83\xd9\x84\xd9\x85\xd9\x86\xd9\x87\xd9\x89\xd9\x8a";
31335 // U+0678; U+0679; U+067a; U+067b; U+067c; U+067d; U+067e; U+067f;
31336 $this->arabPrevLink
.= "\xd9\xb8\xd9\xb9\xd9\xba\xd9\xbb\xd9\xbc\xd9\xbd\xd9\xbe\xd9\xbf";
31337 // U+0680; U+0681; U+0682; U+0683; U+0684; U+0685; U+0686; U+0687;
31338 $this->arabPrevLink
.= "\xda\x80\xda\x81\xda\x82\xda\x83\xda\x84\xda\x85\xda\x86\xda\x87";
31339 // U+069a; U+069b; U+069c; U+069d; U+069e; U+069f;
31340 $this->arabPrevLink
.= "\xda\x9a\xda\x9b\xda\x9c\xda\x9d\xda\x9e\xda\x9f";
31341 // U+06a0; U+06a1; U+06a2; U+06a3; U+06a4; U+06a5; U+06a6; U+06A7; U+06A8;
31342 $this->arabPrevLink
.= "\xda\xa0\xda\xa1\xda\xa2\xda\xa3\xda\xa4\xda\xa5\xda\xa6\xda\xa7\xda\xa8";
31343 // U+06a9; U+06aa; U+06ab; U+06ac; U+06ad; U+06ae; U+06af;
31344 $this->arabPrevLink
.= "\xda\xa9\xda\xaa\xda\xab\xda\xac\xda\xad\xda\xae\xda\xaf";
31345 // U+06b0; U+06b1; U+06b2; U+06b3; U+06b4; U+06b5; U+06b6; U+06b7; U+06b8; U+06b9;
31346 $this->arabPrevLink
.= "\xda\xb0\xda\xb1\xda\xb2\xda\xb3\xda\xb4\xda\xb5\xda\xb6\xda\xb7\xda\xb8\xda\xb9";
31347 // U+06ba; U+06bb; U+06bc; U+06be; U+06bf;
31348 $this->arabPrevLink
.= "\xda\xba\xda\xbb\xda\xbc\xda\xbe\xda\xbf";
31349 // U+06c1; U+06cc; U+06ce; U+06d0; U+06d1;
31350 $this->arabPrevLink
.= "\xdb\x81\xdb\x8c\xdb\x8e\xdb\x90\xdb\x91";
31355 // JOIN TO PREVIOUS LETTER IN LOGICAL ORDER (i.e. AS FINAL FORM)
31356 $this->arabNextLink
= "";
31357 // U+0622; U+0623; U+0624; U+0625; U+0626; U+0627; U+0628; U+0629;
31358 $this->arabNextLink
.= "\xd8\xa2\xd8\xa3\xd8\xa4\xd8\xa5\xd8\xa6\xd8\xa7\xd8\xa8\xd8\xa9";
31359 // U+062A; U+062B; U+062C; U+062D; U+062E; U+062F;
31360 $this->arabNextLink
.= "\xd8\xaa\xd8\xab\xd8\xac\xd8\xad\xd8\xae\xd8\xaf";
31361 // U+0630; U+0631; U+0632; U+0633; U+0634; U+0635; U+0636; U+0637; U+0638; U+0639; U+063A;
31362 $this->arabNextLink
.= "\xd8\xb0\xd8\xb1\xd8\xb2\xd8\xb3\xd8\xb4\xd8\xb5\xd8\xb6\xd8\xb7\xd8\xb8\xd8\xb9\xd8\xba";
31363 // U+0640; U+0641; U+0642; U+0643; U+0644; U+0645; U+0646; U+0647; U+0648; U+0649; U+064A;
31364 $this->arabNextLink
.= "\xd9\x80\xd9\x81\xd9\x82\xd9\x83\xd9\x84\xd9\x85\xd9\x86\xd9\x87\xd9\x88\xd9\x89\xd9\x8a";
31365 // U+0671; U+0672; U+0675; U+0676; U+0677; U+0678; U+0679;
31366 $this->arabNextLink
.= "\xd9\xb1\xd9\xb2\xd9\xb5\xd9\xb6\xd9\xb7\xd9\xb8\xd9\xb9";
31367 // U+067A; U+067B; U+067C; U+067D; U+067E; U+067F;
31368 $this->arabNextLink
.= "\xd9\xba\xd9\xbb\xd9\xbc\xd9\xbd\xd9\xbe\xd9\xbf";
31369 // U+0680; U+0681; U+0682; U+0683; U+0684; U+0685; U+0686; U+0687; U+0688; U+0689;
31370 $this->arabNextLink
.= "\xda\x80\xda\x81\xda\x82\xda\x83\xda\x84\xda\x85\xda\x86\xda\x87\xda\x88\xda\x89";
31371 // U+068A; U+068B; U+068C; U+068D; U+068F;U+068F;
31372 $this->arabNextLink
.= "\xda\x8a\xda\x8b\xda\x8c\xda\x8d\xda\x8e\xda\x8f";
31373 // U+0690; U+0691; U+0692; U+0693; U+0694; U+0695; U+0696; U+0697; U+0698; U+0699;
31374 $this->arabNextLink
.= "\xda\x90\xda\x91\xda\x92\xda\x93\xda\x94\xda\x95\xda\x96\xda\x97\xda\x98\xda\x99";
31375 // U+069A; U+069B; U+069C; U+069D; U+069E; U+069F;
31376 $this->arabNextLink
.= "\xda\x9a\xda\x9b\xda\x9c\xda\x9d\xda\x9e\xda\x9f";
31377 // U+06A0; U+06A1; U+06A2; U+06A3; U+06A4; U+06A5; U+06A6; U+06A7; U+06A8; U+06A9;
31378 $this->arabNextLink
.= "\xda\xa0\xda\xa1\xda\xa2\xda\xa3\xda\xa4\xda\xa5\xda\xa6\xda\xa7\xda\xa8\xda\xa9";
31379 // U+06AA; U+06AB; U+06AC; U+06AD; U+06AE; U+06AF;
31380 $this->arabNextLink
.= "\xda\xaa\xda\xab\xda\xac\xda\xad\xda\xae\xda\xaf";
31381 // U+06B0; U+06B1; U+06B2; U+06B3; U+06B4; U+06B5; U+06B6; U+06B7; U+06B8; U+06B9;
31382 $this->arabNextLink
.= "\xda\xb0\xda\xb1\xda\xb2\xda\xb3\xda\xb4\xda\xb5\xda\xb6\xda\xb7\xda\xb8\xda\xb9";
31383 // U+06BA; U+06BB; U+06BC; U+06BE; U+06BF;
31384 $this->arabNextLink
.= "\xda\xba\xda\xbb\xda\xbc\xda\xbe\xda\xbf";
31385 // U+06C0; U+06C1; U+06C2; U+06C3; U+06C4; U+06C5; U+06C6; U+06C7; U+06C8; U+06C9;
31386 $this->arabNextLink
.= "\xdb\x80\xdb\x81\xdb\x82\xdb\x83\xdb\x84\xdb\x85\xdb\x86\xdb\x87\xdb\x88\xdb\x89";
31387 // U+06CA; U+06CB; U+06CC; U+06CD; U+06CE; U+06CF;
31388 $this->arabNextLink
.= "\xdb\x8a\xdb\x8b\xdb\x8c\xdb\x8d\xdb\x8e\xdb\x8f";
31389 // U+06D0; U+06d1; U+06D2; U+06D3;
31390 $this->arabNextLink
.= "\xdb\x90\xdb\x91\xdb\x92\xdb\x93";
31395 // U+064b U+064c; U+064d; U+064e; U+064f; U+0650; U+0651; U+0652;
31396 $this->arabVowels
= "\xd9\x8b\xd9\x8c\xd9\x8d\xd9\x8e\xd9\x8f\xd9\x90\xd9\x91\xd9\x92";
31398 // Added chars that may not be vowels but should not interrupt joining
31400 $this->arabVowels
.= "\xd9\xb0\xd9\x93";
31401 // ? should also add - U+615, 616, 617-61A, 653-65E, 6D6-6DC, 6DF-6E4, 6E7, 6E8, 6EA-6ED
31405 // ISOLATED FORM :: FINAL :: INITIAL :: MEDIAL
31406 // FB** - FE** = Arabic presentation Forms
31407 // F5** F6** F7** = Private use area used by unAGlyphs in mPDF
31408 $this->arabGlyphs
= array(
31409 "\xd8\x8c"=>array("\xd8\x8c", "\xd8\x8c", "\xd8\x8c", "\xd8\x8c"), /* 060C, 060C, 060C, 060C */
31410 "\xd8\x9b"=>array("\xd8\x9b", "\xd8\x9b", "\xd8\x9b", "\xd8\x9b"), /* 061B, 061B, 061B, 061B */
31411 "\xd8\x9f"=>array("\xd8\x9f", "\xd8\x9f", "\xd8\x9f", "\xd8\x9f"), /* 061F, 061F, 061F, 061F */
31412 "\xd8\xa1"=>array("\xd8\xa1", "\xd8\xa1", "\xd8\xa1", "\xd8\xa1"), /* 0621, 0621, 0621, 0621 */
31413 "\xd8\xa2"=>array("\xd8\xa2", "\xef\xba\x82", "\xd8\xa2", "\xef\xba\x82"), /* 0622, FE82, 0622, FE82 */
31414 "\xd8\xa3"=>array("\xd8\xa3", "\xef\xba\x84", "\xd8\xa3", "\xef\xba\x84"), /* 0623, FE84, 0623, FE84 */
31415 "\xd8\xa4"=>array("\xd8\xa4", "\xef\xba\x86", "\xd8\xa4", "\xef\xba\x86"), /* 0624, FE86, 0624, FE86 */
31416 "\xd8\xa5"=>array("\xd8\xa5", "\xef\xba\x88", "\xd8\xa5", "\xef\xba\x88"), /* 0625, FE88, 0625, FE88 */
31417 "\xd8\xa6"=>array("\xd8\xa6", "\xef\xba\x8a", "\xef\xba\x8b", "\xef\xba\x8c"), /* 0626, FE8A, FE8B, FE8C */
31418 "\xd8\xa7"=>array("\xd8\xa7", "\xef\xba\x8e", "\xd8\xa7", "\xef\xba\x8e"), /* 0627, FE8E, 0627, FE8E */
31419 "\xd8\xa8"=>array("\xd8\xa8", "\xef\xba\x90", "\xef\xba\x91", "\xef\xba\x92"), /* 0628, FE90, FE91, FE92 */
31420 "\xd8\xa9"=>array("\xd8\xa9", "\xef\xba\x94", "\xd8\xa9", "\xef\xba\x94"), /* 0629, FE94, 0629, FE94 */
31421 "\xd8\xaa"=>array("\xd8\xaa", "\xef\xba\x96", "\xef\xba\x97", "\xef\xba\x98"), /* 062A, FE96, FE97, FE98 */
31422 "\xd8\xab"=>array("\xd8\xab", "\xef\xba\x9a", "\xef\xba\x9b", "\xef\xba\x9c"), /* 062B, FE9A, FE9B, FE9C */
31423 "\xd8\xac"=>array("\xd8\xac", "\xef\xba\x9e", "\xef\xba\x9f", "\xef\xba\xa0"), /* 062C, FE9E, FE9F, FEA0 */
31424 "\xd8\xad"=>array("\xd8\xad", "\xef\xba\xa2", "\xef\xba\xa3", "\xef\xba\xa4"), /* 062D, FEA2, FEA3, FEA4 */
31425 "\xd8\xae"=>array("\xd8\xae", "\xef\xba\xa6", "\xef\xba\xa7", "\xef\xba\xa8"), /* 062E, FEA6, FEA7, FEA8 */
31426 "\xd8\xaf"=>array("\xd8\xaf", "\xef\xba\xaa", "\xd8\xaf", "\xef\xba\xaa"), /* 062F, FEAA, 062F, FEAA */
31427 "\xd8\xb0"=>array("\xd8\xb0", "\xef\xba\xac", "\xd8\xb0", "\xef\xba\xac"), /* 0630, FEAC, 0630, FEAC */
31428 "\xd8\xb1"=>array("\xd8\xb1", "\xef\xba\xae", "\xd8\xb1", "\xef\xba\xae"), /* 0631, FEAE, 0631, FEAE */
31429 "\xd8\xb2"=>array("\xd8\xb2", "\xef\xba\xb0", "\xd8\xb2", "\xef\xba\xb0"), /* 0632, FEB0, 0632, FEB0 */
31430 "\xd8\xb3"=>array("\xd8\xb3", "\xef\xba\xb2", "\xef\xba\xb3", "\xef\xba\xb4"), /* 0633, FEB2, FEB3, FEB4 */
31431 "\xd8\xb4"=>array("\xd8\xb4", "\xef\xba\xb6", "\xef\xba\xb7", "\xef\xba\xb8"), /* 0634, FEB6, FEB7, FEB8 */
31432 "\xd8\xb5"=>array("\xd8\xb5", "\xef\xba\xba", "\xef\xba\xbb", "\xef\xba\xbc"), /* 0635, FEBA, FEBB, FEBC */
31433 "\xd8\xb6"=>array("\xd8\xb6", "\xef\xba\xbe", "\xef\xba\xbf", "\xef\xbb\x80"), /* 0636, FEBE, FEBF, FEC0 */
31434 "\xd8\xb7"=>array("\xd8\xb7", "\xef\xbb\x82", "\xef\xbb\x83", "\xef\xbb\x84"), /* 0637, FEC2, FEC3, FEC4 */
31435 "\xd8\xb8"=>array("\xd8\xb8", "\xef\xbb\x86", "\xef\xbb\x87", "\xef\xbb\x88"), /* 0638, FEC6, FEC7, FEC8 */
31436 "\xd8\xb9"=>array("\xd8\xb9", "\xef\xbb\x8a", "\xef\xbb\x8b", "\xef\xbb\x8c"), /* 0639, FECA, FECB, FECC */
31437 "\xd8\xba"=>array("\xd8\xba", "\xef\xbb\x8e", "\xef\xbb\x8f", "\xef\xbb\x90"), /* 063A, FECE, FECF, FED0 */
31438 "\xd9\x80"=>array("\xd9\x80", "\xd9\x80", "\xd9\x80", "\xd9\x80"), /* 0640, 0640, 0640, 0640 */
31439 "\xd9\x81"=>array("\xd9\x81", "\xef\xbb\x92", "\xef\xbb\x93", "\xef\xbb\x94"), /* 0641, FED2, FED3, FED4 */
31440 "\xd9\x82"=>array("\xd9\x82", "\xef\xbb\x96", "\xef\xbb\x97", "\xef\xbb\x98"), /* 0642, FED6, FED7, FED8 */
31441 "\xd9\x83"=>array("\xd9\x83", "\xef\xbb\x9a", "\xef\xbb\x9b", "\xef\xbb\x9c"), /* 0643, FEDA, FEDB, FEDC */
31442 "\xd9\x84"=>array("\xd9\x84", "\xef\xbb\x9e", "\xef\xbb\x9f", "\xef\xbb\xa0"), /* 0644, FEDE, FEDF, FEE0 */
31443 "\xd9\x85"=>array("\xd9\x85", "\xef\xbb\xa2", "\xef\xbb\xa3", "\xef\xbb\xa4"), /* 0645, FEE2, FEE3, FEE4 */
31444 "\xd9\x86"=>array("\xd9\x86", "\xef\xbb\xa6", "\xef\xbb\xa7", "\xef\xbb\xa8"), /* 0646, FEE6, FEE7, FEE8 */
31445 "\xd9\x87"=>array("\xd9\x87", "\xef\xbb\xaa", "\xef\xbb\xab", "\xef\xbb\xac"), /* 0647, FEEA, FEEB, FEEC */
31446 "\xd9\x88"=>array("\xd9\x88", "\xef\xbb\xae", "\xd9\x88", "\xef\xbb\xae"), /* 0648, FEEE, 0648, FEEE */
31448 /* 0649 Alef Maksura should only appear at end of word (in Arabic) So Initial and medial are shown as isolated/final */
31449 "\xd9\x89"=>array("\xd9\x89", "\xef\xbb\xb0", "\xd9\x89", "\xef\xbb\xb0"), /* 0649, FEF0, 0649, FEF0 */
31451 /* 0649 Alef Maksura Initial and Medial forms as given in Unicode FBE8 and FBE9 for Uighur Kazakh (not in some fonts) */
31452 "\xd9\x89"=>array("\xd9\x89", "\xef\xbb\xb0", "\xef\xaf\xa8", "\xef\xaf\xa9"), /* 0649, FEF0, FBE8, FBE9 not in most fonts */
31454 "\xd9\x8a"=>array("\xd9\x8a", "\xef\xbb\xb2", "\xef\xbb\xb3", "\xef\xbb\xb4"), /* 064A, FEF2, FEF3, FEF4 */
31455 "\xd9\x8b"=>array("\xd9\x8b", "\xd9\x8b", "\xd9\x8b", "\xd9\x8b"), /* 064B, 064B, 064B, 064B */
31456 "\xd9\x8c"=>array("\xd9\x8c", "\xd9\x8c", "\xd9\x8c", "\xd9\x8c"), /* 064C, 064C, 064C, 064C */
31457 "\xd9\x8d"=>array("\xd9\x8d", "\xd9\x8d", "\xd9\x8d", "\xd9\x8d"), /* 064D, 064D, 064D, 064D */
31458 "\xd9\x8e"=>array("\xd9\x8e", "\xd9\x8e", "\xd9\x8e", "\xd9\x8e"), /* 064E, 064E, 064E, 064E */
31459 "\xd9\x8f"=>array("\xd9\x8f", "\xd9\x8f", "\xd9\x8f", "\xd9\x8f"), /* 064F, 064F, 064F, 064F */
31460 "\xd9\x90"=>array("\xd9\x90", "\xd9\x90", "\xd9\x90", "\xd9\x90"), /* 0650, 0650, 0650, 0650 */
31461 "\xd9\x91"=>array("\xd9\x91", "\xd9\x91", "\xd9\x91", "\xd9\x91"), /* 0651, 0651, 0651, 0651 */
31462 "\xd9\x92"=>array("\xd9\x92", "\xd9\x92", "\xd9\x92", "\xd9\x92"), /* 0652, 0652, 0652, 0652 */
31463 "\xd9\xb1"=>array("\xd9\xb1", "\xef\xad\x91", "\xd9\xb1", "\xef\xad\x91"), /* 0671, FB51, 0671, FB51 */
31464 "\xd9\xb2"=>array("\xd9\xb2", "\xef\x95\xb2", "\xd9\xb2", "\xef\x95\xb2"), /* 0672, F572, 0672, F572 */
31465 "\xd9\xb5"=>array("\xd9\xb5", "\xef\x95\xb5", "\xd9\xb5", "\xef\x95\xb5"), /* 0675, F575, 0675, F575 */
31466 "\xd9\xb8"=>array("\xd9\xb8", "\xef\x95\xb8", "\xef\xba\x8b", "\xef\xba\x8c"), /* 0678, F578, FE8B, FE8C ( as 0626 ) */
31467 "\xd9\xb9"=>array("\xd9\xb9", "\xef\xad\xa7", "\xef\xad\xa8", "\xef\xad\xa9"), /* 0679, FB67, FB68, FB69 */
31468 "\xd9\xba"=>array("\xd9\xba", "\xef\xad\x9f", "\xef\xad\xa0", "\xef\xad\xa1"), /* 067A, FB5F, FB60, FB61 */
31469 "\xd9\xbb"=>array("\xd9\xbb", "\xef\xad\x93", "\xef\xad\x94", "\xef\xad\x95"), /* 067B, FB53, FB54, FB55 */
31470 "\xd9\xbc"=>array("\xd9\xbc", "\xef\x95\xbc", "\xef\x99\xbc", "\xef\x9d\xbc"), /* 067C, F57C, F67C, F77C */
31471 "\xd9\xbd"=>array("\xd9\xbd", "\xef\x95\xbd", "\xef\x99\xbd", "\xef\x9d\xbd"), /* 067D, F57D, F67D, F77D */
31472 "\xd9\xbe"=>array("\xd9\xbe", "\xef\xad\x97", "\xef\xad\x98", "\xef\xad\x99"), /* 067E, FB57, FB58, FB59 */
31473 "\xd9\xbf"=>array("\xd9\xbf", "\xef\xad\xa3", "\xef\xad\xa4", "\xef\xad\xa5"), /* 067F, FB63, FB64, FB65 */
31474 "\xda\x80"=>array("\xda\x80", "\xef\xad\x9b", "\xef\xad\x9c", "\xef\xad\x9d"), /* 0680, FB5B, FB5C, FB5D */
31475 "\xda\x81"=>array("\xda\x81", "\xef\x96\x81", "\xef\x9a\x81", "\xef\x9e\x81"), /* 0681, F581, F681, F781 */
31476 "\xda\x82"=>array("\xda\x82", "\xef\x96\x82", "\xef\x9a\x82", "\xef\x9e\x82"), /* 0682, F582, F682, F782 */
31477 "\xda\x83"=>array("\xda\x83", "\xef\xad\xb7", "\xef\xad\xb8", "\xef\xad\xb9"), /* 0683, FB77, FB78, FB79 */
31478 "\xda\x84"=>array("\xda\x84", "\xef\xad\xb3", "\xef\xad\xb4", "\xef\xad\xb5"), /* 0684, FB73, FB74, FB75 */
31479 "\xda\x85"=>array("\xda\x85", "\xef\x96\x85", "\xef\x9a\x85", "\xef\x9e\x85"), /* 0685, F585, F685, F785 */
31480 "\xda\x86"=>array("\xda\x86", "\xef\xad\xbb", "\xef\xad\xbc", "\xef\xad\xbd"), /* 0686, FB7B, FB7C, FB7D */
31481 "\xda\x87"=>array("\xda\x87", "\xef\xad\xbf", "\xef\xae\x80", "\xef\xae\x81"), /* 0687, FB7F, FB80, FB81 */
31482 "\xda\x88"=>array("\xda\x88", "\xef\xae\x89", "\xda\x88", "\xda\x88"), /* 0688, FB89, 0688, 0688 */
31483 "\xda\x89"=>array("\xda\x89", "\xef\x96\x89", "\xda\x89", "\xda\x89"), /* 0689, F589, 0689, 0689 */
31484 "\xda\x91"=>array("\xda\x91", "\xef\xae\x8d", "\xda\x91", "\xef\xae\x8d"), /* 0691, FB8D, 0691, FB8D */
31485 "\xda\x93"=>array("\xda\x93", "\xef\x96\x93", "\xda\x93", "\xda\x93"), /* 0693, F593, 0693, 0693 */
31486 "\xda\x96"=>array("\xda\x96", "\xef\x96\x96", "\xda\x96", "\xda\x96"), /* 0696, F596, 0696, 0696 */
31487 "\xda\x98"=>array("\xda\x98", "\xef\xae\x8b", "\xda\x98", "\xef\xae\x8b"), /* 0698, FB8B, 0698, FB8B */
31488 "\xda\x9a"=>array("\xda\x9a", "\xef\x96\x9a", "\xef\x9a\x9a", "\xef\x9e\x9a"), /* 069A, F59A, F69A, F79A */
31489 "\xda\x9b"=>array("\xda\x9b", "\xef\x96\x9b", "\xef\x9a\x9b", "\xef\x9e\x9b"), /* 069B, F59B, F69B, F79B */
31490 "\xda\x9c"=>array("\xda\x9c", "\xef\x96\x9c", "\xef\x9a\x9c", "\xef\x9e\x9c"), /* 069C, F59C, F69C, F79C */
31491 "\xda\x9d"=>array("\xda\x9d", "\xef\x96\x9d", "\xef\x9a\x9d", "\xef\x9e\x9d"), /* 069D, F59D, F69D, F79D */
31492 "\xda\x9e"=>array("\xda\x9e", "\xef\x96\x9e", "\xef\x9a\x9e", "\xef\x9e\x9e"), /* 069E, F59E, F69E, F79E */
31493 "\xda\xa0"=>array("\xda\xa0", "\xef\x96\xa0", "\xef\x9a\xa0", "\xef\x9e\xa0"), /* 06A0, F5A0, F6A0, F7A0 */
31494 "\xda\xa1"=>array("\xda\xa1", "\xef\x96\xa1", "\xef\x9a\xa1", "\xef\x9e\xa1"), /* 06A1, F5A1, F6A1, F7A1 */
31495 "\xda\xa2"=>array("\xda\xa2", "\xef\x96\xa2", "\xef\x9a\xa2", "\xef\x9e\xa2"), /* 06A2, F5A2, F6A2, F7A2 */
31496 "\xda\xa3"=>array("\xda\xa3", "\xef\x96\xa3", "\xef\x9a\xa3", "\xef\x9e\xa3"), /* 06A3, F5A3, F6A3, F7A3 */
31497 "\xda\xa4"=>array("\xda\xa4", "\xef\xad\xab", "\xef\xad\xac", "\xef\xad\xad"), /* 06A4, FB6B, FB6C, FB6D */
31498 "\xda\xa5"=>array("\xda\xa5", "\xef\x96\xa5", "\xef\x9a\xa5", "\xef\x9e\xa5"), /* 06A5, F5A5, F6A5, F7A5 */
31499 "\xda\xa6"=>array("\xda\xa6", "\xef\xad\xaf", "\xef\xad\xb0", "\xef\xad\xb1"), /* 06A6, FB6F, FB70, FB71 */
31500 "\xda\xa9"=>array("\xda\xa9", "\xef\xae\x8f", "\xef\xae\x90", "\xef\xae\x91"), /* 06A9, FB8F, FB90, FB91 */
31501 "\xda\xaa"=>array("\xda\xaa", "\xef\x96\xaa", "\xef\x9a\xaa", "\xef\x9e\xaa"), /* 06AA, F5AA, F6AA, F7AA */
31502 "\xda\xab"=>array("\xda\xab", "\xef\x96\xab", "\xef\x9a\xab", "\xef\x9e\xab"), /* 06AB, F5AB, F6AB, F7AB */
31503 "\xda\xac"=>array("\xda\xac", "\xef\x96\xac", "\xef\x9a\xac", "\xef\x9e\xac"), /* 06AC, F5AC, F6AC, F7AC */
31504 "\xda\xad"=>array("\xda\xad", "\xef\xaf\x94", "\xef\xaf\x95", "\xef\xaf\x96"), /* 06AD, FBD4, FBD5, FBD6 */
31505 "\xda\xae"=>array("\xda\xae", "\xef\x96\xae", "\xef\x9a\xae", "\xef\x9e\xae"), /* 06AE, F5AE, F6AE, F7AE */
31506 "\xda\xaf"=>array("\xda\xaf", "\xef\xae\x93", "\xef\xae\x94", "\xef\xae\x95"), /* 06Af, FB93, FB94, FB95 */
31507 "\xda\xb0"=>array("\xda\xb0", "\xef\x96\xb0", "\xef\x9a\xb0", "\xef\x9e\xb0"), /* 06B0, F5B0, F6B0, F7B0 */
31508 "\xda\xb1"=>array("\xda\xb1", "\xef\xae\x9b", "\xef\xae\x9c", "\xef\xae\x9d"), /* 06B1, FB9B, FB9C, FB9D */
31509 "\xda\xb2"=>array("\xda\xb2", "\xef\x96\xb2", "\xef\x9a\xb2", "\xef\x9e\xb2"), /* 06B2, F5B2, F6B2, F7B2 */
31510 "\xda\xb3"=>array("\xda\xb3", "\xef\xae\x97", "\xef\xae\x98", "\xef\xae\x99"), /* 06B3, FB97, FB98, FB99 */
31511 "\xda\xb4"=>array("\xda\xb4", "\xef\x96\xb4", "\xef\x9a\xb4", "\xef\x9e\xb4"), /* 06B4, F5B4, F6B4, F7B4 */
31512 "\xda\xb5"=>array("\xda\xb5", "\xef\x96\xb5", "\xef\x9a\xb5", "\xef\x9e\xb5"), /* 06B5, F5B5, F6B5, F7B5 */
31513 "\xda\xb6"=>array("\xda\xb6", "\xef\x96\xb6", "\xef\x9a\xb6", "\xef\x9e\xb6"), /* 06B6, F5B6, F6B6, F7B6 */
31514 "\xda\xb7"=>array("\xda\xb7", "\xef\x96\xb7", "\xef\x9a\xb7", "\xef\x9e\xb7"), /* 06B7, F5B7, F6B7, F7B7 */
31515 "\xda\xb8"=>array("\xda\xb8", "\xef\x96\xb8", "\xef\x9a\xb8", "\xef\x9e\xb8"), /* 06B8, F5B8, F6B8, F7B8 */
31516 "\xda\xb9"=>array("\xda\xb9", "\xef\x96\xb9", "\xef\x9a\xb9", "\xef\x9e\xb9"), /* 06B9, F5B9, F6B9, F7B9 */
31517 "\xda\xba"=>array("\xda\xba", "\xef\xae\x9f", "\xda\xba", "\xda\xba"), /* 06BA, FB9F, 06BA, 06BA */
31518 "\xda\xbb"=>array("\xda\xbb", "\xef\xae\xa1", "\xef\xae\xa2", "\xef\xae\xa3"), /* 06BB, FBA1, FBA2, FBA3 */
31519 "\xda\xbc"=>array("\xda\xbc", "\xef\x96\xbc", "\xef\x9a\xbc", "\xef\x9e\xbc"), /* 06BC, F5BC, F6BC, F7BC */
31520 "\xda\xbe"=>array("\xda\xbe", "\xef\xae\xab", "\xef\xae\xac", "\xef\xae\xad"), /* 06BE, FBAB, FBAC, FBAD */
31521 "\xda\xbf"=>array("\xda\xbf", "\xef\x96\xbf", "\xef\x9a\xbf", "\xef\x9e\xbf"), /* 06BF, F5BF, F6BF, F7BF */
31522 "\xdb\x80"=>array("\xdb\x80", "\xef\xae\xa5", "\xdb\x80", "\xef\xae\xa5"), /* 06C0, FBA5, 06C0, FBA5 */
31523 "\xdb\x81"=>array("\xdb\x81", "\xef\xae\xa7", "\xef\xae\xa8", "\xef\xae\xa9"), /* 06C1, FBA7, FBA8, FBA9 */
31524 "\xdb\x8c"=>array("\xdb\x8c", "\xef\xaf\xbd", "\xef\xaf\xbe", "\xef\xaf\xbf"), /* 06CC, FBFD, FBFE, FBFF */
31525 "\xdb\x8d"=>array("\xdb\x8d", "\xef\x97\x8d", "\xdb\x8d", "\xef\x97\x8d"), /* 06CD, F5CD, 06CD, F5CD */
31526 "\xdb\x8e"=>array("\xdb\x8e", "\xef\x97\x8e", "\xef\x9b\x8e", "\xef\x9f\x8e"), /* 06CE, F5CE, F6CE, F7CE */
31527 "\xdb\x90"=>array("\xdb\x90", "\xef\xaf\xa5", "\xef\xaf\xa6", "\xef\xaf\xa7"), /* 06D0, FBE5, FBE6, FBE7 */
31528 "\xdb\x91"=>array("\xdb\x91", "\xef\x97\x91", "\xef\xad\x98", "\xef\xad\x99"), /* 06D1, F5D1, FB58, FB59 Fudge borrows from 067E */
31529 "\xdb\x92"=>array("\xdb\x92", "\xef\xae\xaf", "\xdb\x92", "\xef\xae\xaf"), /* 06D2, FBAF, 06D2, FBAF */
31530 "\xdb\x93"=>array("\xdb\x93", "\xef\xae\xb1", "\xdb\x93", "\xef\xae\xb1"), /* 06D3, FBB1, 06D3, FBB1 */
31534 // LAM with ALEF ligatures (Mandatory ligatures)
31536 // U+0644; U+0622; U+0644; U+0623; U+0644; U+0625; U+0644; U+0627;
31537 $this->arabLigGlyphs
= "\xd9\x84\xd8\xa2\xd9\x84\xd8\xa3\xd9\x84\xd8\xa5\xd9\x84\xd8\xa7";
31538 $this->arabLigHex
= 'FEF5FEF6FEF5FEF6FEF7FEF8FEF7FEF8FEF9FEFAFEF9FEFAFEFBFEFCFEFBFEFC';
31543 function ArabJoin($str) {
31544 if (!$this->arabGlyphs
) { $this
->InitArabic(); }
31549 $chars = preg_split('//u', $str);
31550 $max = count($chars);
31551 for ($i = $max - 1; $i >= 0; $i--) {
31552 $crntChar = $chars[$i];
31553 if ($i > 0){ $prevChar
= $chars
[$i
- 1]; }
31554 else{ $prevChar
= NULL; }
31555 if ($prevChar && mb_strpos($this->arabVowels
, $prevChar, 0, 'utf-8') !== false) {
31556 $prevChar = $chars[$i - 2];
31557 if ($prevChar && mb_strpos($this->arabVowels
, $prevChar, 0, 'utf-8') !== false) {
31558 $prevChar = $chars[$i - 3];
31561 if ($crntChar && mb_strpos($this->arabVowels
, $crntChar, 0, 'utf-8') !== false) {
31562 // If next_char = nextLink && prev_char = prevLink:
31563 // Added && $prevchar (defined) else error on mb_strpos()
31564 if ($chars[$i +
1] && (mb_strpos($this->arabNextLink
, $chars[$i +
1], 0, 'utf-8') !== false) && $prevChar && (mb_strpos($this->arabPrevLink
, $prevChar, 0, 'utf-8') !== false)) {
31565 $output[] = $this->get_arab_glyphs($crntChar, 1); // <final> form
31568 $output[] = $this->get_arab_glyphs($crntChar, 0); // <isolated> form
31572 // NB = آ أ إ ا ل
31573 if (isset($chars[$i +
1]) && in_array($chars[$i +
1], array("\xd8\xa2","\xd8\xa3","\xd8\xa5","\xd8\xa7")) && $crntChar == "\xd9\x84"){
31576 if (ord($crntChar) < 128) {
31577 $output[] = $crntChar;
31578 $nextChar = $crntChar;
31582 if ($prevChar == "\xd9\x84" && ($crntChar == "\xd8\xa2" || $crntChar == "\xd8\xa3" || $crntChar == "\xd8\xa5" || $crntChar == "\xd8\xa7")) {
31583 if ($chars[$i - 2] && mb_strpos($this->arabPrevLink
, $chars[$i - 2], 0, 'utf-8') !== false) {
31584 $form++
; // <final> form
31586 $pos = mb_strpos($this->arabLigGlyphs
, ($prevChar . $crntChar), 0, 'utf-8');
31587 $pos = $pos*8 +
$form*4;
31588 $pres = (mb_substr($this->arabLigHex
, $pos, 4, 'utf-8'));
31589 // If presentation forms for mandatory ligatures with diacritics not present (even if remapped from e.g. uni0644uni0625)
31590 // try replacing with mandatory ligature Alef/lam isolated/final FEFB/FEFC + diacritic glyph
31591 if (!$this->_charDefined($this->CurrentFont
['cw'], hexdec($pres)) && $this->_charDefined($this->CurrentFont
['cw'], hexdec('FEFB'))) {
31592 if ($pres=='FEF5') { $output
[] = strcode2utf('ﻻٓ'); }
31593 else if ($pres=='FEF6') { $output
[] = strcode2utf('ﻼٓ'); }
31594 else if ($pres=='FEF7') { $output
[] = strcode2utf('ﻻٔ'); }
31595 else if ($pres=='FEF8') { $output
[] = strcode2utf('ﻼٔ'); }
31596 else if ($pres=='FEF9') { $output
[] = strcode2utf('ﻻٕ'); }
31597 else if ($pres=='FEFA') { $output
[] = strcode2utf('ﻼٕ'); }
31600 $output[] = strcode2utf('&#x' . $pres . ';');
31602 $nextChar = $prevChar;
31605 if ($prevChar && mb_strpos($this->arabPrevLink
, $prevChar, 0, 'utf-8') !== false) {
31608 if ($nextChar && mb_strpos($this->arabNextLink
, $nextChar, 0, 'utf-8') !== false) {
31611 $output[] = $this->get_arab_glyphs($crntChar, $form) ;
31612 $nextChar = $crntChar;
31614 $ra = array_reverse($output);
31620 function get_arab_glyphs($char, $type) {
31621 if ($type>0 && isset($this->arabGlyphs
[$char])) {
31622 // If presentation form specified FB** - FE** = Arabic presentation Forms
31623 if (preg_match("/[\x{FB50}-\x{FEFF}]/u",$this->arabGlyphs
[$char][$type])) {
31624 $unicode = $this->UTF8StringToArray($this->arabGlyphs
[$char][$type], false);
31625 if ($this->_charDefined($this->CurrentFont
['cw'],$unicode[0])) { return $this
->arabGlyphs
[$char
][$type
]; }
31626 else if (isset($this->CurrentFont
['unAGlyphs'])) {
31627 $uni = $this->UTF8StringToArray($char, false);
31628 $pua = $uni[0] - 1536 +
62464 +
256*$type ;
31629 if ($this->_charDefined($this->CurrentFont
['cw'], $pua)) { return strcode2utf('&#x' . dechex($pua
) . ';'); }
31634 // If PUA form specified and unAGlphs font set F5** F6** F7** = Private use area used by unAGlyphs in mPDF
31635 if (preg_match("/[\x{F500}-\x{F7FF}]/u",$this->arabGlyphs
[$char][$type]) && isset($this->CurrentFont
['unAGlyphs'])) {
31636 $unicode = $this->UTF8StringToArray($this->arabGlyphs
[$char][$type], false);
31637 if ($this->_charDefined($this->CurrentFont
['cw'],$unicode[0])) { return $this
->arabGlyphs
[$char
][$type
]; }
31640 return $this->arabGlyphs
[$char][$type];
31648 //===========================
31649 // Functions originally in htmltoolkit - moved mPDF 4.0
31651 // Call-back function Used for usort in fn _tableWrite
31653 function _cmpdom($a, $b) {
31654 return ($a["dom"] < $b["dom"]) ? -1 : 1;
31657 function mb_strrev($str, $enc = 'utf-8'){
31659 $ch = preg_split('//u',$str);
31660 $revch = array_reverse($ch);
31661 return implode('',$revch);
31665 // Callback function from function printcolumnbuffer in mpdf
31666 function columnAdjustAdd($type,$k,$xadj,$yadj,$a,$b,$c=0,$d=0,$e=0,$f=0) {
31667 if ($type == 'Td') { // xpos,ypos
31668 $a +
= ($xadj * $k);
31669 $b -= ($yadj * $k);
31670 return 'BT '.sprintf('%.3F %.3F',$a,$b).' Td';
31672 else if ($type == 're') { // xpos,ypos,width,height
31673 $a +
= ($xadj * $k);
31674 $b -= ($yadj * $k);
31675 return sprintf('%.3F %.3F %.3F %.3F',$a,$b,$c,$d).' re';
31677 else if ($type == 'l') { // xpos,ypos,x2pos,y2pos
31678 $a +
= ($xadj * $k);
31679 $b -= ($yadj * $k);
31680 return sprintf('%.3F %.3F l',$a,$b);
31682 else if ($type == 'img') { // width,height,xpos,ypos
31683 $c +
= ($xadj * $k);
31684 $d -= ($yadj * $k);
31685 return sprintf('q %.3F 0 0 %.3F %.3F %.3F',$a,$b,$c,$d).' cm /'.$e;
31687 else if ($type == 'draw') { // xpos,ypos
31688 $a +
= ($xadj * $k);
31689 $b -= ($yadj * $k);
31690 return sprintf('%.3F %.3F m',$a,$b);
31692 else if ($type == 'bezier') { // xpos,ypos,x2pos,y2pos,x3pos,y3pos
31693 $a +
= ($xadj * $k);
31694 $b -= ($yadj * $k);
31695 $c +
= ($xadj * $k);
31696 $d -= ($yadj * $k);
31697 $e +
= ($xadj * $k);
31698 $f -= ($yadj * $k);
31699 return sprintf('%.3F %.3F %.3F %.3F %.3F %.3F',$a,$b,$c,$d,$e,$f).' c';
31702 /*-- END COLUMNS --*/
31706 function ConvertColor($color="#000000"){
31707 $color = trim(strtolower($color));
31709 if ($color=='transparent') { return false; }
31710 else if ($color=='inherit') { return false; }
31711 else if (isset($this->SVGcolors
[$color])) $color = $this->SVGcolors
[$color];
31713 if (preg_match('/^[\d]+$/',$color)) { $c
= (array(1,$color
)); } // i.e. integer only
31714 else if ($color[0] == '#') { //case of #nnnnnn or #nnn
31715 $cor = preg_replace('/\s+.*/','',$color); // in case of Background: #CCC url() x-repeat etc.
31716 if (strlen($cor) == 4) { // Turn #RGB into #RRGGBB
31717 $cor = "#" . $cor[1] . $cor[1] . $cor[2] . $cor[2] . $cor[3] . $cor[3];
31719 $r = hexdec(substr($cor, 1, 2));
31720 $g = hexdec(substr($cor, 3, 2));
31721 $b = hexdec(substr($cor, 5, 2));
31722 $c = array(3,$r,$g,$b);
31724 else if (preg_match('/(rgba|rgb|device-cmyka|cmyka|device-cmyk|cmyk|hsla|hsl|spot)\((.*?)\)/',$color,$m)) { // mPDF 5.6.05
31726 $cores = explode(",", $m[2]);
31727 $ncores = count($cores);
31728 if (stristr($cores[0],'%') ) {
31730 if ($type=='rgb' || $type=='rgba') { $cores
[0] = intval($cores
[0]*255/100); }
31732 if ($ncores>1 && stristr($cores[1],'%') ) {
31734 if ($type=='rgb' || $type=='rgba') { $cores
[1] = intval($cores
[1]*255/100); }
31735 if ($type=='hsl' || $type=='hsla') { $cores
[1] = $cores
[1]/100; }
31737 if ($ncores>2 && stristr($cores[2],'%') ) {
31739 if ($type=='rgb' || $type=='rgba') { $cores
[2] = intval($cores
[2]*255/100); }
31740 if ($type=='hsl' || $type=='hsla') { $cores
[2] = $cores
[2]/100; }
31742 if ($ncores>3 && stristr($cores[3],'%') ) {
31746 if ($type=='rgb') { $c
= array(3,$cores
[0],$cores
[1],$cores
[2]); }
31747 else if ($type=='rgba') { $c
= array(5,$cores
[0],$cores
[1],$cores
[2],$cores
[3]*100); }
31748 else if ($type=='cmyk' || $type=='device-cmyk') { $c
= array(4,$cores
[0],$cores
[1],$cores
[2],$cores
[3]); } // mPDF 5.6.05
31749 else if ($type=='cmyka' || $type=='device-cmyka') { $c
= array(6,$cores
[0],$cores
[1],$cores
[2],$cores
[3],$cores
[4]*100); } // mPDF 5.6.05
31750 else if ($type=='hsl' || $type=='hsla') {
31751 $conv = $this->hsl2rgb($cores[0]/360,$cores[1],$cores[2]);
31752 if ($type=='hsl') { $c
= array(3,$conv
[0],$conv
[1],$conv
[2]); }
31753 else if ($type=='hsla') { $c
= array(5,$conv
[0],$conv
[1],$conv
[2],$cores
[3]*100); }
31755 else if ($type=='spot') {
31756 $name = strtoupper(trim($cores[0]));
31758 if(!isset($this->spotColors
[$name])) {
31759 if (isset($cores[5])) { $this
->AddSpotColor($cores
[0],$cores
[2],$cores
[3],$cores
[4],$cores
[5]); }
31760 else { $this
->Error('Undefined spot color: '.$name
); }
31762 $c = array(2,$this->spotColors
[$name]['i'],$cores[1]);
31767 // $this->restrictColorSpace
31768 // 1 - allow GRAYSCALE only [convert CMYK/RGB->gray]
31769 // 2 - allow RGB / SPOT COLOR / Grayscale [convert CMYK->RGB]
31770 // 3 - allow CMYK / SPOT COLOR / Grayscale [convert RGB->CMYK]
31771 if ($this->PDFA
|| $this->PDFX
|| $this->restrictColorSpace
) {
31772 if ($c[0]==1) { // GRAYSCALE
31774 else if ($c[0]==2) { // SPOT COLOR
31775 if (!isset($this->spotColorIDs
[$c[1]])) { die('Error: Spot colour has not been defined - '.$this
->spotColorIDs
[$c
[1]]); }
31777 if ($this->PDFA
&& !$this->PDFAauto
) { $this
->PDFAXwarnings
[] = "Spot color specified '".$this
->spotColorIDs
[$c
[1]]."' (converted to process color)"; }
31778 if ($this->restrictColorSpace
!=3) {
31779 $sp = $this->spotColors
[$this->spotColorIDs
[$c[1]]];
31780 $c = $this->cmyk2rgb(array(4,$sp['c'],$sp['m'],$sp['y'],$sp['k']));
31783 else if ($this->restrictColorSpace
==1) {
31784 $sp = $this->spotColors
[$this->spotColorIDs
[$c[1]]];
31785 $c = $this->cmyk2gray(array(4,$sp['c'],$sp['m'],$sp['y'],$sp['k']));
31788 else if ($c[0]==3) { // RGB
31789 if ($this->PDFX
|| ($this->PDFA
&& $this->restrictColorSpace
==3)) {
31790 if (($this->PDFA
&& !$this->PDFAauto
) || ($this->PDFX
&& !$this->PDFXauto
)) { $this
->PDFAXwarnings
[] = "RGB color specified '".$color
."' (converted to CMYK)"; }
31791 $c = $this->rgb2cmyk($c);
31793 else if ($this->restrictColorSpace
==1) { $c
= $this
->rgb2gray($c
); }
31794 else if ($this->restrictColorSpace
==3) { $c
= $this
->rgb2cmyk($c
); }
31796 else if ($c[0]==4) { // CMYK
31797 if ($this->PDFA
&& $this->restrictColorSpace
!=3) {
31798 if ($this->PDFA
&& !$this->PDFAauto
) { $this
->PDFAXwarnings
[] = "CMYK color specified '".$color
."' (converted to RGB)"; }
31799 $c = $this->cmyk2rgb($c);
31801 else if ($this->restrictColorSpace
==1) { $c
= $this
->cmyk2gray($c
); }
31802 else if ($this->restrictColorSpace
==2) { $c
= $this
->cmyk2rgb($c
); }
31804 else if ($c[0]==5) { // RGBa
31805 if ($this->PDFX
|| ($this->PDFA
&& $this->restrictColorSpace
==3)) {
31806 if (($this->PDFA
&& !$this->PDFAauto
) || ($this->PDFX
&& !$this->PDFXauto
)) { $this
->PDFAXwarnings
[] = "RGB color with transparency specified '".$color
."' (converted to CMYK without transparency)"; }
31807 $c = $this->rgb2cmyk($c);
31808 $c = array(4, $c[1], $c[2], $c[3], $c[4]);
31810 else if ($this->PDFA
&& $this->restrictColorSpace
!=3) {
31811 if (!$this->PDFAauto
) { $this
->PDFAXwarnings
[] = "RGB color with transparency specified '".$color
."' (converted to RGB without transparency)"; }
31812 $c = $this->rgb2cmyk($c);
31813 $c = array(4, $c[1], $c[2], $c[3], $c[4]);
31815 else if ($this->restrictColorSpace
==1) { $c
= $this
->rgb2gray($c
); }
31816 else if ($this->restrictColorSpace
==3) { $c
= $this
->rgb2cmyk($c
); }
31818 else if ($c[0]==6) { // CMYKa
31819 if ($this->PDFA
&& $this->restrictColorSpace
!=3) {
31820 if (($this->PDFA
&& !$this->PDFAauto
) || ($this->PDFX
&& !$this->PDFXauto
)) { $this
->PDFAXwarnings
[] = "CMYK color with transparency specified '".$color
."' (converted to RGB without transparency)"; }
31821 $c = $this->cmyk2rgb($c);
31822 $c = array(3, $c[1], $c[2], $c[3]);
31824 else if ($this->PDFX
|| ($this->PDFA
&& $this->restrictColorSpace
==3)) {
31825 if (($this->PDFA
&& !$this->PDFAauto
) || ($this->PDFX
&& !$this->PDFXauto
)) { $this
->PDFAXwarnings
[] = "CMYK color with transparency specified '".$color
."' (converted to CMYK without transparency)"; }
31826 $c = $this->cmyk2rgb($c);
31827 $c = array(3, $c[1], $c[2], $c[3]);
31829 else if ($this->restrictColorSpace
==1) { $c
= $this
->cmyk2gray($c
); }
31830 else if ($this->restrictColorSpace
==2) { $c
= $this
->cmyk2rgb($c
); }
31833 if (is_array($c)) {
31834 $c = array_pad($c, 6, 0);
31835 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
31840 function rgb2gray($c) {
31841 if (isset($c[4])) { return array(1,(($c
[1] * .21) +
($c
[2] * .71) +
($c
[3] * .07)), ord(1), $c
[4]); }
31842 else {
return array(1,(($c
[1] * .21) +
($c
[2] * .71) +
($c
[3] * .07))); }
31845 function cmyk2gray($c) {
31846 $rgb = $this->cmyk2rgb($c);
31847 return $this->rgb2gray($rgb);
31850 function rgb2cmyk($c) {
31851 $cyan = 1 - ($c[1] / 255);
31852 $magenta = 1 - ($c[2] / 255);
31853 $yellow = 1 - ($c[3] / 255);
31854 $min = min($cyan, $magenta, $yellow);
31857 if ($c[0]==5) { return array (6,100,100,100,100, $c
[4]); }
31858 else {
return array (4,100,100,100,100); }
31860 //if ($c[0]==5) { return array (6,0,0,0,100, $c[4]); }
31861 //else { return array (4,0,0,0,100); }
31865 if ($c[0]==5) { return array (6,($cyan
-$K
)*100/$black
, ($magenta
-$K
)*100/$black
, ($yellow
-$K
)*100/$black
, $K
*100, $c
[4]); }
31866 else {
return array (4,($cyan
-$K
)*100/$black
, ($magenta
-$K
)*100/$black
, ($yellow
-$K
)*100/$black
, $K
*100); }
31870 function cmyk2rgb($c) {
31872 $colors = 255 - ($c[4]*2.55);
31873 $rgb[0] = intval($colors * (255 - ($c[1]*2.55))/255);
31874 $rgb[1] = intval($colors * (255 - ($c[2]*2.55))/255);
31875 $rgb[2] = intval($colors * (255 - ($c[3]*2.55))/255);
31876 if ($c[0]==6) { return array (5,$rgb
[0],$rgb
[1],$rgb
[2], $c
[5]); }
31877 else {
return array (3,$rgb
[0],$rgb
[1],$rgb
[2]); }
31880 function rgb2hsl($var_r, $var_g, $var_b) {
31881 $var_min = min($var_r,$var_g,$var_b);
31882 $var_max = max($var_r,$var_g,$var_b);
31883 $del_max = $var_max - $var_min;
31884 $l = ($var_max +
$var_min) / 2;
31885 if ($del_max == 0) {
31890 if ($l < 0.5) { $s
= $del_max
/ ($var_max + $var_min
); }
31891 else { $s
= $del_max
/ (2 - $var_max
- $var_min
); }
31892 $del_r = ((($var_max - $var_r) / 6) +
($del_max / 2)) / $del_max;
31893 $del_g = ((($var_max - $var_g) / 6) +
($del_max / 2)) / $del_max;
31894 $del_b = ((($var_max - $var_b) / 6) +
($del_max / 2)) / $del_max;
31895 if ($var_r == $var_max) { $h
= $del_b
- $del_g
; }
31896 elseif ($var_g == $var_max) { $h
= (1 / 3) + $del_r
- $del_b
; }
31897 elseif ($var_b == $var_max) { $h
= (2 / 3) + $del_g
- $del_r
; };
31898 if ($h < 0) { $h +
= 1; }
31899 if ($h > 1) { $h
-= 1; }
31901 return array($h,$s,$l);
31905 function hsl2rgb($h2,$s2,$l2) {
31906 // Input is HSL value of complementary colour, held in $h2, $s, $l as fractions of 1
31907 // Output is RGB in normal 255 255 255 format, held in $r, $g, $b
31908 // Hue is converted using function hue_2_rgb, shown at the end of this code
31915 if ($l2 < 0.5) { $var_2
= $l2
* (1 + $s2
); }
31916 else { $var_2
= ($l2 + $s2
) - ($s2
* $l2
); }
31917 $var_1 = 2 * $l2 - $var_2;
31918 $r = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2 +
(1 / 3)));
31919 $g = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2));
31920 $b = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2 - (1 / 3)));
31922 return array($r,$g,$b);
31925 function hue_2_rgb($v1,$v2,$vh) {
31926 // Function to convert hue to RGB, called from above
31927 if ($vh < 0) { $vh +
= 1; };
31928 if ($vh > 1) { $vh
-= 1; };
31929 if ((6 * $vh) < 1) { return ($v1 +
($v2
- $v1
) * 6 * $vh
); };
31930 if ((2 * $vh) < 1) { return ($v2
); };
31931 if ((3 * $vh) < 2) { return ($v1 +
($v2
- $v1
) * ((2 / 3 - $vh
) * 6)); };
31935 function _invertColor($cor) {
31936 if ($cor[0]==3 || $cor[0]==5) { // RGB
31937 return array(3, (255-$cor[1]), (255-$cor[2]), (255-$cor[3]));
31939 else if ($cor[0]==4 || $cor[0]==6) { // CMYK
31940 return array(4, (100-$cor[1]), (100-$cor[2]), (100-$cor[3]), (100-$cor[4]));
31942 else if ($cor[0]==1) { // Grayscale
31943 return array(1, (255-$cor[1]));
31945 // Cannot cope with non-RGB colors at present
31946 die('Error in _invertColor - trying to invert non-RGB color');
31949 function _colAtoString($cor) {
31951 if ($cor{0}==1) $s = 'rgb('.ord($cor{1}).','.ord($cor{1}).','.ord($cor{1}).')';
31952 else if ($cor{0}==2) $s = 'spot('.ord($cor{1}).','.ord($cor{2}).')'; // SPOT COLOR
31953 else if ($cor{0}==3) $s = 'rgb('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).')';
31954 else if ($cor{0}==4) $s = 'cmyk('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).','.ord($cor{4}).')';
31955 else if ($cor{0}==5) $s = 'rgba('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).','.sprintf('%0.2F',ord($cor{4})/100).')';
31956 else if ($cor{0}==6) $s = 'cmyka('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).','.ord($cor{4}).','.sprintf('%0.2F',ord($cor{5})/100).')';
31960 function ConvertSize($size=5,$maxsize=0,$fontsize=false,$usefontsize=true){
31961 // usefontsize - setfalse for e.g. margins - will ignore fontsize for % values
31962 // Depends of maxsize value to make % work properly. Usually maxsize == pagewidth
31963 // For text $maxsize = Fontsize
31964 // Setting e.g. margin % will use maxsize (pagewidth) and em will use fontsize
31965 //Identify size (remember: we are using 'mm' units here)
31966 $size = trim(strtolower($size));
31968 if ( $size == 'thin' ) $size = 1*(25.4/$this->dpi
); //1 pixel width for table borders
31969 elseif ( stristr($size,'px') ) $size *= (25.4/$this->dpi
); //pixels
31970 elseif ( stristr($size,'cm') ) $size *= 10; //centimeters
31971 elseif ( stristr($size,'mm') ) $size +
= 0; //millimeters
31972 elseif ( stristr($size,'pt') ) $size *= 25.4/72; //72 pts/inch
31973 elseif ( stristr($size,'rem') ) { // mPDF 5.6.12
31974 $size +
= 0; //make "0.83rem" become simply "0.83"
31975 $size *= ($this->default_font_size
/ _MPDFK
);
31977 elseif ( stristr($size,'em') ) {
31978 $size +
= 0; //make "0.83em" become simply "0.83"
31979 if ($fontsize) { $size
*= $fontsize
; }
31980 else { $size
*= $maxsize
; }
31982 elseif ( stristr($size,'%') ) {
31983 $size +
= 0; //make "90%" become simply "90"
31984 if ($fontsize && $usefontsize) { $size
*= $fontsize
/100; }
31985 else { $size
*= $maxsize
/100; }
31987 elseif ( stristr($size,'in') ) $size *= 25.4; //inches
31988 elseif ( stristr($size,'pc') ) $size *= 38.1/9; //PostScript picas
31989 elseif ( stristr($size,'ex') ) { // Approximates "ex" as half of font height
31990 $size +
= 0; //make "3.5ex" become simply "3.5"
31991 if ($fontsize) { $size
*= $fontsize
/2; }
31992 else { $size
*= $maxsize
/2; }
31994 elseif ( $size == 'medium' ) $size = 3*(25.4/$this->dpi
); //3 pixel width for table borders
31995 elseif ( $size == 'thick' ) $size = 5*(25.4/$this->dpi
); //5 pixel width for table borders
31996 elseif ($size == 'xx-small') {
31997 if ($fontsize) { $size
*= $fontsize
*0.7; }
31998 else { $size
*= $maxsize
*0.7; }
32000 elseif ($size == 'x-small') {
32001 if ($fontsize) { $size
*= $fontsize
*0.77; }
32002 else { $size
*= $maxsize
*0.77; }
32004 elseif ($size == 'small') {
32005 if ($fontsize) { $size
*= $fontsize
*0.86; }
32006 else { $size
*= $maxsize
*0.86; }
32008 elseif ($size == 'medium') {
32009 if ($fontsize) { $size
*= $fontsize
; }
32010 else { $size
*= $maxsize
; }
32012 elseif ($size == 'large') {
32013 if ($fontsize) { $size
*= $fontsize
*1.2; }
32014 else { $size
*= $maxsize
*1.2; }
32016 elseif ($size == 'x-large') {
32017 if ($fontsize) { $size
*= $fontsize
*1.5; }
32018 else { $size
*= $maxsize
*1.5; }
32020 elseif ($size == 'xx-large') {
32021 if ($fontsize) { $size
*= $fontsize
*2; }
32022 else { $size
*= $maxsize
*2; }
32024 else $size *= (25.4/$this->dpi
); //nothing == px
32030 function lesser_entity_decode($html) {
32031 //supports the most used entity codes (only does ascii safe characters)
32032 //$html = str_replace(" "," ",$html); // mPDF 5.3.59
32033 $html = str_replace("<","<",$html);
32034 $html = str_replace(">",">",$html);
32036 $html = str_replace("'","'",$html);
32037 $html = str_replace(""",'"',$html);
32038 $html = str_replace("&","&",$html);
32042 function AdjustHTML($html, $tabSpaces=8) {
32043 //Try to make the html text more manageable (turning it into XHTML)
32044 if (PHP_VERSION_ID
< 50307) {
32045 if (strlen($html) > 100000) {
32046 if (PHP_VERSION_ID
< 50200) $this->Error("The HTML code is more than 100,000 characters. You should use WriteHTML() with smaller string lengths.");
32047 else ini_set("pcre.backtrack_limit","1000000");
32051 /*-- ANNOTATIONS --*/
32052 preg_match_all("/(<annotation.*?>)/si", $html, $m);
32053 if (count($m[1])) {
32054 for($i=0;$i<count($m[1]);$i++
) {
32055 $sub = preg_replace("/\n/si", "\xbb\xa4\xac", $m[1][$i]);
32056 $html = preg_replace('/'.preg_quote($m[1][$i], '/').'/si', $sub, $html);
32059 /*-- END ANNOTATIONS --*/
32061 preg_match_all("/(<svg.*?<\/svg>)/si", $html, $svgi);
32062 if (count($svgi[0])) {
32063 for($i=0;$i<count($svgi[0]);$i++
) {
32064 $file = _MPDF_TEMP_PATH
.'_tempSVG'.RAND(1,10000).'_'.$i.'.svg';
32065 //Save to local file
32066 file_put_contents($file, $svgi[0][$i]);
32067 $html = str_replace($svgi[0][$i], '<img src="'.$file.'" />', $html); // mPDF 5.5.18
32071 //Remove javascript code from HTML (should not appear in the PDF file)
32072 $html = preg_replace('/<script.*?<\/script>/is','',$html);
32074 //Remove special comments
32075 $html = preg_replace('/<!--mpdf/i','',$html);
32076 $html = preg_replace('/mpdf-->/i','',$html);
32078 //Remove comments from HTML (should not appear in the PDF file)
32079 $html = preg_replace('/<!--.*?-->/s','',$html);
32081 $html = preg_replace('/\f/','',$html); //replace formfeed by nothing
32082 $html = preg_replace('/\r/','',$html); //replace carriage return by nothing
32084 // Well formed XHTML end tags
32085 $html = preg_replace('/<(br|hr)\/>/i',"<\\1 />",$html);
32086 // Get rid of empty <thead></thead>
32087 $html = preg_replace('/<thead>\s*<\/thead>/i','',$html);
32088 $html = preg_replace('/<tfoot>\s*<\/tfoot>/i','',$html);
32089 $html = preg_replace('/<table[^>]*>\s*<\/table>/i','',$html);
32090 $html = preg_replace('/<tr>\s*<\/tr>/i','',$html);
32092 // Remove spaces at end of table cells
32093 $html = preg_replace("/[ \n\r]+<\/t(d|h)/",'</t\\1',$html); // mPDF 5.5.09
32095 $html = preg_replace("/[ ]*<dottab\s*[\/]*>[ ]*/",'<dottab />',$html);
32097 // Concatenates any Substitute characters from symbols/dingbats
32098 $html = str_replace('</tts><tts>','|',$html);
32099 $html = str_replace('</ttz><ttz>','|',$html);
32100 $html = str_replace('</tta><tta>','|',$html);
32102 $html = preg_replace('/<br \/>\s*/is',"<br />",$html);
32104 $html = preg_replace('/<wbr[ \/]*>\s*/is',"­",$html); // mPDF 5.6.04
32106 // Preserve '\n's in content between the tags <pre> and </pre>
32107 if (preg_match('/<pre/',$html)) {
32108 $html_a = preg_split('/(\<\/?pre[^\>]*\>)/', $html, -1, 2);
32111 foreach($html_a AS $s) {
32112 if ($c>1 && preg_match('/^<\/pre/i',$s)) { $c
--; $s
=preg_replace('/<\/pre/i','</innerpre',$s
); }
32113 else if ($c>0 && preg_match('/^<pre/i',$s)) { $c++
; $s
=preg_replace('/<pre/i','<innerpre',$s
); }
32114 else if (preg_match('/^<pre/i',$s)) { $c++
; }
32115 else if (preg_match('/^<\/pre/i',$s)) { $c
--; }
32116 array_push($h, $s);
32118 $html = implode("", $h);
32120 $thereispre = preg_match_all('#<pre(.*?)>(.*?)</pre>#si',$html,$temp);
32121 // Preserve '\n's in content between the tags <textarea> and </textarea>
32122 $thereistextarea = preg_match_all('#<textarea(.*?)>(.*?)</textarea>#si',$html,$temp2);
32123 $html = preg_replace('/[\n]/',' ',$html); //replace linefeed by spaces
32124 $html = preg_replace('/[\t]/',' ',$html); //replace tabs by spaces
32126 // Converts < to < when not a tag
32127 $html = preg_replace('/<([^!\/a-zA-Z])/i','<\\1',$html);
32128 $html = preg_replace("/[ ]+/",' ',$html);
32130 $html = preg_replace('/\/li>\s+<\/(u|o)l/i','/li></\\1l',$html);
32131 $html = preg_replace('/\/(u|o)l>\s+<\/li/i','/\\1l></li',$html);
32132 $html = preg_replace('/\/li>\s+<\/(u|o)l/i','/li></\\1l',$html);
32133 $html = preg_replace('/\/li>\s+<li/i','/li><li',$html);
32134 $html = preg_replace('/<(u|o)l([^>]*)>[ ]+/i','<\\1l\\2>',$html);
32135 $html = preg_replace('/[ ]+<(u|o)l/i','<\\1l',$html);
32138 while($thereispre) //Recover <pre attributes>content</pre>
32140 $temp[2][$iterator] = preg_replace("/^([^\n\t]*?)\t/me", "stripslashes('\\1') . str_repeat(' ', ( $tabSpaces - (mb_strlen(stripslashes('\\1')) % $tabSpaces)) )",$temp[2][$iterator]);
32141 $temp[2][$iterator] = preg_replace('/\t/',str_repeat(" ",$tabSpaces),$temp[2][$iterator]);
32143 $temp[2][$iterator] = preg_replace('/\n/',"<br />",$temp[2][$iterator]);
32144 $temp[2][$iterator] = str_replace('\\',"\\\\",$temp[2][$iterator]);
32145 $html = preg_replace('#<pre(.*?)>(.*?)</pre>#si','<erp'.$temp[1][$iterator].'>'.$temp[2][$iterator].'</erp>',$html,1);
32150 while($thereistextarea) //Recover <textarea attributes>content</textarea>
32152 $temp2[2][$iterator] = preg_replace('/\t/',str_repeat(" ",$tabSpaces),$temp2[2][$iterator]);
32153 $temp2[2][$iterator] = str_replace('\\',"\\\\",$temp2[2][$iterator]); // mPDF 5.3.88
32154 $html = preg_replace('#<textarea(.*?)>(.*?)</textarea>#si','<aeratxet'.$temp2[1][$iterator].'>'.trim($temp2[2][$iterator]) .'</aeratxet>',$html,1);
32155 $thereistextarea--;
32158 //Restore original tag names
32159 $html = str_replace("<erp","<pre",$html);
32160 $html = str_replace("</erp>","</pre>",$html);
32161 $html = str_replace("<aeratxet","<textarea",$html);
32162 $html = str_replace("</aeratxet>","</textarea>",$html);
32163 $html = str_replace("</innerpre","</pre",$html);
32164 $html = str_replace("<innerpre","<pre",$html);
32166 $html = preg_replace('/<textarea([^>]*)><\/textarea>/si','<textarea\\1> </textarea>',$html);
32167 $html = preg_replace('/(<table[^>]*>)\s*(<caption)(.*?<\/caption>)(.*?<\/table>)/si','\\2 position="top"\\3\\1\\4\\2 position="bottom"\\3',$html); // *TABLES*
32168 $html = preg_replace('/<(h[1-6])([^>]*)(>(?:(?!h[1-6]).)*?<\/\\1>\s*<table)/si','<\\1\\2 keep-with-table="1"\\3',$html); // *TABLES*
32169 $html = preg_replace("/\xbb\xa4\xac/", "\n", $html);
32175 function dec2other($num, $cp) {
32176 $nstr = (string) $num;
32178 for ($i=0;$i<strlen($nstr);$i++
) {
32179 if ($this->_charDefined($this->CurrentFont
['cw'],$cp+
intval($nstr[$i]))) { // contains arabic-indic numbers
32180 $rnum .= code2utf($cp+
intval($nstr[$i]));
32182 else { $rnum
.= $nstr
[$i
]; }
32187 function dec2alpha($valor,$toupper="true"){
32188 // returns a string from A-Z to AA-ZZ to AAA-ZZZ
32189 // OBS: A = 65 ASCII TABLE VALUE
32190 if (($valor < 1) || ($valor > 18278)) return "?"; //supports 'only' up to 18278
32191 $c1 = $c2 = $c3 = '';
32192 if ($valor > 702) // 3 letters (up to 18278)
32194 $c1 = 65 +
floor(($valor-703)/676);
32195 $c2 = 65 +
floor((($valor-703)%
676)/26);
32196 $c3 = 65 +
floor((($valor-703)%
676)%
26);
32198 elseif ($valor > 26) // 2 letters (up to 702)
32200 $c1 = (64 +
(int)(($valor-1) / 26));
32201 $c2 = (64 +
(int)($valor %
26));
32202 if ($c2 == 64) $c2 +
= 26;
32204 else // 1 letter (up to 26)
32206 $c1 = (64 +
$valor);
32209 if ($c2 != '') $alpha .= chr($c2);
32210 if ($c3 != '') $alpha .= chr($c3);
32211 if (!$toupper) $alpha = strtolower($alpha);
32216 function dec2roman($valor,$toupper=true){
32217 //returns a string as a roman numeral
32218 $r1=$r2=$r3=$r4='';
32219 if (($valor >= 5000) || ($valor < 1)) return "?"; //supports 'only' up to 4999
32220 $aux = (int)($valor/1000);
32230 $aux = (int)($valor/100);
32237 case 1: $r2.="C"; break;
32238 case 9: $r2="CM"; break;
32242 case 5: $r2="D".$r2; break;
32243 case 4: $r2="CD"; break;
32247 $aux = (int)($valor/10);
32254 case 1: $r3.="X"; break;
32255 case 9: $r3="XC"; break;
32259 case 5: $r3="L".$r3; break;
32260 case 4: $r3="XL"; break;
32267 case 1: $r4.="I"; break;
32268 case 9: $r4="IX"; break;
32272 case 5: $r4="V".$r4; break;
32273 case 4: $r4="IV"; break;
32276 $roman = $r1.$r2.$r3.$r4;
32277 if (!$toupper) $roman = strtolower($roman);
32280 /*-- END LISTS --*/
32283 //===========================
32285 function SetImportUse() {
32286 $this->enableImports
= true;
32287 ini_set('auto_detect_line_endings',1);
32288 require_once(_MPDF_PATH
."mpdfi/pdf_context.php");
32289 require_once(_MPDF_PATH
."mpdfi/pdf_parser.php");
32290 require_once(_MPDF_PATH
."mpdfi/fpdi_pdf_parser.php");
32294 function hex2str($hex) {
32295 return pack("H*", str_replace(array("\r","\n"," "),"", $hex));
32298 function str2hex($str) {
32299 return current(unpack("H*",$str));
32303 function pdf_write_value(&$value) {
32304 switch ($value[0]) {
32305 case PDF_TYPE_NUMERIC
:
32306 case PDF_TYPE_TOKEN
:
32307 // A numeric value or a token.
32308 // Simply output them
32309 $this->_out($value[1]." ", false);
32312 case PDF_TYPE_ARRAY
:
32313 // An array. Output the proper
32314 // structure and move on.
32315 $this->_out("[",false);
32316 for ($i = 0; $i < count($value[1]); $i++
) {
32317 $this->pdf_write_value($value[1][$i]);
32322 case PDF_TYPE_DICTIONARY
:
32324 $this->_out("<<",false);
32326 while (list($k, $v) = each($value[1])) {
32327 $this->_out($k . " ",false);
32328 $this->pdf_write_value($v);
32333 case PDF_TYPE_OBJREF
:
32334 // An indirect object reference
32335 // Fill the object stack if needed
32336 $cpfn =& $this->current_parser
->filename
;
32337 if (!isset($this->_don_obj_stack
[$cpfn][$value[1]])) {
32338 $this->_newobj(false,true);
32339 $this->_obj_stack
[$cpfn][$value[1]] = array($this->n
, $value);
32340 $this->_don_obj_stack
[$cpfn][$value[1]] = array($this->n
, $value);
32342 $objid = $this->_don_obj_stack
[$cpfn][$value[1]][0];
32343 $this->_out("{$objid} 0 R"); //{$value[2]}
32346 case PDF_TYPE_STRING
:
32347 if ($this->encrypted
) {
32348 $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id
), $value[1]);
32349 $value[1] = $this->_escape($value[1]);
32352 $this->_out('('.$value[1].')');
32355 case PDF_TYPE_STREAM
:
32356 // A stream. First, output the
32357 // stream dictionary, then the
32358 // stream data itself.
32359 $this->pdf_write_value($value[1]);
32360 if ($this->encrypted
) {
32361 $value[2][1] = $this->_RC4($this->_objectkey($this->_current_obj_id
), $value[2][1]);
32363 $this->_out("stream");
32364 $this->_out($value[2][1]);
32365 $this->_out("endstream");
32368 case PDF_TYPE_HEX
:
32369 if ($this->encrypted
) {
32370 $value[1] = $this->hex2str($value[1]);
32371 $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id
), $value[1]);
32372 // remake hexstring of encrypted string
32373 $value[1] = $this->str2hex($value[1]);
32375 $this->_out("<".$value[1].">");
32378 case PDF_TYPE_NULL
:
32379 // The null object.
32380 $this->_out("null");
32385 // ========== OVERWRITE SEARCH STRING IN A PDF FILE ================
32386 function OverWrite($file_in, $search, $replacement, $dest="D", $file_out="mpdf" ) {
32387 $pdf = file_get_contents($file_in);
32389 if (!is_array($search)) {
32391 $search = array($x);
32393 if (!is_array($replacement)) {
32395 $search = array($x);
32398 if (!$this->onlyCoreFonts
&& !$this->usingCoreFont
) {
32399 foreach($search AS $k=>$val) {
32400 $search[$k] = $this->UTF8ToUTF16BE($search[$k] , false);
32401 $search[$k] = $this->_escape($search[$k]);
32402 $replacement[$k] = $this->UTF8ToUTF16BE($replacement[$k], false);
32403 $replacement[$k] = $this->_escape($replacement[$k]);
32407 foreach($replacement AS $k=>$val) {
32408 $replacement[$k] = mb_convert_encoding($replacement[$k],$this->mb_enc
,'utf-8');
32409 $replacement[$k] = $this->_escape($replacement[$k]);
32413 // Get xref into array
32415 preg_match("/xref\n0 (\d+)\n(.*?)\ntrailer/s",$pdf,$m);
32416 $xref_objid = $m[1];
32417 preg_match_all('/(\d{10}) (\d{5}) (f|n)/',$m[2],$x);
32418 for($i=0; $i<count($x[0]); $i++
) {
32419 $xref[] = array(intval($x[1][$i]), $x[2][$i], $x[3][$i]);
32422 $changes = array();
32423 preg_match("/<<\s*\/Type\s*\/Pages\s*\/Kids\s*\[(.*?)\]\s*\/Count/s",$pdf,$m);
32424 preg_match_all("/(\d+) 0 R /s",$m[1],$o);
32426 foreach($objlist AS $obj) {
32427 if ($this->compress
) {
32428 preg_match("/".($obj+
1)." 0 obj\n<<\s*\/Filter\s*\/FlateDecode\s*\/Length (\d+)>>\nstream\n(.*?)\nendstream\n/s",$pdf,$m);
32431 preg_match("/".($obj+
1)." 0 obj\n<<\s*\/Length (\d+)>>\nstream\n(.*?)\nendstream\n/s",$pdf,$m);
32434 if (!$s) { continue; }
32436 if ($this->encrypted
) {
32437 $s = $this->_RC4($this->_objectkey($obj+
1), $s);
32439 if ($this->compress
) {
32440 $s = gzuncompress($s);
32442 foreach($search AS $k=>$val) {
32443 $s = str_replace($search[$k],$replacement[$k],$s);
32445 if ($this->compress
) {
32446 $s = gzcompress($s);
32448 if ($this->encrypted
) {
32449 $s = $this->_RC4($this->_objectkey($obj+
1), $s);
32451 $newlen = strlen($s);
32452 $changes[($xref[$obj+
1][0])] = ($newlen - $oldlen) +
(strlen($newlen) - strlen($oldlen ));
32453 if ($this->compress
) {
32454 $newstr = ($obj+
1) . " 0 obj\n<</Filter /FlateDecode /Length ".$newlen.">>\nstream\n".$s."\nendstream\n";
32457 $newstr = ($obj+
1) . " 0 obj\n<</Length ".$newlen.">>\nstream\n".$s."\nendstream\n";
32459 $pdf = str_replace($m[0],$newstr,$pdf);
32462 // Update xref in PDF
32464 $newxref = "xref\n0 ".$xref_objid."\n";
32465 foreach($xref AS $v) {
32466 foreach($changes AS $ck => $cv) {
32467 if ($v[0] > $ck) { $v
[0] +
= $cv
; }
32469 $newxref .= sprintf('%010d',$v[0]) . ' ' . $v[1] . ' ' .$v[2] . " \n";
32471 $newxref .= "trailer";
32472 $pdf = preg_replace("/xref\n0 \d+\n.*?\ntrailer/s",$newxref,$pdf);
32474 // Update startxref in PDF
32475 preg_match("/startxref\n(\d+)\n%%EOF/s", $pdf, $m);
32476 $startxref = $m[1];
32477 $startxref +
= array_sum($changes);
32478 $pdf = preg_replace("/startxref\n(\d+)\n%%EOF/s","startxref\n".$startxref."\n%%EOF",$pdf);
32483 //Send to standard output
32484 if(isset($_SERVER['SERVER_NAME']))
32486 //We send to a browser
32487 Header('Content-Type: application/pdf');
32488 Header('Content-Length: '.strlen($pdf));
32489 Header('Content-disposition: inline; filename='.$file_out);
32494 //Save to local file
32495 if (!$file_out) { $file_out
= 'mpdf.pdf'; }
32496 $f=fopen($file_out,'wb');
32497 if(!$f) die('Unable to create output file: '.$file_out);
32498 fwrite($f,$pdf,strlen($pdf));
32502 //Return as a string
32507 if(isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'],'MSIE'))
32508 Header('Content-Type: application/force-download');
32510 Header('Content-Type: application/octet-stream');
32511 Header('Content-Length: '.strlen($pdf));
32512 Header('Content-disposition: attachment; filename='.$file_out);
32519 function GetTemplateSize($tplidx, $_w=0, $_h=0) {
32520 if (!$this->tpls
[$tplidx])
32522 $w = $this->tpls
[$tplidx]['box']['w'];
32523 $h = $this->tpls
[$tplidx]['box']['h'];
32524 if ($_w == 0 and $_h == 0) {
32532 return array("w" => $_w, "h" => $_h);
32536 function Thumbnail($file, $npr=3, $spacing=10) { //$npr = number per row
32537 $w = (($this->pgwidth +
$spacing)/$npr) - $spacing;
32538 $oldlinewidth = $this->LineWidth
;
32539 $this->SetLineWidth(0.02);
32540 $this->SetDColor($this->ConvertColor(0));
32543 $x = $_x = $this->lMargin
;
32544 $_y = $this->tMargin
;
32545 if ($this->y
==0) { $y
= $_y
; } else { $y
= $this
->y
; }
32546 $pagecount = $this->SetSourceFile($file);
32547 for ($n = 1; $n <= $pagecount; $n++
) {
32548 $tplidx = $this->ImportPage($n);
32549 $size = $this->useTemplate($tplidx, $x, $y, $w);
32550 $this->Rect($x, $y, $size['w'], $size['h']);
32551 $h = max($h, $size['h']);
32552 $maxh = max($h, $maxh);
32553 if ($n %
$npr == 0) {
32554 if (($y +
$h +
$spacing +
$maxh)>$this->PageBreakTrigger
&& $n != $pagecount) {
32560 $y +
= $h+
$spacing ;
32566 $x +
= $w+
$spacing ;
32569 $this->SetLineWidth($oldlinewidth);
32572 function SetSourceFile($filename) {
32573 $this->current_filename
= $filename;
32574 $fn =& $this->current_filename
;
32575 if (!isset($this->parsers
[$fn]))
32576 // $this->parsers[$fn] =& new fpdi_pdf_parser($fn,$this);
32577 $this->parsers
[$fn] = new fpdi_pdf_parser($fn,$this);
32578 if (!$this->parsers
[$fn]->success
) {
32579 $this->Error($this->parsers
[$fn]->errormsg
); // Delete this line to return false on fail
32582 $this->current_parser
=& $this->parsers
[$fn];
32583 return $this->parsers
[$fn]->getPageCount();
32585 function ImportPage($pageno=1, $crop_x=null, $crop_y=null, $crop_w=0, $crop_h=0, $boxName='/CropBox') {
32586 $fn =& $this->current_filename
;
32587 $parser =& $this->parsers
[$fn];
32588 $parser->setPageno($pageno);
32591 $this->tpls
[$this->tpl
] = array();
32592 $tpl =& $this->tpls
[$this->tpl
];
32593 $tpl['parser'] =& $parser;
32594 $tpl['resources'] = $parser->getPageResources();
32595 $tpl['buffer'] = $parser->getContent();
32596 if (!in_array($boxName, $parser->availableBoxes
))
32597 return $this->Error(sprintf("Unknown box: %s", $boxName));
32598 $pageboxes = $parser->getPageBoxes($pageno);
32601 * CropBox: Default -> MediaBox
32602 * BleedBox: Default -> CropBox
32603 * TrimBox: Default -> CropBox
32604 * ArtBox: Default -> CropBox
32606 if (!isset($pageboxes[$boxName]) && ($boxName == "/BleedBox" || $boxName == "/TrimBox" || $boxName == "/ArtBox"))
32607 $boxName = "/CropBox";
32608 if (!isset($pageboxes[$boxName]) && $boxName == "/CropBox")
32609 $boxName = "/MediaBox";
32610 if (!isset($pageboxes[$boxName]))
32612 $box = $pageboxes[$boxName];
32614 $tpl['box'] = $box;
32615 // To build an array that can be used by useTemplate()
32616 $this->tpls
[$this->tpl
] = array_merge($this->tpls
[$this->tpl
],$box);
32617 // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects()
32620 $tpl['w'] = $tpl['box']['w'] ;
32621 $tpl['h'] = $tpl['box']['h'] ;
32622 if ($crop_w) { $tpl
['box']['w'] = $crop_w
; }
32623 if ($crop_h) { $tpl
['box']['h'] = $crop_h
; }
32624 if (isset($crop_x)) { $tpl
['box']['x'] = $crop_x
; }
32625 if (isset($crop_y)) {$tpl
['box']['y'] = $tpl
['h'] - $crop_y
- $crop_h
; }
32627 $page =& $parser->pages
[$parser->pageno
];
32628 // fix for rotated pages
32629 $rotation = $parser->getPageRotation($pageno);
32631 if (isset($rotation[1]) && ($angle = $rotation[1] %
360) != 0 && $tpl['box']['w'] == $tpl['w']) {
32632 $steps = $angle / 90;
32636 $tpl['w'] = $steps %
2 == 0 ? $_w : $_h;
32637 $tpl['h'] = $steps %
2 == 0 ? $_h : $_w;
32638 if ($steps %
2 != 0) {
32639 $x = $y = ($steps == 1 || $steps == -3) ? $tpl['h'] : $tpl['w'];
32644 $cx=($x/2+
$tpl['box']['x'])*_MPDFK
;
32645 $cy=($y/2+
$tpl['box']['y'])*_MPDFK
;
32650 $tpl['box']['w'] = $tpl['w'] ;
32651 $tpl['box']['h'] = $tpl['h'] ;
32652 $tpl['buffer'] = sprintf('q %.5F %.5F %.5F %.5F %.2F %.2F cm 1 0 0 1 %.2F %.2F cm %s Q',$c,$s,-$s,$c,$cx,$cy,-$cx,-$cy, $tpl['buffer']);
32656 function UseTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) {
32657 if (!isset($this->tpls
[$tplidx]))
32658 $this->Error("Template does not exist!");
32659 if($this->state
==0) { $this
->AddPage(); }
32660 $out = 'q 0 J 1 w 0 j 0 G'."\n"; // reset standard values
32661 $x = $this->tpls
[$tplidx]['x'];
32662 $y = $this->tpls
[$tplidx]['y'];
32663 $w = $this->tpls
[$tplidx]['w'];
32664 $h = $this->tpls
[$tplidx]['h'];
32665 if ($_x == null) { $_x
= $x
; }
32666 if ($_y == null) { $_y
= $y
; }
32667 if ($_x === -1) { $_x
= $this
->x
; }
32668 if ($_y === -1) { $_y
= $this
->y
; }
32670 $wh = $this->getTemplateSize($tplidx,$_w,$_h);
32673 $out .= sprintf("q %.4F 0 0 %.4F %.2F %.2F cm", ($_w/$this->tpls
[$tplidx]['box']['w']), ($_h/$this->tpls
[$tplidx]['box']['h']), $_x*_MPDFK
, ($this->h
-($_y+
$_h))*_MPDFK
)."\n";
32674 $out .= $this->tplprefix
.$tplidx." Do Q\n";
32676 $s = array("w" => $_w, "h" => $_h);
32678 $this->pages
[$this->page
] = $out . $this->pages
[$this->page
];
32681 function SetPageTemplate($tplidx='') {
32682 if (!isset($this->tpls
[$tplidx])) {
32683 $this->pageTemplate
= '';
32686 $this->pageTemplate
= $tplidx;
32688 function SetDocTemplate($file='', $continue=0) {
32689 $this->docTemplate
= $file;
32690 $this->docTemplateContinue
= $continue;
32692 /*-- END IMPORTS --*/
32695 /* ---------------------------------------------- */
32696 /* ---------------------------------------------- */
32697 /* ---------------------------------------------- */
32698 /* ---------------------------------------------- */
32699 /* ---------------------------------------------- */
32702 function _set_object_javascript ($string) {
32705 $this->_out('/S /JavaScript ');
32706 $this->_out('/JS '.$this->_textstring($string));
32708 $this->_out('endobj');
32711 function SetJS($script) {
32712 $this->js
= $script;