PluginProbe
PDF & Print by BestWebSoft – WordPress Posts and Pages PDF Generator Plugin / 1.7.9
PDF & Print by BestWebSoft – WordPress Posts and Pages PDF Generator Plugin v1.7.9
trunk 1.5 1.6 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 All 71 releases
pdf-print / mpdf / mpdf.php

mpdf.php in PDF & Print by BestWebSoft – WordPress Posts and Pages PDF Generator Plugin 1.7.9, at mpdf/mpdf.php

33,236 lines 1.3 MB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // ******************************************************************************
4 // Software: mPDF, Unicode-HTML Free PDF generator *
5 // Version: 5.7.4 based on *
6 // FPDF by Olivier PLATHEY *
7 // HTML2FPDF by Renato Coelho *
8 // Date: 2014-08-23 *
9 // Author: Ian Back <ianb@bpm1.com> *
10 // License: GPL *
11 // *
12 // Changes: See changelog.txt *
13 // ******************************************************************************
14
15
16 define('mPDF_VERSION','5.7.4');
17
18 //Scale factor
19 define('_MPDFK', (72/25.4));
20
21 /*-- HTML-CSS --*/
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);
27
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 --*/
34
35 if (!defined('_MPDF_PATH')) define('_MPDF_PATH', dirname(preg_replace('/\\\\/','/',__FILE__)) . '/');
36 if (!defined('_MPDF_URI')) define('_MPDF_URI',_MPDF_PATH);
37
38 require_once(_MPDF_PATH.'includes/functions.php');
39 require_once(_MPDF_PATH.'config_cp.php');
40
41 if (!defined('_JPGRAPH_PATH')) define("_JPGRAPH_PATH", _MPDF_PATH.'jpgraph/');
42
43 if (!defined('_MPDF_TEMP_PATH')) define("_MPDF_TEMP_PATH", _MPDF_PATH.'tmp/');
44
45 if (!defined('_MPDF_TTFONTPATH')) { define('_MPDF_TTFONTPATH',_MPDF_PATH.'ttfonts/'); }
46 if (!defined('_MPDF_TTFONTDATAPATH')) { define('_MPDF_TTFONTDATAPATH',_MPDF_PATH.'ttfontdata/'); }
47
48 $errorlevel=error_reporting();
49 $errorlevel=error_reporting($errorlevel & ~E_NOTICE);
50
51 //error_reporting(E_ALL);
52
53 if(function_exists("date_default_timezone_set")) {
54 if (ini_get("date.timezone")=="") { date_default_timezone_set("Europe/London"); }
55 }
56 if (!function_exists("mb_strlen")) { die("Error - mPDF requires mb_string functions. Ensure that PHP is compiled with php_mbstring.dll enabled."); }
57
58 if (!defined('PHP_VERSION_ID')) {
59 $version = explode('.', PHP_VERSION);
60 define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
61 }
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));
65
66 class mPDF
67 {
68
69 ///////////////////////////////
70 // EXTERNAL (PUBLIC) VARIABLES
71 // Define these in config.php
72 ///////////////////////////////
73 var $CJKforceend; // mPDF 5.6.40
74 // mPDF 5.6.34
75 var $h2bookmarks;
76 var $h2toc;
77 var $decimal_align; // mPDF 5.6.13
78 var $margBuffer; // mPDF 5.4.04
79 var $splitTableBorderWidth; // mPDF 5.4.16
80
81 var $cacheTables;
82 var $bookmarkStyles;
83 var $useActiveForms;
84
85 var $repackageTTF;
86 var $allowCJKorphans;
87 var $allowCJKoverflow;
88
89 var $useKerning;
90 var $restrictColorSpace;
91 var $bleedMargin;
92 var $crossMarkMargin;
93 var $cropMarkMargin;
94 var $cropMarkLength;
95 var $nonPrintMargin;
96
97 var $PDFX;
98 var $PDFXauto;
99
100 var $PDFA;
101 var $PDFAauto;
102 var $ICCProfile;
103
104 var $printers_info;
105 var $iterationCounter;
106 var $smCapsScale;
107 var $smCapsStretch;
108
109 var $backupSubsFont;
110 var $backupSIPFont;
111 var $debugfonts;
112 var $useAdobeCJK;
113 var $percentSubset;
114 var $maxTTFFilesize;
115 var $BMPonly;
116
117 var $tableMinSizePriority;
118
119 var $dpi;
120 var $watermarkImgAlphaBlend;
121 var $watermarkImgBehind;
122 var $justifyB4br;
123 var $packTableData;
124 var $pgsIns;
125 var $simpleTables;
126 var $enableImports;
127
128 var $debug;
129 var $showStats;
130 var $setAutoTopMargin;
131 var $setAutoBottomMargin;
132 var $autoMarginPadding;
133 var $collapseBlockMargins;
134 var $falseBoldWeight;
135 var $normalLineheight;
136 var $progressBar;
137 var $incrementFPR1;
138 var $incrementFPR2;
139 var $incrementFPR3;
140 var $incrementFPR4;
141
142 var $SHYlang;
143 var $SHYleftmin;
144 var $SHYrightmin;
145 var $SHYcharmin;
146 var $SHYcharmax;
147 var $SHYlanguages;
148 // PageNumber Conditional Text
149 var $pagenumPrefix;
150 var $pagenumSuffix;
151 var $nbpgPrefix;
152 var $nbpgSuffix;
153 var $showImageErrors;
154 var $allow_output_buffering;
155 var $autoPadding;
156 var $useGraphs;
157 var $autoFontGroupSize;
158 var $tabSpaces;
159 var $useLang;
160 var $restoreBlockPagebreaks;
161 var $watermarkTextAlpha;
162 var $watermarkImageAlpha;
163 var $watermark_size;
164 var $watermark_pos;
165 var $annotSize;
166 var $annotMargin;
167 var $annotOpacity;
168 var $title2annots;
169 var $keepColumns;
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;
176 var $CSSselectMedia;
177
178 var $forcePortraitHeaders;
179 var $forcePortraitMargins;
180 var $displayDefaultOrientation;
181 var $ignore_invalid_utf8;
182 var $allowedCSStags;
183 var $onlyCoreFonts;
184 var $allow_charset_conversion;
185
186 var $jSWord;
187 var $jSmaxChar;
188 var $jSmaxCharLast;
189 var $jSmaxWordLast;
190
191 var $max_colH_correction;
192
193
194 var $table_error_report;
195 var $table_error_report_param;
196 var $biDirectional;
197 var $text_input_as_HTML;
198 var $anchor2Bookmark;
199 var $list_indent_first_level;
200 var $shrink_tables_to_fit;
201
202 var $allow_html_optional_endtags;
203
204 var $img_dpi;
205
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;
214
215 var $pregUHCchars;
216 var $pregSJISchars;
217 var $pregCJKchars;
218 var $pregASCIIchars1;
219 var $pregASCIIchars2;
220 var $pregASCIIchars3;
221 var $pregVIETchars;
222 var $pregVIETPluschars;
223
224 var $pregRTLchars;
225 var $pregHEBchars;
226 var $pregARABICchars;
227 var $pregNonARABICchars;
228 // INDIC
229 var $pregHIchars;
230 var $pregBNchars;
231 var $pregPAchars;
232 var $pregGUchars;
233 var $pregORchars;
234 var $pregTAchars;
235 var $pregTEchars;
236 var $pregKNchars;
237 var $pregMLchars;
238 var $pregSHchars;
239 var $pregINDextra;
240
241 var $mirrorMargins;
242 var $default_lineheight_correction;
243 var $watermarkText;
244 var $watermarkImage;
245 var $showWatermarkText;
246 var $showWatermarkImage;
247
248 var $fontsizes;
249
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
255
256
257
258 //////////////////////
259 // CLASS OBJECTS
260 //////////////////////
261 var $cssmgr;
262 var $grad;
263 var $bmp;
264 var $wmf;
265 var $tocontents;
266 var $form;
267 var $directw;
268
269 //////////////////////
270 // INTERNAL VARIABLES
271 //////////////////////
272 var $uniqstr; // mPDF 5.7.2
273 var $writingToC; // mPDF 5.6.38
274 // mPDF 5.6.01
275 var $layers;
276 var $current_layer;
277 var $open_layer_pane;
278 var $decimal_offset; // mPDF 5.6.13
279 var $inMeter; // mPDF 5.5.09
280
281 var $CJKleading;
282 var $CJKfollowing;
283 var $CJKoverflow;
284
285 var $textshadow;
286
287 var $colsums;
288 var $spanborder;
289 var $spanborddet;
290
291 var $visibility;
292
293 var $useRC128encryption;
294 var $uniqid;
295
296 var $kerning;
297 var $fixedlSpacing;
298 var $minwSpacing;
299 var $lSpacingCSS;
300 var $wSpacingCSS;
301
302 var $listDir;
303 var $spotColorIDs;
304 var $SVGcolors;
305 var $spotColors;
306 var $defTextColor;
307 var $defDrawColor;
308 var $defFillColor;
309
310 var $tableBackgrounds;
311 var $inlineDisplayOff;
312 var $kt_y00;
313 var $kt_p00;
314 var $upperCase;
315 var $checkSIP;
316 var $checkSMP;
317 var $checkCJK;
318 var $tableCJK;
319
320 var $watermarkImgAlpha;
321 var $PDFAXwarnings;
322 var $MetadataRoot;
323 var $OutputIntentRoot;
324 var $InfoRoot;
325 var $current_filename;
326 var $parsers;
327 var $current_parser;
328 var $_obj_stack;
329 var $_don_obj_stack;
330 var $_current_obj_id;
331 var $tpls;
332 var $tpl;
333 var $tplprefix;
334 var $_res;
335
336 var $pdf_version;
337 var $noImageFile;
338 var $lastblockbottommargin;
339 var $baselineC;
340 // mPDF 5.7.3 inline text-decoration parameters
341 var $baselineSup;
342 var $baselineSub;
343 var $baselineS;
344 var $subPos;
345 var $subArrMB;
346 var $ReqFontStyle;
347 var $tableClipPath ;
348 var $forceExactLineheight;
349 var $listOcc;
350
351 var $fullImageHeight;
352 var $inFixedPosBlock; // Internal flag for position:fixed block
353 var $fixedPosBlock; // Buffer string for position:fixed block
354 var $fixedPosBlockDepth;
355 var $fixedPosBlockBBox;
356 var $fixedPosBlockSave;
357 var $maxPosL;
358 var $maxPosR;
359
360 var $loaded;
361
362 var $extraFontSubsets;
363 var $docTemplateStart; // Internal flag for page (page no. -1) that docTemplate starts on
364 var $time0;
365
366 // Classes
367 var $indic;
368 var $barcode;
369
370 var $SHYpatterns;
371 var $loadedSHYpatterns;
372 var $loadedSHYdictionary;
373 var $SHYdictionary;
374 var $SHYdictionaryWords;
375
376 var $spanbgcolorarray;
377 var $default_font;
378 var $list_lineheight;
379 var $headerbuffer;
380 var $lastblocklevelchange;
381 var $nestedtablejustfinished;
382 var $linebreakjustfinished;
383 var $cell_border_dominance_L;
384 var $cell_border_dominance_R;
385 var $cell_border_dominance_T;
386 var $cell_border_dominance_B;
387 var $table_keep_together;
388 var $plainCell_properties;
389 var $inherit_lineheight;
390 var $listitemtype;
391 var $shrin_k1;
392 var $outerfilled;
393
394 var $blockContext;
395 var $floatDivs;
396
397
398 var $patterns;
399 var $pageBackgrounds;
400
401 var $bodyBackgroundGradient;
402 var $bodyBackgroundImage;
403 var $bodyBackgroundColor;
404
405 var $writingHTMLheader; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
406 var $writingHTMLfooter;
407 var $autoFontGroups;
408 var $angle;
409
410 var $gradients;
411
412 var $kwt_Reference;
413 var $kwt_BMoutlines;
414 var $kwt_toc;
415
416 var $tbrot_Reference;
417 var $tbrot_BMoutlines;
418 var $tbrot_toc;
419
420 var $col_Reference;
421 var $col_BMoutlines;
422 var $col_toc;
423
424 var $currentGraphId;
425 var $graphs;
426
427 var $floatbuffer;
428 var $floatmargins;
429
430 var $bullet;
431 var $bulletarray;
432
433 var $rtlAsArabicFarsi; // DEPRACATED
434
435 var $currentLang;
436 var $default_lang;
437 var $default_available_fonts;
438 var $pageTemplate;
439 var $docTemplate;
440 var $docTemplateContinue;
441
442 var $arabGlyphs;
443 var $arabHex;
444 var $persianGlyphs;
445 var $persianHex;
446 var $arabVowels;
447 var $arabPrevLink;
448 var $arabNextLink;
449
450
451 var $formobjects; // array of Form Objects for WMF
452 var $InlineProperties;
453 var $InlineAnnots;
454 var $ktAnnots;
455 var $tbrot_Annots;
456 var $kwt_Annots;
457 var $columnAnnots;
458 var $columnForms;
459
460 var $PageAnnots;
461
462 var $pageDim; // Keep track of page wxh for orientation changes - set in _beginpage, used in _putannots
463
464 var $breakpoints;
465
466 var $tableLevel;
467 var $tbctr;
468 var $innermostTableLevel;
469 var $saveTableCounter;
470 var $cellBorderBuffer;
471
472 var $saveHTMLFooter_height;
473 var $saveHTMLFooterE_height;
474
475 var $firstPageBoxHeader;
476 var $firstPageBoxHeaderEven;
477 var $firstPageBoxFooter;
478 var $firstPageBoxFooterEven;
479
480 var $page_box;
481 var $show_marks; // crop or cross marks
482
483 var $basepathIsLocal;
484
485 var $use_kwt;
486 var $kwt;
487 var $kwt_height;
488 var $kwt_y0;
489 var $kwt_x0;
490 var $kwt_buffer;
491 var $kwt_Links;
492 var $kwt_moved;
493 var $kwt_saved;
494
495 var $PageNumSubstitutions;
496
497 var $table_borders_separate;
498 var $base_table_properties;
499 var $borderstyles;
500
501 var $listjustfinished;
502 var $blockjustfinished;
503
504 var $orig_bMargin;
505 var $orig_tMargin;
506 var $orig_lMargin;
507 var $orig_rMargin;
508 var $orig_hMargin;
509 var $orig_fMargin;
510
511 var $pageheaders;
512 var $pagefooters;
513
514 var $pageHTMLheaders;
515 var $pageHTMLfooters;
516
517 var $saveHTMLHeader;
518 var $saveHTMLFooter;
519
520 var $HTMLheaderPageLinks;
521 var $HTMLheaderPageAnnots;
522 var $HTMLheaderPageForms;
523
524 // See config_fonts.php for these next 5 values
525 var $available_unifonts;
526 var $sans_fonts;
527 var $serif_fonts;
528 var $mono_fonts;
529 var $defaultSubsFont;
530
531 // List of ALL available CJK fonts (incl. styles) (Adobe add-ons) hw removed
532 var $available_CJK_fonts;
533
534 var $HTMLHeader;
535 var $HTMLFooter;
536 var $HTMLHeaderE;
537 var $HTMLFooterE;
538 var $bufferoutput;
539
540 var $showdefaultpagenos; // DEPRACATED -left for backward compatability
541
542
543 // CJK fonts
544 var $Big5_widths;
545 var $GB_widths;
546 var $SJIS_widths;
547 var $UHC_widths;
548
549 // SetProtection
550 var $encrypted; //whether document is protected
551 var $Uvalue; //U entry in pdf document
552 var $Ovalue; //O entry in pdf document
553 var $Pvalue; //P entry in pdf document
554 var $enc_obj_id; //encryption object id
555 var $last_rc4_key; //last RC4 key encrypted (cached for optimisation)
556 var $last_rc4_key_c; //last RC4 computed key
557 var $encryption_key;
558 var $padding; //used for encryption
559
560
561 // Bookmark
562 var $BMoutlines;
563 var $OutlineRoot;
564 // INDEX
565 var $ColActive;
566 var $Reference;
567 var $CurrCol;
568 var $NbCol;
569 var $y0; //Top ordinate of columns
570 var $ColL;
571 var $ColWidth;
572 var $ColGap;
573 // COLUMNS
574 var $ColR;
575 var $ChangeColumn;
576 var $columnbuffer;
577 var $ColDetails;
578 var $columnLinks;
579 var $colvAlign;
580 // Substitutions
581 var $substitute; // Array of substitution strings e.g. <ttz>112</ttz>
582 var $entsearch; // Array of HTML entities (>ASCII 127) to substitute
583 var $entsubstitute; // Array of substitution decimal unicode for the Hi entities
584
585
586 // Default values if no style sheet offered (cf. http://www.w3.org/TR/CSS21/sample.html)
587 var $defaultCSS;
588
589 var $linemaxfontsize;
590 var $lineheight_correction;
591 var $lastoptionaltag; // Save current block item which HTML specifies optionsl endtag
592 var $pageoutput;
593 var $charset_in;
594 var $blk;
595 var $blklvl;
596 var $ColumnAdjust;
597 var $ws; // Word spacing
598 var $HREF;
599 var $pgwidth;
600 var $fontlist;
601 var $oldx;
602 var $oldy;
603 var $B;
604 var $U; //underlining flag
605 var $S; // SmallCaps flag
606 var $I;
607
608 var $tdbegin;
609 var $table;
610 var $cell;
611 var $col;
612 var $row;
613
614 var $divbegin;
615 var $divalign;
616 var $divwidth;
617 var $divheight;
618 var $divrevert;
619 var $spanbgcolor;
620
621 var $listlvl;
622 var $listnum;
623 var $listtype;
624 var $listoccur;
625 var $listlist;
626 var $listitem;
627
628 var $pjustfinished;
629 var $ignorefollowingspaces;
630 var $SUP;
631 var $SUB;
632 var $SMALL;
633 var $BIG;
634 var $toupper;
635 var $tolower;
636 var $capitalize;
637 var $dash_on;
638 var $dotted_on;
639 var $strike;
640
641 var $textbuffer;
642 var $currentfontstyle;
643 var $currentfontfamily;
644 var $currentfontsize;
645 var $colorarray;
646 var $bgcolorarray;
647 var $internallink;
648 var $enabledtags;
649
650 var $lineheight;
651 var $basepath;
652 var $textparam;
653
654 var $specialcontent;
655 var $selectoption;
656 var $objectbuffer;
657
658 // Table Rotation
659 var $table_rotate;
660 var $tbrot_maxw;
661 var $tbrot_maxh;
662 var $tablebuffer;
663 var $tbrot_align;
664 var $tbrot_Links;
665
666 var $divbuffer; // Buffer used when keeping DIV on one page
667 var $keep_block_together; // Keep a Block from page-break-inside: avoid
668 var $ktLinks; // Keep-together Block links array
669 var $ktBlock; // Keep-together Block array
670 var $ktForms;
671 var $ktReference;
672 var $ktBMoutlines;
673 var $_kttoc;
674
675 var $tbrot_y0;
676 var $tbrot_x0;
677 var $tbrot_w;
678 var $tbrot_h;
679
680 var $mb_enc;
681 var $directionality;
682
683 var $extgstates; // Used for alpha channel - Transparency (Watermark)
684 var $mgl;
685 var $mgt;
686 var $mgr;
687 var $mgb;
688
689 var $tts;
690 var $ttz;
691 var $tta;
692
693 var $headerDetails;
694 var $footerDetails;
695
696 // Best to alter the below variables using default stylesheet above
697 var $page_break_after_avoid;
698 var $margin_bottom_collapse;
699 var $list_indent;
700 var $list_align;
701 var $list_margin_bottom;
702 var $default_font_size; // in pts
703 var $original_default_font_size; // used to save default sizes when using table default
704 var $original_default_font;
705 var $watermark_font;
706 var $defaultAlign;
707
708 // TABLE
709 var $defaultTableAlign;
710 var $tablethead;
711 var $thead_font_weight;
712 var $thead_font_style;
713 var $thead_font_smCaps;
714 var $thead_valign_default;
715 var $thead_textalign_default;
716 var $tabletfoot;
717 var $tfoot_font_weight;
718 var $tfoot_font_style;
719 var $tfoot_font_smCaps;
720 var $tfoot_valign_default;
721 var $tfoot_textalign_default;
722
723 var $trow_text_rotate;
724
725 var $cellPaddingL;
726 var $cellPaddingR;
727 var $cellPaddingT;
728 var $cellPaddingB;
729 var $table_lineheight;
730 var $table_border_attr_set;
731 var $table_border_css_set;
732
733 var $shrin_k; // factor with which to shrink tables - used internally - do not change
734 var $shrink_this_table_to_fit; // 0 or false to disable; value (if set) gives maximum factor to reduce fontsize
735 var $MarginCorrection; // corrects for OddEven Margins
736 var $margin_footer;
737 var $margin_header;
738
739 var $tabletheadjustfinished;
740 var $usingCoreFont;
741 var $charspacing;
742
743 //Private properties FROM FPDF
744 var $DisplayPreferences;
745 var $flowingBlockAttr;
746 var $page; //current page number
747 var $n; //current object number
748 var $offsets; //array of object offsets
749 var $buffer; //buffer holding in-memory PDF
750 var $pages; //array containing pages
751 var $state; //current document state
752 var $compress; //compression flag
753 var $DefOrientation; //default orientation
754 var $CurOrientation; //current orientation
755 var $OrientationChanges; //array indicating orientation changes
756 var $k; //scale factor (number of points in user unit)
757 var $fwPt;
758 var $fhPt; //dimensions of page format in points
759 var $fw;
760 var $fh; //dimensions of page format in user unit
761 var $wPt;
762 var $hPt; //current dimensions of page in points
763 var $w;
764 var $h; //current dimensions of page in user unit
765 var $lMargin; //left margin
766 var $tMargin; //top margin
767 var $rMargin; //right margin
768 var $bMargin; //page break margin
769 var $cMarginL; //cell margin Left
770 var $cMarginR; //cell margin Right
771 var $cMarginT; //cell margin Left
772 var $cMarginB; //cell margin Right
773 var $DeflMargin; //Default left margin
774 var $DefrMargin; //Default right margin
775 var $x;
776 var $y; //current position in user unit for cell positioning
777 var $lasth; //height of last cell printed
778 var $LineWidth; //line width in user unit
779 var $CoreFonts; //array of standard font names
780 var $fonts; //array of used fonts
781 var $FontFiles; //array of font files
782 var $images; //array of used images
783 var $PageLinks; //array of links in pages
784 var $links; //array of internal links
785 var $FontFamily; //current font family
786 var $FontStyle; //current font style
787 var $CurrentFont; //current font info
788 var $FontSizePt; //current font size in points
789 var $FontSize; //current font size in user unit
790 var $DrawColor; //commands for drawing color
791 var $FillColor; //commands for filling color
792 var $TextColor; //commands for text color
793 var $ColorFlag; //indicates whether fill and text colors are different
794 var $autoPageBreak; //automatic page breaking
795 var $PageBreakTrigger; //threshold used to trigger page breaks
796 var $InFooter; //flag set when processing footer
797 var $InHTMLFooter;
798
799 var $processingFooter; //flag set when processing footer - added for columns
800 var $processingHeader; //flag set when processing header - added for columns
801 var $ZoomMode; //zoom display mode
802 var $LayoutMode; //layout display mode
803 var $title; //title
804 var $subject; //subject
805 var $author; //author
806 var $keywords; //keywords
807 var $creator; //creator
808
809 var $aliasNbPg; //alias for total number of pages
810 var $aliasNbPgGp; //alias for total number of pages in page group
811 var $aliasNbPgHex;
812 var $aliasNbPgGpHex;
813
814 var $ispre;
815
816 var $outerblocktags;
817 var $innerblocktags;
818
819
820 // **********************************
821 // **********************************
822 // **********************************
823 // **********************************
824 // **********************************
825 // **********************************
826 // **********************************
827 // **********************************
828 // **********************************
829
830 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') {
831
832 /*-- BACKGROUNDS --*/
833 if (!class_exists('grad', false)) { include(_MPDF_PATH.'classes/grad.php'); }
834 if (empty($this->grad)) { $this->grad = new grad($this); }
835 /*-- END BACKGROUNDS --*/
836 /*-- FORMS --*/
837 if (!class_exists('form', false)) { include(_MPDF_PATH.'classes/form.php'); }
838 if (empty($this->form)) { $this->form = new form($this); }
839 /*-- END FORMS --*/
840
841 $this->time0 = microtime(true);
842 //Some checks
843 $this->_dochecks();
844
845 // Set up Aliases for backwards compatability
846 $this->UnvalidatedText =& $this->watermarkText;
847 $this->TopicIsUnvalidated =& $this->showWatermarkText;
848 $this->AliasNbPg =& $this->aliasNbPg;
849 $this->AliasNbPgGp =& $this->aliasNbPgGp;
850 $this->BiDirectional =& $this->biDirectional;
851 $this->Anchor2Bookmark =& $this->anchor2Bookmark;
852 $this->KeepColumns =& $this->keepColumns;
853 $this->useOddEven =& $this->mirrorMargins;
854 $this->useSubstitutionsMB =& $this->useSubstitutions;
855
856 $this->writingToC = false; // mPDF 5.6.38
857 $this->uniqstr = '20110230'; // mPDF 5.7.2
858 // mPDF 5.6.01
859 $this->layers = array();
860 $this->current_layer = 0;
861 $this->open_layer_pane = false;
862
863 $this->visibility='visible';
864
865 //Initialization of properties
866 $this->spotColors=array();
867 $this->spotColorIDs = array();
868 $this->tableBackgrounds = array();
869
870 $this->kt_y00 = '';
871 $this->kt_p00 = '';
872 $this->iterationCounter = false;
873 $this->BMPonly = array();
874 $this->page=0;
875 $this->n=2;
876 $this->buffer='';
877 $this->objectbuffer = array();
878 $this->pages=array();
879 $this->OrientationChanges=array();
880 $this->state=0;
881 $this->fonts=array();
882 $this->FontFiles=array();
883 $this->images=array();
884 $this->links=array();
885 $this->InFooter=false;
886 $this->processingFooter=false;
887 $this->processingHeader=false;
888 $this->lasth=0;
889 $this->FontFamily='';
890 $this->FontStyle='';
891 $this->FontSizePt=9;
892 $this->U=false;
893 // Small Caps
894 $this->upperCase = array();
895 $this->S = false;
896 $this->smCapsScale = 1;
897 $this->smCapsStretch = 100;
898 $this->margBuffer = 0; // mPDF 5.4.04
899 $this->inMeter = false; // mPDF 5.5.09
900 $this->decimal_offset = 0;
901
902 $this->defTextColor = $this->TextColor = $this->SetTColor($this->ConvertColor(0),true);
903 $this->defDrawColor = $this->DrawColor = $this->SetDColor($this->ConvertColor(0),true);
904 $this->defFillColor = $this->FillColor = $this->SetFColor($this->ConvertColor(255),true);
905
906 //SVG color names array
907 //http://www.w3schools.com/css/css_colornames.asp
908 $this->SVGcolors = array('antiquewhite'=>'#FAEBD7','aqua'=>'#00FFFF','aquamarine'=>'#7FFFD4','beige'=>'#F5F5DC','black'=>'#000000',
909 'blue'=>'#0000FF','brown'=>'#A52A2A','cadetblue'=>'#5F9EA0','chocolate'=>'#D2691E','cornflowerblue'=>'#6495ED','crimson'=>'#DC143C',
910 'darkblue'=>'#00008B','darkgoldenrod'=>'#B8860B','darkgreen'=>'#006400','darkmagenta'=>'#8B008B','darkorange'=>'#FF8C00',
911 'darkred'=>'#8B0000','darkseagreen'=>'#8FBC8F','darkslategray'=>'#2F4F4F','darkviolet'=>'#9400D3','deepskyblue'=>'#00BFFF',
912 'dodgerblue'=>'#1E90FF','firebrick'=>'#B22222','forestgreen'=>'#228B22','fuchsia'=>'#FF00FF','gainsboro'=>'#DCDCDC','gold'=>'#FFD700',
913 'gray'=>'#808080','green'=>'#008000','greenyellow'=>'#ADFF2F','hotpink'=>'#FF69B4','indigo'=>'#4B0082','khaki'=>'#F0E68C',
914 'lavenderblush'=>'#FFF0F5','lemonchiffon'=>'#FFFACD','lightcoral'=>'#F08080','lightgoldenrodyellow'=>'#FAFAD2','lightgreen'=>'#90EE90',
915 'lightsalmon'=>'#FFA07A','lightskyblue'=>'#87CEFA','lightslategray'=>'#778899','lightyellow'=>'#FFFFE0','lime'=>'#00FF00','limegreen'=>'#32CD32',
916 'magenta'=>'#FF00FF','maroon'=>'#800000','mediumaquamarine'=>'#66CDAA','mediumorchid'=>'#BA55D3','mediumseagreen'=>'#3CB371',
917 'mediumspringgreen'=>'#00FA9A','mediumvioletred'=>'#C71585','midnightblue'=>'#191970','mintcream'=>'#F5FFFA','moccasin'=>'#FFE4B5','navy'=>'#000080',
918 'olive'=>'#808000','orange'=>'#FFA500','orchid'=>'#DA70D6','palegreen'=>'#98FB98',
919 'palevioletred'=>'#D87093','peachpuff'=>'#FFDAB9','pink'=>'#FFC0CB','powderblue'=>'#B0E0E6','purple'=>'#800080',
920 'red'=>'#FF0000','royalblue'=>'#4169E1','salmon'=>'#FA8072','seagreen'=>'#2E8B57','sienna'=>'#A0522D','silver'=>'#C0C0C0','skyblue'=>'#87CEEB',
921 'slategray'=>'#708090','springgreen'=>'#00FF7F','steelblue'=>'#4682B4','tan'=>'#D2B48C','teal'=>'#008080','thistle'=>'#D8BFD8','turquoise'=>'#40E0D0',
922 'violetred'=>'#D02090','white'=>'#FFFFFF','yellow'=>'#FFFF00',
923 'aliceblue'=>'#f0f8ff', 'azure'=>'#f0ffff', 'bisque'=>'#ffe4c4', 'blanchedalmond'=>'#ffebcd', 'blueviolet'=>'#8a2be2', 'burlywood'=>'#deb887',
924 'chartreuse'=>'#7fff00', 'coral'=>'#ff7f50', 'cornsilk'=>'#fff8dc', 'cyan'=>'#00ffff', 'darkcyan'=>'#008b8b', 'darkgray'=>'#a9a9a9',
925 'darkgrey'=>'#a9a9a9', 'darkkhaki'=>'#bdb76b', 'darkolivegreen'=>'#556b2f', 'darkorchid'=>'#9932cc', 'darksalmon'=>'#e9967a',
926 'darkslateblue'=>'#483d8b', 'darkslategrey'=>'#2f4f4f', 'darkturquoise'=>'#00ced1', 'deeppink'=>'#ff1493', 'dimgray'=>'#696969',
927 'dimgrey'=>'#696969', 'floralwhite'=>'#fffaf0', 'ghostwhite'=>'#f8f8ff', 'goldenrod'=>'#daa520', 'grey'=>'#808080', 'honeydew'=>'#f0fff0',
928 'indianred'=>'#cd5c5c', 'ivory'=>'#fffff0', 'lavender'=>'#e6e6fa', 'lawngreen'=>'#7cfc00', 'lightblue'=>'#add8e6', 'lightcyan'=>'#e0ffff',
929 'lightgray'=>'#d3d3d3', 'lightgrey'=>'#d3d3d3', 'lightpink'=>'#ffb6c1', 'lightseagreen'=>'#20b2aa', 'lightslategrey'=>'#778899',
930 'lightsteelblue'=>'#b0c4de', 'linen'=>'#faf0e6', 'mediumblue'=>'#0000cd', 'mediumpurple'=>'#9370db', 'mediumslateblue'=>'#7b68ee',
931 'mediumturquoise'=>'#48d1cc', 'mistyrose'=>'#ffe4e1', 'navajowhite'=>'#ffdead', 'oldlace'=>'#fdf5e6', 'olivedrab'=>'#6b8e23', 'orangered'=>'#ff4500',
932 'palegoldenrod'=>'#eee8aa', 'paleturquoise'=>'#afeeee', 'papayawhip'=>'#ffefd5', 'peru'=>'#cd853f', 'plum'=>'#dda0dd', 'rosybrown'=>'#bc8f8f',
933 'saddlebrown'=>'#8b4513', 'sandybrown'=>'#f4a460', 'seashell'=>'#fff5ee', 'slateblue'=>'#6a5acd', 'slategrey'=>'#708090', 'snow'=>'#fffafa',
934 'tomato'=>'#ff6347', 'violet'=>'#ee82ee', 'wheat'=>'#f5deb3', 'whitesmoke'=>'#f5f5f5', 'yellowgreen'=>'#9acd32');
935
936 $this->ColorFlag=false;
937 $this->extgstates = array();
938
939 $this->mb_enc='windows-1252';
940 $this->directionality='ltr';
941 $this->defaultAlign = 'L';
942 $this->defaultTableAlign = 'L';
943
944 $this->fixedPosBlockSave = array();
945 $this->extraFontSubsets = 0;
946
947 $this->SHYpatterns = array();
948 $this->loadedSHYdictionary = false;
949 $this->SHYdictionary = array();
950 $this->SHYdictionaryWords = array();
951 $this->blockContext = 1;
952 $this->floatDivs = array();
953 $this->DisplayPreferences='';
954
955 $this->patterns = array(); // Tiling patterns used for backgrounds
956 $this->pageBackgrounds = array();
957 $this->writingHTMLheader = false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
958 $this->writingHTMLfooter = false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
959 $this->gradients = array();
960
961 $this->kwt_Reference = array();
962 $this->kwt_BMoutlines = array();
963 $this->kwt_toc = array();
964
965 $this->tbrot_Reference = array();
966 $this->tbrot_BMoutlines = array();
967 $this->tbrot_toc = array();
968
969 $this->col_Reference = array();
970 $this->col_BMoutlines = array();
971 $this->col_toc = array();
972 $this->graphs = array();
973
974 $this->pgsIns = array();
975 $this->PDFAXwarnings = array();
976 $this->inlineDisplayOff = false;
977 $this->kerning = false;
978 $this->lSpacingCSS = '';
979 $this->wSpacingCSS = '';
980 $this->fixedlSpacing = false;
981 $this->minwSpacing = 0;
982
983
984 $this->baselineC = 0.35; // Baseline for text
985 // mPDF 5.7.3 inline text-decoration parameters
986 $this->baselineSup = 0.5; // Sets default change in baseline for <sup> text bas factor of preceeding fontsize
987 $this->baselineSub = -0.2; // Sets default change in baseline for <sub> text bas factor of preceeding fontsize
988 $this->baselineS = 0.3; // Sets default height for <strike> text as factor of fontsize
989
990 $this->noImageFile = str_replace("\\","/",dirname(__FILE__)) . '/includes/no_image.jpg';
991 $this->subPos = 0;
992 $this->forceExactLineheight = false;
993 $this->listOcc = 0;
994 $this->normalLineheight = 1.3;
995 // These are intended as configuration variables, and should be set in config.php - which will override these values;
996 // set here as failsafe as will cause an error if not defined
997 $this->incrementFPR1 = 10;
998 $this->incrementFPR2 = 10;
999 $this->incrementFPR3 = 10;
1000 $this->incrementFPR4 = 10;
1001
1002 $this->fullImageHeight = false;
1003 $this->floatbuffer = array();
1004 $this->floatmargins = array();
1005 $this->autoFontGroups = 0;
1006 $this->formobjects=array(); // array of Form Objects for WMF
1007 $this->InlineProperties=array();
1008 $this->InlineAnnots=array();
1009 $this->ktAnnots=array();
1010 $this->tbrot_Annots=array();
1011 $this->kwt_Annots=array();
1012 $this->columnAnnots=array();
1013 $this->pageDim=array();
1014 $this->breakpoints = array(); // used in columnbuffer
1015 $this->tableLevel=0;
1016 $this->tbctr=array(); // counter for nested tables at each level
1017 $this->page_box = array();
1018 $this->show_marks = ''; // crop or cross marks
1019 $this->kwt = false;
1020 $this->kwt_height = 0;
1021 $this->kwt_y0 = 0;
1022 $this->kwt_x0 = 0;
1023 $this->kwt_buffer = array();
1024 $this->kwt_Links = array();
1025 $this->kwt_moved = false;
1026 $this->kwt_saved = false;
1027 $this->PageNumSubstitutions = array();
1028 $this->base_table_properties=array();
1029 $this->borderstyles = array('inset','groove','outset','ridge','dotted','dashed','solid','double');
1030 $this->tbrot_align = 'C';
1031 $this->pageheaders=array();
1032 $this->pagefooters=array();
1033
1034 $this->pageHTMLheaders=array();
1035 $this->pageHTMLfooters=array();
1036 $this->HTMLheaderPageLinks = array();
1037 $this->HTMLheaderPageAnnots = array();
1038
1039 $this->ktForms = array();
1040 $this->HTMLheaderPageForms = array();
1041 $this->columnForms = array();
1042 $this->tbrotForms = array();
1043 $this->useRC128encryption = false;
1044 $this->uniqid = '';
1045
1046 $this->bufferoutput = false;
1047 $this->encrypted=false; //whether document is protected
1048 $this->BMoutlines=array();
1049 $this->ColActive=0; //Flag indicating that columns are on (the index is being processed)
1050 $this->Reference=array(); //Array containing the references
1051 $this->CurrCol=0; //Current column number
1052 $this->ColL = array(0); // Array of Left pos of columns - absolute - needs Margin correction for Odd-Even
1053 $this->ColR = array(0); // Array of Right pos of columns - absolute pos - needs Margin correction for Odd-Even
1054 $this->ChangeColumn = 0;
1055 $this->columnbuffer = array();
1056 $this->ColDetails = array(); // Keeps track of some column details
1057 $this->columnLinks = array(); // Cross references PageLinks
1058 $this->substitute = array(); // Array of substitution strings e.g. <ttz>112</ttz>
1059 $this->entsearch = array(); // Array of HTML entities (>ASCII 127) to substitute
1060 $this->entsubstitute = array(); // Array of substitution decimal unicode for the Hi entities
1061 $this->lastoptionaltag = '';
1062 $this->charset_in = '';
1063 $this->blk = array();
1064 $this->blklvl = 0;
1065 $this->tts = false;
1066 $this->ttz = false;
1067 $this->tta = false;
1068 $this->ispre=false;
1069
1070 $this->checkSIP = false;
1071 $this->checkSMP = false;
1072 $this->checkCJK = false;
1073 $this->tableCJK = false;
1074
1075 $this->headerDetails=array();
1076 $this->footerDetails=array();
1077 $this->page_break_after_avoid = false;
1078 $this->margin_bottom_collapse = false;
1079 $this->tablethead = 0;
1080 $this->tabletfoot = 0;
1081 $this->table_border_attr_set = 0;
1082 $this->table_border_css_set = 0;
1083 $this->shrin_k = 1.0;
1084 $this->shrink_this_table_to_fit = 0;
1085 $this->MarginCorrection = 0;
1086
1087 $this->tabletheadjustfinished = false;
1088 $this->usingCoreFont = false;
1089 $this->charspacing=0;
1090
1091 $this->autoPageBreak = true;
1092
1093 require(_MPDF_PATH.'config.php'); // config data
1094
1095 $this->_setPageSize($format, $orientation);
1096 $this->DefOrientation=$orientation;
1097
1098 $this->margin_header=$mgh;
1099 $this->margin_footer=$mgf;
1100
1101 $bmargin=$mgb;
1102
1103 $this->DeflMargin = $mgl;
1104 $this->DefrMargin = $mgr;
1105
1106 $this->orig_tMargin = $mgt;
1107 $this->orig_bMargin = $bmargin;
1108 $this->orig_lMargin = $this->DeflMargin;
1109 $this->orig_rMargin = $this->DefrMargin;
1110 $this->orig_hMargin = $this->margin_header;
1111 $this->orig_fMargin = $this->margin_footer;
1112
1113 if ($this->setAutoTopMargin=='pad') { $mgt += $this->margin_header; }
1114 if ($this->setAutoBottomMargin=='pad') { $mgb += $this->margin_footer; }
1115 $this->SetMargins($this->DeflMargin,$this->DefrMargin,$mgt); // sets l r t margin
1116 //Automatic page break
1117 $this->SetAutoPageBreak($this->autoPageBreak,$bmargin); // sets $this->bMargin & PageBreakTrigger
1118
1119 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
1120
1121 //Interior cell margin (1 mm) ? not used
1122 $this->cMarginL = 1;
1123 $this->cMarginR = 1;
1124 //Line width (0.2 mm)
1125 $this->LineWidth=.567/_MPDFK;
1126
1127 //To make the function Footer() work - replaces {nb} with page number
1128 $this->AliasNbPages();
1129 $this->AliasNbPageGroups();
1130
1131 $this->aliasNbPgHex = '{nbHEXmarker}';
1132 $this->aliasNbPgGpHex = '{nbpgHEXmarker}';
1133
1134 //Enable all tags as default
1135 $this->DisableTags();
1136 //Full width display mode
1137 $this->SetDisplayMode(100); // fullwidth? 'fullpage'
1138 //Compression
1139 $this->SetCompression(true);
1140 //Set default display preferences
1141 $this->SetDisplayPreferences('');
1142
1143 // Font data
1144 require(_MPDF_PATH.'config_fonts.php');
1145 // Available fonts
1146 $this->available_unifonts = array();
1147 foreach ($this->fontdata AS $f => $fs) {
1148 if (isset($fs['R']) && $fs['R']) { $this->available_unifonts[] = $f; }
1149 if (isset($fs['B']) && $fs['B']) { $this->available_unifonts[] = $f.'B'; }
1150 if (isset($fs['I']) && $fs['I']) { $this->available_unifonts[] = $f.'I'; }
1151 if (isset($fs['BI']) && $fs['BI']) { $this->available_unifonts[] = $f.'BI'; }
1152 }
1153
1154 $this->default_available_fonts = $this->available_unifonts;
1155
1156 $optcore = false;
1157 $onlyCoreFonts = false;
1158 if (preg_match('/([\-+])aCJK/i',$mode, $m)) {
1159 $mode = preg_replace('/([\-+])aCJK/i','',$mode);
1160 if ($m[1]=='+') { $this->useAdobeCJK = true; }
1161 else { $this->useAdobeCJK = false; }
1162 }
1163
1164 if (strlen($mode)==1) {
1165 if ($mode=='s') { $this->percentSubset = 100; $mode = ''; }
1166 else if ($mode=='c') { $onlyCoreFonts = true; $mode = ''; }
1167 }
1168 else if (substr($mode,-2)=='-s') {
1169 $this->percentSubset = 100;
1170 $mode = substr($mode,0,strlen($mode)-2);
1171 }
1172 else if (substr($mode,-2)=='-c') {
1173 $onlyCoreFonts = true;
1174 $mode = substr($mode,0,strlen($mode)-2);
1175 }
1176 else if (substr($mode,-2)=='-x') {
1177 $optcore = true;
1178 $mode = substr($mode,0,strlen($mode)-2);
1179 }
1180
1181 // Autodetect if mode is a language_country string (en-GB or en_GB or en)
1182 if ((strlen($mode) == 5 && $mode != 'UTF-8') || strlen($mode) == 2) {
1183 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($mode, $this->useAdobeCJK);
1184 if ($coreSuitable && $optcore) { $onlyCoreFonts = true; }
1185 if ($mpdf_pdf_unifonts) {
1186 $this->RestrictUnicodeFonts($mpdf_pdf_unifonts);
1187 $this->default_available_fonts = $mpdf_pdf_unifonts;
1188 }
1189 $this->currentLang = $mode;
1190 $this->default_lang = $mode;
1191 }
1192
1193 $this->onlyCoreFonts = $onlyCoreFonts;
1194
1195 if ($this->onlyCoreFonts) {
1196 $this->setMBencoding('windows-1252'); // sets $this->mb_enc
1197 }
1198 else {
1199 $this->setMBencoding('UTF-8'); // sets $this->mb_enc
1200 }
1201 @mb_regex_encoding('UTF-8'); // required only for mb_ereg... and mb_split functions
1202
1203
1204 // Adobe CJK fonts
1205 $this->available_CJK_fonts = array('gb','big5','sjis','uhc','gbB','big5B','sjisB','uhcB','gbI','big5I','sjisI','uhcI',
1206 'gbBI','big5BI','sjisBI','uhcBI');
1207
1208
1209 //Standard fonts
1210 $this->CoreFonts=array('ccourier'=>'Courier','ccourierB'=>'Courier-Bold','ccourierI'=>'Courier-Oblique','ccourierBI'=>'Courier-BoldOblique',
1211 'chelvetica'=>'Helvetica','chelveticaB'=>'Helvetica-Bold','chelveticaI'=>'Helvetica-Oblique','chelveticaBI'=>'Helvetica-BoldOblique',
1212 'ctimes'=>'Times-Roman','ctimesB'=>'Times-Bold','ctimesI'=>'Times-Italic','ctimesBI'=>'Times-BoldItalic',
1213 'csymbol'=>'Symbol','czapfdingbats'=>'ZapfDingbats');
1214 $this->fontlist=array("ctimes","ccourier","chelvetica","csymbol","czapfdingbats");
1215
1216 // Substitutions
1217 $this->setHiEntitySubstitutions();
1218
1219 if ($this->onlyCoreFonts) {
1220 $this->useSubstitutions = true;
1221 $this->SetSubstitutions();
1222 }
1223 else { $this->useSubstitutions = false; }
1224
1225 /*-- HTML-CSS --*/
1226
1227 if (!class_exists('cssmgr', false)) { include(_MPDF_PATH .'classes/cssmgr.php'); }
1228 $this->cssmgr = new cssmgr($this);
1229 if (file_exists(_MPDF_PATH.'mpdf.css')) {
1230 $css = file_get_contents(_MPDF_PATH.'mpdf.css');
1231 $css2 = $this->cssmgr->ReadDefaultCSS($css);
1232 $this->defaultCSS = $this->cssmgr->array_merge_recursive_unique($this->defaultCSS,$css2);
1233 }
1234 /*-- END HTML-CSS --*/
1235
1236 if ($default_font=='') {
1237 if ($this->onlyCoreFonts) {
1238 if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']),$this->mono_fonts)) { $default_font = 'ccourier'; }
1239 else if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']),$this->sans_fonts)) { $default_font = 'chelvetica'; }
1240 else { $default_font = 'ctimes'; }
1241 }
1242 else { $default_font = $this->defaultCSS['BODY']['FONT-FAMILY']; }
1243 }
1244 if (!$default_font_size) {
1245 $mmsize = $this->ConvertSize($this->defaultCSS['BODY']['FONT-SIZE']);
1246 $default_font_size = $mmsize*(_MPDFK);
1247 }
1248
1249 if ($default_font) { $this->SetDefaultFont($default_font); }
1250 if ($default_font_size) { $this->SetDefaultFontSize($default_font_size); }
1251
1252 $this->SetLineHeight(); // lineheight is in mm
1253
1254 $this->SetFColor($this->ConvertColor(255));
1255 $this->HREF='';
1256 $this->oldy=-1;
1257 $this->B=0;
1258 $this->U=false;
1259 $this->S=false;
1260 $this->I=0;
1261
1262 $this->listlvl=0;
1263 $this->listnum=0;
1264 $this->listtype='';
1265 $this->listoccur=array();
1266 $this->listlist=array();
1267 $this->listitem=array();
1268
1269 $this->tdbegin=false;
1270 $this->table=array();
1271 $this->cell=array();
1272 $this->col=-1;
1273 $this->row=-1;
1274 $this->cellBorderBuffer = array();
1275
1276 $this->divbegin=false;
1277 $this->divalign='';
1278 $this->divwidth=0;
1279 $this->divheight=0;
1280 $this->spanbgcolor=false;
1281 $this->divrevert=false;
1282 $this->spanborder=false;
1283 $this->spanborddet=array();
1284
1285 $this->blockjustfinished=false;
1286 $this->listjustfinished=false;
1287 $this->ignorefollowingspaces = true; //in order to eliminate exceeding left-side spaces
1288 $this->toupper=false;
1289 $this->tolower=false;
1290 $this->capitalize=false;
1291 $this->dash_on=false;
1292 $this->dotted_on=false;
1293 $this->SUP=false;
1294 $this->SUB=false;
1295 $this->strike=false;
1296 $this->textshadow='';
1297
1298 $this->currentfontfamily='';
1299 $this->currentfontsize='';
1300 $this->currentfontstyle='';
1301 $this->colorarray=array();
1302 $this->spanbgcolorarray=array();
1303 $this->textbuffer=array();
1304 $this->internallink=array();
1305 $this->basepath = "";
1306
1307 $this->SetBasePath('');
1308
1309 $this->textparam = array();
1310
1311 $this->specialcontent = '';
1312 $this->selectoption = array();
1313
1314 /*-- IMPORTS --*/
1315
1316 $this->tpls = array();
1317 $this->tpl = 0;
1318 $this->tplprefix = "/TPL";
1319 $this->res = array();
1320 if ($this->enableImports) {
1321 $this->SetImportUse();
1322 }
1323 /*-- END IMPORTS --*/
1324
1325 if ($this->progressBar) { $this->StartProgressBarOutput($this->progressBar) ; } // *PROGRESS-BAR*
1326 }
1327
1328
1329 function _setPageSize($format, &$orientation) {
1330 //Page format
1331 if(is_string($format))
1332 {
1333 if ($format=='') { $format = 'A4'; }
1334 $pfo = 'P';
1335 if(preg_match('/([0-9a-zA-Z]*)-L/i',$format,$m)) { // e.g. A4-L = A4 landscape
1336 $format=$m[1];
1337 $pfo='L';
1338 }
1339 $format = $this->_getPageFormat($format);
1340 if (!$format) { $this->Error('Unknown page format: '.$format); }
1341 else { $orientation = $pfo; }
1342
1343 $this->fwPt=$format[0];
1344 $this->fhPt=$format[1];
1345 }
1346 else
1347 {
1348 if (!$format[0] || !$format[1]) { $this->Error('Invalid page format: '.$format[0].' '.$format[1]); }
1349 $this->fwPt=$format[0]*_MPDFK;
1350 $this->fhPt=$format[1]*_MPDFK;
1351 }
1352 $this->fw=$this->fwPt/_MPDFK;
1353 $this->fh=$this->fhPt/_MPDFK;
1354 //Page orientation
1355 $orientation=strtolower($orientation);
1356 if($orientation=='p' or $orientation=='portrait')
1357 {
1358 $orientation='P';
1359 $this->wPt=$this->fwPt;
1360 $this->hPt=$this->fhPt;
1361 }
1362 elseif($orientation=='l' or $orientation=='landscape')
1363 {
1364 $orientation='L';
1365 $this->wPt=$this->fhPt;
1366 $this->hPt=$this->fwPt;
1367 }
1368 else $this->Error('Incorrect orientation: '.$orientation);
1369 $this->CurOrientation=$orientation;
1370
1371 $this->w=$this->wPt/_MPDFK;
1372 $this->h=$this->hPt/_MPDFK;
1373 }
1374
1375 function _getPageFormat($format) {
1376 switch (strtoupper($format)) {
1377 case '4A0': {$format = array(4767.87,6740.79); break;}
1378 case '2A0': {$format = array(3370.39,4767.87); break;}
1379 case 'A0': {$format = array(2383.94,3370.39); break;}
1380 case 'A1': {$format = array(1683.78,2383.94); break;}
1381 case 'A2': {$format = array(1190.55,1683.78); break;}
1382 case 'A3': {$format = array(841.89,1190.55); break;}
1383 case 'A4': {$format = array(595.28,841.89); break;} // mPDF 5.7.4
1384 case 'A5': {$format = array(419.53,595.28); break;}
1385 case 'A6': {$format = array(297.64,419.53); break;}
1386 case 'A7': {$format = array(209.76,297.64); break;}
1387 case 'A8': {$format = array(147.40,209.76); break;}
1388 case 'A9': {$format = array(104.88,147.40); break;}
1389 case 'A10': {$format = array(73.70,104.88); break;}
1390 case 'B0': {$format = array(2834.65,4008.19); break;}
1391 case 'B1': {$format = array(2004.09,2834.65); break;}
1392 case 'B2': {$format = array(1417.32,2004.09); break;}
1393 case 'B3': {$format = array(1000.63,1417.32); break;}
1394 case 'B4': {$format = array(708.66,1000.63); break;}
1395 case 'B5': {$format = array(498.90,708.66); break;}
1396 case 'B6': {$format = array(354.33,498.90); break;}
1397 case 'B7': {$format = array(249.45,354.33); break;}
1398 case 'B8': {$format = array(175.75,249.45); break;}
1399 case 'B9': {$format = array(124.72,175.75); break;}
1400 case 'B10': {$format = array(87.87,124.72); break;}
1401 case 'C0': {$format = array(2599.37,3676.54); break;}
1402 case 'C1': {$format = array(1836.85,2599.37); break;}
1403 case 'C2': {$format = array(1298.27,1836.85); break;}
1404 case 'C3': {$format = array(918.43,1298.27); break;}
1405 case 'C4': {$format = array(649.13,918.43); break;}
1406 case 'C5': {$format = array(459.21,649.13); break;}
1407 case 'C6': {$format = array(323.15,459.21); break;}
1408 case 'C7': {$format = array(229.61,323.15); break;}
1409 case 'C8': {$format = array(161.57,229.61); break;}
1410 case 'C9': {$format = array(113.39,161.57); break;}
1411 case 'C10': {$format = array(79.37,113.39); break;}
1412 case 'RA0': {$format = array(2437.80,3458.27); break;}
1413 case 'RA1': {$format = array(1729.13,2437.80); break;}
1414 case 'RA2': {$format = array(1218.90,1729.13); break;}
1415 case 'RA3': {$format = array(864.57,1218.90); break;}
1416 case 'RA4': {$format = array(609.45,864.57); break;}
1417 case 'SRA0': {$format = array(2551.18,3628.35); break;}
1418 case 'SRA1': {$format = array(1814.17,2551.18); break;}
1419 case 'SRA2': {$format = array(1275.59,1814.17); break;}
1420 case 'SRA3': {$format = array(907.09,1275.59); break;}
1421 case 'SRA4': {$format = array(637.80,907.09); break;}
1422 case 'LETTER': {$format = array(612.00,792.00); break;}
1423 case 'LEGAL': {$format = array(612.00,1008.00); break;}
1424 case 'LEDGER': {$format = array(279.00,432.00); break;}
1425 case 'TABLOID': {$format = array(279.00,432.00); break;}
1426 case 'EXECUTIVE': {$format = array(521.86,756.00); break;}
1427 case 'FOLIO': {$format = array(612.00,936.00); break;}
1428 case 'B': {$format=array(362.83,561.26 ); break;} // 'B' format paperback size 128x198mm
1429 case 'A': {$format=array(314.65,504.57 ); break;} // 'A' format paperback size 111x178mm
1430 case 'DEMY': {$format=array(382.68,612.28 ); break;} // 'Demy' format paperback size 135x216mm
1431 case 'ROYAL': {$format=array(433.70,663.30 ); break;} // 'Royal' format paperback size 153x234mm
1432 default: {$format = array(595.28,841.89); break;} // mPDF 5.7.4
1433 }
1434 return $format;
1435 }
1436
1437
1438 /*-- PROGRESS-BAR --*/
1439 function StartProgressBarOutput($mode=1) {
1440 // must be relative path, or URI (not a file system path)
1441 if (!defined('_MPDF_URI')) {
1442 $this->progressBar = false;
1443 if ($this->debug) { $this->Error("You need to define _MPDF_URI to use the progress bar!"); }
1444 else return false;
1445 }
1446 $this->progressBar = $mode;
1447 if ($this->progbar_altHTML) {
1448 echo $this->progbar_altHTML;
1449 }
1450 else {
1451 echo '<html>
1452 <head>
1453 <title>mPDF File Progress</title>
1454 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1455 <link rel="stylesheet" type="text/css" href="'._MPDF_URI.'progbar.css" />
1456 </head>
1457 <body>
1458 <div class="main">
1459 <div class="heading">'.$this->progbar_heading.'</div>
1460 <div class="demo">
1461 ';
1462 if ($this->progressBar==2) { echo ' <table width="100%"><tr><td style="width: 50%;">
1463 <span class="barheading">Writing HTML code</span> <br/>
1464
1465 <div class="progressBar">
1466 <div id="element1" class="innerBar">&nbsp;</div>
1467 </div>
1468 <span class="code" id="box1"></span>
1469 </td><td style="width: 50%;">
1470 <span class="barheading">Autosizing elements</span> <br/>
1471 <div class="progressBar">
1472 <div id="element4" class="innerBar">&nbsp;</div>
1473 </div>
1474 <span class="code" id="box4"></span>
1475 <br/><br/>
1476 <span class="barheading">Writing Tables</span> <br/>
1477 <div class="progressBar">
1478 <div id="element7" class="innerBar">&nbsp;</div>
1479 </div>
1480 <span class="code" id="box7"></span>
1481 </td></tr>
1482 <tr><td><br /><br /></td><td></td></tr>
1483 <tr><td style="width: 50%;">
1484 '; }
1485 echo ' <span class="barheading">Writing PDF file</span> <br/>
1486 <div class="progressBar">
1487 <div id="element2" class="innerBar">&nbsp;</div>
1488 </div>
1489 <span class="code" id="box2"></span>
1490 ';
1491 if ($this->progressBar==2) { echo '
1492 </td><td style="width: 50%;">
1493 <span class="barheading">Memory usage</span> <br/>
1494 <div class="progressBar">
1495 <div id="element5" class="innerBar">&nbsp;</div>
1496 </div>
1497 <span id="box5">0</span> '.ini_get("memory_limit").'<br />
1498 <br/><br/>
1499 <span class="barheading">Memory usage (peak)</span> <br/>
1500 <div class="progressBar">
1501 <div id="element6" class="innerBar">&nbsp;</div>
1502 </div>
1503 <span id="box6">0</span> '.ini_get("memory_limit").'<br />
1504 </td></tr>
1505 </table>
1506 '; }
1507 echo ' <br/><br/>
1508 <span id="box3"></span>
1509
1510 </div>
1511 ';
1512 }
1513 ob_flush();
1514 flush();
1515 }
1516
1517 function UpdateProgressBar($el,$val,$txt='') {
1518 // $val should be a string - 5 = actual value, +15 = increment
1519
1520 if ($this->progressBar<2) {
1521 if ($el>3) { return; }
1522 else if ($el ==1) { $el = 2; }
1523 }
1524 echo '<script type="text/javascript">';
1525 if ($val) { echo ' document.getElementById(\'element'.$el.'\').style.width=\''.$val.'%\'; '; }
1526 if ($txt) { echo ' document.getElementById(\'box'.$el.'\').innerHTML=\''.$txt.'\'; '; }
1527 if ($this->progressBar==2) {
1528 $m = round(memory_get_usage(true)/1048576);
1529 $m2 = round(memory_get_peak_usage(true)/1048576);
1530 $mem = $m * 100 / (ini_get("memory_limit")+0);
1531 $mem2 = $m2 * 100 / (ini_get("memory_limit")+0);
1532 echo ' document.getElementById(\'element5\').style.width=\''.$mem.'%\'; ';
1533 echo ' document.getElementById(\'element6\').style.width=\''.$mem2.'%\'; ';
1534 echo ' document.getElementById(\'box5\').innerHTML=\''.$m.'MB / \'; ';
1535 echo ' document.getElementById(\'box6\').innerHTML=\''.$m2.'MB / \'; ';
1536 }
1537 echo '</script>'."\n";
1538 ob_flush();
1539 flush();
1540 }
1541 /*-- END PROGRESS-BAR --*/
1542
1543
1544
1545 function RestrictUnicodeFonts($res) {
1546 // $res = array of (Unicode) fonts to restrict to: e.g. norasi|norasiB - language specific
1547 if (count($res)) { // Leave full list of available fonts if passed blank array
1548 $this->available_unifonts = $res;
1549 }
1550 else { $this->available_unifonts = $this->default_available_fonts; }
1551 if (count($this->available_unifonts) == 0) { $this->available_unifonts[] = $this->default_available_fonts[0]; }
1552 $this->available_unifonts = array_values($this->available_unifonts);
1553 }
1554
1555
1556 function setMBencoding($enc) {
1557 if ($this->mb_enc != $enc) {
1558 $this->mb_enc = $enc;
1559 mb_internal_encoding($this->mb_enc);
1560 }
1561 }
1562
1563
1564 function SetMargins($left,$right,$top) {
1565 //Set left, top and right margins
1566 $this->lMargin=$left;
1567 $this->rMargin=$right;
1568 $this->tMargin=$top;
1569 }
1570
1571 function ResetMargins() {
1572 //ReSet left, top margins
1573 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P' && $this->CurOrientation=='L') {
1574 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
1575 $this->tMargin=$this->orig_rMargin;
1576 $this->bMargin=$this->orig_lMargin;
1577 }
1578 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS
1579 $this->tMargin=$this->orig_lMargin;
1580 $this->bMargin=$this->orig_rMargin;
1581 }
1582 $this->lMargin=$this->DeflMargin;
1583 $this->rMargin=$this->DefrMargin;
1584 $this->MarginCorrection = 0;
1585 $this->PageBreakTrigger=$this->h-$this->bMargin;
1586 }
1587 else if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
1588 $this->lMargin=$this->DefrMargin;
1589 $this->rMargin=$this->DeflMargin;
1590 $this->MarginCorrection = $this->DefrMargin-$this->DeflMargin;
1591
1592 }
1593 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS
1594 $this->lMargin=$this->DeflMargin;
1595 $this->rMargin=$this->DefrMargin;
1596 if ($this->mirrorMargins) { $this->MarginCorrection = $this->DeflMargin-$this->DefrMargin; }
1597 }
1598 $this->x=$this->lMargin;
1599
1600 }
1601
1602 function SetLeftMargin($margin) {
1603 //Set left margin
1604 $this->lMargin=$margin;
1605 if($this->page>0 and $this->x<$margin) $this->x=$margin;
1606 }
1607
1608 function SetTopMargin($margin) {
1609 //Set top margin
1610 $this->tMargin=$margin;
1611 }
1612
1613 function SetRightMargin($margin) {
1614 //Set right margin
1615 $this->rMargin=$margin;
1616 }
1617
1618 function SetAutoPageBreak($auto,$margin=0) {
1619 //Set auto page break mode and triggering margin
1620 $this->autoPageBreak=$auto;
1621 $this->bMargin=$margin;
1622 $this->PageBreakTrigger=$this->h-$margin;
1623 }
1624
1625 function SetDisplayMode($zoom,$layout='continuous') {
1626 //Set display mode in viewer
1627 if($zoom=='fullpage' or $zoom=='fullwidth' or $zoom=='real' or $zoom=='default' or !is_string($zoom))
1628 $this->ZoomMode=$zoom;
1629 else
1630 $this->Error('Incorrect zoom display mode: '.$zoom);
1631 if($layout=='single' or $layout=='continuous' or $layout=='two' or $layout=='twoleft' or $layout=='tworight' or $layout=='default')
1632 $this->LayoutMode=$layout;
1633 else
1634 $this->Error('Incorrect layout display mode: '.$layout);
1635 }
1636
1637 function SetCompression($compress) {
1638 //Set page compression
1639 if(function_exists('gzcompress')) $this->compress=$compress;
1640 else $this->compress=false;
1641 }
1642
1643 function SetTitle($title) {
1644 //Title of document // Arrives as UTF-8
1645 $this->title = $title;
1646 }
1647
1648 function SetSubject($subject) {
1649 //Subject of document
1650 $this->subject= $subject;
1651 }
1652
1653 function SetAuthor($author) {
1654 //Author of document
1655 $this->author= $author;
1656 }
1657
1658 function SetKeywords($keywords) {
1659 //Keywords of document
1660 $this->keywords= $keywords;
1661 }
1662
1663 function SetCreator($creator) {
1664 //Creator of document
1665 $this->creator= $creator;
1666 }
1667
1668
1669 function SetAnchor2Bookmark($x) {
1670 $this->anchor2Bookmark = $x;
1671 }
1672
1673 function AliasNbPages($alias='{nb}') {
1674 //Define an alias for total number of pages
1675 $this->aliasNbPg=$alias;
1676 }
1677
1678 function AliasNbPageGroups($alias='{nbpg}') {
1679 //Define an alias for total number of pages in a group
1680 $this->aliasNbPgGp=$alias;
1681 }
1682
1683 function SetAlpha($alpha, $bm='Normal', $return=false, $mode='B') {
1684 // alpha: real value from 0 (transparent) to 1 (opaque)
1685 // bm: blend mode, one of the following:
1686 // Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn,
1687 // HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity
1688 // set alpha for stroking (CA) and non-stroking (ca) operations
1689 // mode determines F (fill) S (stroke) B (both)
1690 if (($this->PDFA || $this->PDFX) && $alpha!=1) {
1691 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "Image opacity must be 100% (Opacity changed to 100%)"; }
1692 $alpha = 1;
1693 }
1694 $a = array('BM'=>'/'.$bm);
1695 if ($mode=='F' || $mode=='B') $a['ca'] = $alpha; // mPDF 5.7.2
1696 if ($mode=='S' || $mode=='B') $a['CA'] = $alpha; // mPDF 5.7.2
1697 $gs = $this->AddExtGState($a);
1698 if ($return) { return sprintf('/GS%d gs', $gs); }
1699 else { $this->_out(sprintf('/GS%d gs', $gs)); }
1700 }
1701
1702 function AddExtGState($parms) {
1703 $n = count($this->extgstates);
1704 // check if graphics state already exists
1705 for ($i=1; $i<=$n; $i++) {
1706 if (count($this->extgstates[$i]['parms']) == count($parms)) {
1707 $same = true;
1708 foreach($this->extgstates[$i]['parms'] AS $k=>$v) {
1709 if (!isset($parms[$k]) || $parms[$k] != $v) { $same = false; break; }
1710 }
1711 if ($same) { return $i; }
1712 }
1713 }
1714 $n++;
1715 $this->extgstates[$n]['parms'] = $parms;
1716 return $n;
1717 }
1718
1719 function SetVisibility($v) {
1720 if (($this->PDFA || $this->PDFX) && $this->visibility!='visible') { $this->PDFAXwarnings[] = "Cannot set visibility to anything other than full when using PDFA or PDFX"; return ''; }
1721 else if (!$this->PDFA && !$this->PDFX)
1722 $this->pdf_version='1.5';
1723 if($this->visibility!='visible') {
1724 $this->_out('EMC');
1725 $this->hasOC=intval($this->hasOC ); // mPDF 5.6.01
1726 }
1727 if($v=='printonly') {
1728 $this->_out('/OC /OC1 BDC');
1729 $this->hasOC=($this->hasOC | 1); // mPDF 5.6.01
1730 }
1731 elseif($v=='screenonly') {
1732 $this->_out('/OC /OC2 BDC');
1733 $this->hasOC=($this->hasOC | 2); // mPDF 5.6.01
1734 }
1735 elseif($v=='hidden') {
1736 $this->_out('/OC /OC3 BDC');
1737 $this->hasOC=($this->hasOC | 4); // mPDF 5.6.01
1738 }
1739 elseif($v!='visible')
1740 $this->Error('Incorrect visibility: '.$v);
1741 $this->visibility=$v;
1742 }
1743
1744 function Error($msg) {
1745 //Fatal error
1746 header('Content-Type: text/html; charset=utf-8');
1747 die('<B>mPDF error: </B>'.$msg);
1748 }
1749
1750 function Open() {
1751 //Begin document
1752 if($this->state==0) $this->_begindoc();
1753 }
1754
1755 function Close() {
1756 if ($this->progressBar) { $this->UpdateProgressBar(2,'2','Closing last page'); } // *PROGRESS-BAR*
1757 //Terminate document
1758 if($this->state==3) return;
1759 if($this->page==0) $this->AddPage($this->CurOrientation);
1760 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); } // *TABLES*
1761 if ($this->tablebuffer) { $this->printtablebuffer(); } // *TABLES*
1762 /*-- COLUMNS --*/
1763
1764 if ($this->ColActive) {
1765 $this->SetColumns(0);
1766 $this->ColActive = 0;
1767 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
1768 }
1769 /*-- END COLUMNS --*/
1770 if (count($this->divbuffer)) { $this->printdivbuffer(); }
1771
1772 // BODY Backgrounds
1773 $s = '';
1774
1775 $s .= $this->PrintBodyBackgrounds();
1776
1777 $s .= $this->PrintPageBackgrounds();
1778 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', "\n".$s."\n".'\\1', $this->pages[$this->page]);
1779 $this->pageBackgrounds = array();
1780
1781 if($this->visibility!='visible')
1782 $this->SetVisibility('visible');
1783 // mPDF 5.6.01 - LAYERS
1784 $this->EndLayer();
1785
1786 if (!$this->tocontents || !$this->tocontents->TOCmark) { //Page footer
1787 $this->InFooter=true;
1788 $this->Footer();
1789 $this->InFooter=false;
1790 }
1791 if ($this->tocontents && ($this->tocontents->TOCmark || count($this->tocontents->m_TOC))) { $this->tocontents->insertTOC(); } // *TOC*
1792
1793 //Close page
1794 $this->_endpage();
1795
1796 //Close document
1797 $this->_enddoc();
1798 }
1799
1800 /*-- BACKGROUNDS --*/
1801 function _resizeBackgroundImage($imw, $imh, $cw, $ch, $resize=0, $repx, $repy, $pba=array(), $size=array()) { // mPDF 5.6.10
1802 // pba is background positioning area (from CSS background-origin) may not always be set [x,y,w,h]
1803 // size is from CSS3 background-size - takes precendence over old resize
1804 // $w - absolute length or % or auto or cover | contain
1805 // $h - absolute length or % or auto or cover | contain
1806 // mPDF 5.6.10
1807 if (isset($pba['w'])) $cw = $pba['w'];
1808 if (isset($pba['h'])) $ch = $pba['h'];
1809
1810 $cw = $cw*_MPDFK;
1811 $ch = $ch*_MPDFK;
1812 if (empty($size) && !$resize) { return array($imw, $imh, $repx, $repy); }
1813
1814 // mPDF 5.6.10
1815 if (isset($size['w']) && $size['w']) {
1816 if ($size['w']=='contain') {
1817 // 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.
1818 // Same as resize==3
1819 $h = $imh * $cw/$imw;
1820 $w = $cw;
1821 if ($h > $ch) {
1822 $w = $w * $ch/$h;
1823 $h = $ch;
1824 }
1825 }
1826 else if ($size['w']=='cover') {
1827 // 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.
1828 $h = $imh * $cw/$imw;
1829 $w = $cw;
1830 if ($h < $ch) {
1831 $w = $w * $h/$ch;
1832 $h = $ch;
1833 }
1834 }
1835 else {
1836 if (stristr($size['w'] ,'%')) {
1837 $size['w'] += 0;
1838 $size['w'] /= 100;
1839 $size['w'] = ($cw * $size['w']);
1840 }
1841 if (stristr($size['h'] ,'%')) {
1842 $size['h'] += 0;
1843 $size['h'] /= 100;
1844 $size['h'] = ($ch * $size['h']);
1845 }
1846 if ($size['w']=='auto' && $size['h']=='auto') {
1847 $w = $imw;
1848 $h = $imh;
1849 }
1850 else if ($size['w']=='auto' && $size['h']!='auto') {
1851 $w = $imw * $size['h']/$imh;
1852 $h = $size['h'];
1853 }
1854 else if ($size['w']!='auto' && $size['h']=='auto') {
1855 $h = $imh * $size['w']/$imw;
1856 $w = $size['w'];
1857 }
1858 else {
1859 $w = $size['w'];
1860 $h = $size['h'];
1861 }
1862 }
1863 return array($w, $h, $repx, $repy);
1864 }
1865 else if ($resize==1 && $imw > $cw) {
1866 $h = $imh * $cw/$imw;
1867 return array($cw, $h, $repx, $repy);
1868 }
1869 else if ($resize==2 && $imh > $ch) {
1870 $w = $imw * $ch/$imh;
1871 return array($w, $ch, $repx, $repy);
1872 }
1873 else if ($resize==3) {
1874 $w = $imw;
1875 $h = $imh;
1876 if ($w > $cw) {
1877 $h = $h * $cw/$w;
1878 $w = $cw;
1879 }
1880 if ($h > $ch) {
1881 $w = $w * $ch/$h;
1882 $h = $ch;
1883 }
1884 return array($w, $h, $repx, $repy);
1885 }
1886 else if ($resize==4) {
1887 $h = $imh * $cw/$imw;
1888 return array($cw, $h, $repx, $repy);
1889 }
1890 else if ($resize==5) {
1891 $w = $imw * $ch/$imh;
1892 return array($w, $ch, $repx, $repy);
1893 }
1894 else if ($resize==6) {
1895 return array($cw, $ch, $repx, $repy);
1896 }
1897 return array($imw, $imh, $repx, $repy);
1898 }
1899
1900
1901 function SetBackground(&$properties, &$maxwidth) {
1902 // mPDF 5.6.10 5.6.11
1903 if (isset($properties['BACKGROUND-ORIGIN']) && ($properties['BACKGROUND-ORIGIN']=='border-box' || $properties['BACKGROUND-ORIGIN']== 'content-box')) { $origin = $properties['BACKGROUND-ORIGIN']; }
1904 else { $origin = 'padding-box'; }
1905 // mPDF 5.6.10
1906 if (isset($properties['BACKGROUND-SIZE'])) {
1907 if (stristr($properties['BACKGROUND-SIZE'] ,'contain') ) { $bsw = $bsh = 'contain'; }
1908 else if (stristr($properties['BACKGROUND-SIZE'] ,'cover') ) { $bsw = $bsh = 'cover'; }
1909 else {
1910 $bsw = $bsh = 'auto';
1911 $sz = preg_split('/\s+/',trim($properties['BACKGROUND-SIZE']));
1912 if (count($sz)==2) { $bsw = $sz[0]; $bsh = $sz[1]; }
1913 else { $bsw = $sz[0]; }
1914 if (!stristr($bsw ,'%') && !stristr($bsw ,'auto') ) { $bsw = $this->ConvertSize($bsw ,$maxwidth,$this->FontSize); }
1915 if (!stristr($bsh ,'%') && !stristr($bsh ,'auto') ) { $bsh = $this->ConvertSize($bsh ,$maxwidth,$this->FontSize); }
1916 }
1917 $size = array('w'=>$bsw, 'h'=>$bsh);
1918 }
1919 if (preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/',$properties['BACKGROUND-IMAGE'])) {
1920 return array('gradient'=>$properties['BACKGROUND-IMAGE'], 'origin'=>$origin, 'size'=>$size ); // mPDF 5.6.10
1921 }
1922 else {
1923 $file = $properties['BACKGROUND-IMAGE'];
1924 $sizesarray = $this->Image($file,0,0,0,0,'','',false, false, false, false, true);
1925 if (isset($sizesarray['IMAGE_ID'])) {
1926 $image_id = $sizesarray['IMAGE_ID'];
1927 $orig_w = $sizesarray['WIDTH']*_MPDFK; // in user units i.e. mm
1928 $orig_h = $sizesarray['HEIGHT']*_MPDFK; // (using $this->img_dpi)
1929 if (isset($properties['BACKGROUND-IMAGE-RESOLUTION'])) {
1930 if (preg_match('/from-image/i', $properties['BACKGROUND-IMAGE-RESOLUTION']) && isset($sizesarray['set-dpi']) && $sizesarray['set-dpi']>0) {
1931 $orig_w *= $this->img_dpi / $sizesarray['set-dpi'];
1932 $orig_h *= $this->img_dpi / $sizesarray['set-dpi'];
1933 }
1934 else if (preg_match('/(\d+)dpi/i', $properties['BACKGROUND-IMAGE-RESOLUTION'], $m)) {
1935 $dpi = $m[1];
1936 if ($dpi > 0) {
1937 $orig_w *= $this->img_dpi / $dpi;
1938 $orig_h *= $this->img_dpi / $dpi;
1939 }
1940 }
1941 }
1942 $x_repeat = true;
1943 $y_repeat = true;
1944 if (isset($properties['BACKGROUND-REPEAT'])) {
1945 if ($properties['BACKGROUND-REPEAT']=='no-repeat' || $properties['BACKGROUND-REPEAT']=='repeat-x') { $y_repeat = false; }
1946 if ($properties['BACKGROUND-REPEAT']=='no-repeat' || $properties['BACKGROUND-REPEAT']=='repeat-y') { $x_repeat = false; }
1947 }
1948 $x_pos = 0;
1949 $y_pos = 0;
1950 if (isset($properties['BACKGROUND-POSITION'])) {
1951 $ppos = preg_split('/\s+/',$properties['BACKGROUND-POSITION']);
1952 $x_pos = $ppos[0];
1953 $y_pos = $ppos[1];
1954 if (!stristr($x_pos ,'%') ) { $x_pos = $this->ConvertSize($x_pos ,$maxwidth,$this->FontSize); }
1955 if (!stristr($y_pos ,'%') ) { $y_pos = $this->ConvertSize($y_pos ,$maxwidth,$this->FontSize); }
1956 }
1957 if (isset($properties['BACKGROUND-IMAGE-RESIZE'])) { $resize = $properties['BACKGROUND-IMAGE-RESIZE']; }
1958 else { $resize = 0; }
1959 if (isset($properties['BACKGROUND-IMAGE-OPACITY'])) { $opacity = $properties['BACKGROUND-IMAGE-OPACITY']; }
1960 else { $opacity = 1; }
1961 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 );
1962 }
1963 }
1964 return false;
1965 }
1966 /*-- END BACKGROUNDS --*/
1967
1968 function PrintBodyBackgrounds() {
1969 $s = '';
1970 $clx = 0;
1971 $cly = 0;
1972 $clw = $this->w;
1973 $clh = $this->h;
1974 // If using bleed and trim margins in paged media
1975 if ($this->pageDim[$this->page]['outer_width_LR'] || $this->pageDim[$this->page]['outer_width_TB']) {
1976 $clx = $this->pageDim[$this->page]['outer_width_LR'] - $this->pageDim[$this->page]['bleedMargin'];
1977 $cly = $this->pageDim[$this->page]['outer_width_TB'] - $this->pageDim[$this->page]['bleedMargin'];
1978 $clw = $this->w - 2*$clx;
1979 $clh = $this->h - 2*$cly;
1980 }
1981
1982 if ($this->bodyBackgroundColor) {
1983 $s .= 'q ' .$this->SetFColor($this->bodyBackgroundColor, true)."\n";
1984 if ($this->bodyBackgroundColor{0}==5) { // RGBa
1985 $s .= $this->SetAlpha(ord($this->bodyBackgroundColor{4})/100, 'Normal', true, 'F')."\n";
1986 }
1987 else if ($this->bodyBackgroundColor{0}==6) { // CMYKa
1988 $s .= $this->SetAlpha(ord($this->bodyBackgroundColor{5})/100, 'Normal', true, 'F')."\n";
1989 }
1990 $s .= sprintf('%.3F %.3F %.3F %.3F re f Q', ($clx*_MPDFK), ($cly*_MPDFK),$clw*_MPDFK,$clh*_MPDFK)."\n";
1991 }
1992
1993 /*-- BACKGROUNDS --*/
1994 if ($this->bodyBackgroundGradient) {
1995 $g = $this->grad->parseBackgroundGradient($this->bodyBackgroundGradient);
1996 if ($g) {
1997 $s .= $this->grad->Gradient($clx, $cly, $clw, $clh, (isset($g['gradtype']) ? $g['gradtype'] : null), $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
1998 }
1999 }
2000 if ($this->bodyBackgroundImage) {
2001 if ( $this->bodyBackgroundImage['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->bodyBackgroundImage['gradient'])) {
2002 $g = $this->grad->parseMozGradient( $this->bodyBackgroundImage['gradient']);
2003 if ($g) {
2004 $s .= $this->grad->Gradient($clx, $cly, $clw, $clh, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
2005 }
2006 }
2007 else if ($this->bodyBackgroundImage['image_id']) { // Background pattern
2008 $n = count($this->patterns)+1;
2009 // If using resize, uses TrimBox (not including the bleed)
2010 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']);
2011
2012 $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']);
2013 if (($this->bodyBackgroundImage['opacity']>0 || $this->bodyBackgroundImage['opacity']==='0') && $this->bodyBackgroundImage['opacity']<1) { $opac = $this->SetAlpha($this->bodyBackgroundImage['opacity'],'Normal',true); }
2014 else { $opac = ''; }
2015 $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";
2016 }
2017 }
2018 /*-- END BACKGROUNDS --*/
2019 return $s;
2020 }
2021
2022
2023 function PrintPageBackgrounds($adjustmenty=0) {
2024 $s = '';
2025
2026 ksort($this->pageBackgrounds);
2027 foreach($this->pageBackgrounds AS $bl=>$pbs) {
2028 foreach ($pbs AS $pb) {
2029 if ((!isset($pb['image_id']) && !isset($pb['gradient'])) || isset($pb['shadowonly'])) { // Background colour or boxshadow
2030 // mPDF 5.6.01 - LAYERS
2031 if($pb['z-index']>0) {
2032 $this->current_layer = $pb['z-index'];
2033 $s .= "\n".'/OCBZ-index /ZI'.$pb['z-index'].' BDC'."\n";
2034 }
2035
2036 if($pb['visibility']!='visible') {
2037 if($pb['visibility']=='printonly')
2038 $s .= '/OC /OC1 BDC'."\n";
2039 else if($pb['visibility']=='screenonly')
2040 $s .= '/OC /OC2 BDC'."\n";
2041 else if($pb['visibility']=='hidden')
2042 $s .= '/OC /OC3 BDC'."\n";
2043 }
2044 // Box shadow
2045 if (isset($pb['shadow']) && $pb['shadow']) { $s .= $pb['shadow']."\n"; }
2046 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2047 $s .= 'q '.$this->SetFColor($pb['col'], true)."\n";
2048 if ($pb['col']{0}==5) { // RGBa
2049 $s .= $this->SetAlpha(ord($pb['col']{4})/100, 'Normal', true, 'F')."\n";
2050 }
2051 else if ($pb['col']{0}==6) { // CMYKa
2052 $s .= $this->SetAlpha(ord($pb['col']{5})/100, 'Normal', true, 'F')."\n";
2053 }
2054 $s .= sprintf('%.3F %.3F %.3F %.3F re f Q',$pb['x']*_MPDFK,($this->h-$pb['y'])*_MPDFK,$pb['w']*_MPDFK,-$pb['h']*_MPDFK)."\n";
2055 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2056 if($pb['visibility']!='visible')
2057 $s .= 'EMC'."\n";
2058
2059 // mPDF 5.6.01 - LAYERS
2060 if($pb['z-index']>0) {
2061 $s .= "\n".'EMCBZ-index'."\n";
2062 $this->current_layer = 0;
2063 }
2064 }
2065 }
2066 /*-- BACKGROUNDS --*/
2067 foreach ($pbs AS $pb) {
2068 // mPDF 5.6.01 - LAYERS
2069 if ((isset($pb['gradient']) && $pb['gradient']) || (isset($pb['image_id']) && $pb['image_id'])) {
2070 if($pb['z-index']>0) {
2071 $this->current_layer = $pb['z-index'];
2072 $s .= "\n".'/OCGZ-index /ZI'.$pb['z-index'].' BDC'."\n";
2073 }
2074 if($pb['visibility']!='visible') {
2075 if($pb['visibility']=='printonly')
2076 $s .= '/OC /OC1 BDC'."\n";
2077 else if($pb['visibility']=='screenonly')
2078 $s .= '/OC /OC2 BDC'."\n";
2079 else if($pb['visibility']=='hidden')
2080 $s .= '/OC /OC3 BDC'."\n";
2081 }
2082 }
2083 if (isset($pb['gradient']) && $pb['gradient']) {
2084 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2085 $s .= $this->grad->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
2086 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2087 }
2088 else if (isset($pb['image_id']) && $pb['image_id']) { // Background Image
2089 $pb['y'] -= $adjustmenty;
2090 $pb['h'] += $adjustmenty;
2091 $n = count($this->patterns)+1;
2092 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
2093 $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
2094 $x = $pb['x']*_MPDFK;
2095 $y = ($this->h - $pb['y'])*_MPDFK;
2096 $w = $pb['w']*_MPDFK;
2097 $h = -$pb['h']*_MPDFK;
2098 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2099 if ($this->writingHTMLfooter || $this->writingHTMLheader) { // Write each (tiles) image rather than use as a pattern
2100 $iw = $pb['orig_w']/_MPDFK;
2101 $ih = $pb['orig_h']/_MPDFK;
2102
2103 $w = $pb['w'];
2104 $h = $pb['h'];
2105 $x0 = $pb['x'];
2106 $y0 = $pb['y'];
2107
2108 // mPDF 5.6.11
2109 if (isset($pb['bpa']) && $pb['bpa']) {
2110 $w = $pb['bpa']['w'];
2111 $h = $pb['bpa']['h'];
2112 $x0 = $pb['bpa']['x'];
2113 $y0 = $pb['bpa']['y'];
2114 }
2115
2116 // mPDF 5.6.11
2117 if (isset($pb['size']['w']) && $pb['size']['w']) {
2118 $size = $pb['size'];
2119
2120 if ($size['w']=='contain') {
2121 // 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.
2122 // Same as resize==3
2123 $ih = $ih * $pb['bpa']['w']/$iw;
2124 $iw = $pb['bpa']['w'];
2125 if ($ih > $pb['bpa']['h']) {
2126 $iw = $iw * $pb['bpa']['h']/$ih;
2127 $ih = $pb['bpa']['h'];
2128 }
2129 }
2130 else if ($size['w']=='cover') {
2131 // 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.
2132 $ih = $ih * $pb['bpa']['w']/$iw;
2133 $iw = $pb['bpa']['w'];
2134 if ($ih < $pb['bpa']['h']) {
2135 $iw = $iw * $ih/$pb['bpa']['h'];
2136 $ih = $pb['bpa']['h'];
2137 }
2138 }
2139 else {
2140 if (stristr($size['w'] ,'%')) {
2141 $size['w'] += 0;
2142 $size['w'] /= 100;
2143 $size['w'] = ($pb['bpa']['w'] * $size['w']);
2144 }
2145 if (stristr($size['h'] ,'%')) {
2146 $size['h'] += 0;
2147 $size['h'] /= 100;
2148 $size['h'] = ($pb['bpa']['h'] * $size['h']);
2149 }
2150 if ($size['w']=='auto' && $size['h']=='auto') {
2151 $iw = $iw;
2152 $ih = $ih;
2153 }
2154 else if ($size['w']=='auto' && $size['h']!='auto') {
2155 $iw = $iw * $size['h']/$ih;
2156 $ih = $size['h'];
2157 }
2158 else if ($size['w']!='auto' && $size['h']=='auto') {
2159 $ih = $ih * $size['w']/$iw;
2160 $iw = $size['w'];
2161 }
2162 else {
2163 $iw = $size['w'];
2164 $ih = $size['h'];
2165 }
2166 }
2167 }
2168
2169 // Number to repeat
2170 if ($pb['x_repeat']) { $nx = ceil($pb['w']/$iw)+1; } // mPDF 5.6.11
2171 else { $nx = 1; }
2172 if ($pb['y_repeat']) { $ny = ceil($pb['h']/$ih)+1; } // mPDF 5.6.11
2173 else { $ny = 1; }
2174
2175 $x_pos = $pb['x_pos'];
2176 if (stristr($x_pos ,'%') ) {
2177 $x_pos += 0;
2178 $x_pos /= 100;
2179 $x_pos = ($pb['bpa']['w'] * $x_pos) - ($iw * $x_pos); // mPDF 5.6.11
2180 }
2181 $y_pos = $pb['y_pos'];
2182 if (stristr($y_pos ,'%') ) {
2183 $y_pos += 0;
2184 $y_pos /= 100;
2185 $y_pos = ($pb['bpa']['h'] * $y_pos) - ($ih * $y_pos); // mPDF 5.6.11
2186 }
2187 if ($nx>1) {
2188 while($x_pos>($pb['x']-$pb['bpa']['x'])) { $x_pos -= $iw; } // mPDF 5.6.11
2189 }
2190 if ($ny>1) {
2191 while($y_pos>($pb['y']-$pb['bpa']['y'])) { $y_pos -= $ih; } // mPDF 5.6.11
2192 }
2193 for($xi=0;$xi<$nx;$xi++) {
2194 for($yi=0;$yi<$ny;$yi++) {
2195 $x = $x0 + $x_pos + ($iw*$xi);
2196 $y = $y0 + $y_pos + ($ih*$yi);
2197 if ($pb['opacity']>0 && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
2198 else { $opac = ''; }
2199 $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";
2200 }
2201 }
2202 }
2203 else {
2204 if (($pb['opacity']>0 || $pb['opacity']==='0') && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
2205 else { $opac = ''; }
2206 $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $x, $y, $w, $h) ."\n";
2207 }
2208 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2209 }
2210 if ((isset($pb['gradient']) && $pb['gradient']) || (isset($pb['image_id']) && $pb['image_id'])) {
2211 if($pb['visibility']!='visible')
2212 $s .= 'EMC'."\n";
2213
2214 // mPDF 5.6.01 - LAYERS
2215 if($pb['z-index']>0) {
2216 $s .= "\n".'EMCGZ-index'."\n";
2217 $this->current_layer = 0;
2218 }
2219 }
2220
2221 }
2222 /*-- END BACKGROUNDS --*/
2223 }
2224 return $s;
2225 }
2226
2227 function PrintTableBackgrounds($adjustmenty=0) {
2228 $s = '';
2229 /*-- BACKGROUNDS --*/
2230 ksort($this->tableBackgrounds);
2231 foreach($this->tableBackgrounds AS $bl=>$pbs) {
2232 foreach ($pbs AS $pb) {
2233 if ((!isset($pb['gradient']) || !$pb['gradient']) && (!isset($pb['image_id']) || !$pb['image_id'])) {
2234 $s .= 'q '.$this->SetFColor($pb['col'], true)."\n";
2235 if ($pb['col']{0}==5) { // RGBa
2236 $s .= $this->SetAlpha(ord($pb['col']{4})/100, 'Normal', true, 'F')."\n";
2237 }
2238 else if ($pb['col']{0}==6) { // CMYKa
2239 $s .= $this->SetAlpha(ord($pb['col']{5})/100, 'Normal', true, 'F')."\n";
2240 }
2241 $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";
2242 }
2243 if (isset($pb['gradient']) && $pb['gradient']) {
2244 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2245 $s .= $this->grad->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
2246 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2247 }
2248 if (isset($pb['image_id']) && $pb['image_id']) { // Background pattern
2249 $pb['y'] -= $adjustmenty;
2250 $pb['h'] += $adjustmenty;
2251 $n = count($this->patterns)+1;
2252 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']);
2253 $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']);
2254 $x = $pb['x']*_MPDFK;
2255 $y = ($this->h - $pb['y'])*_MPDFK;
2256 $w = $pb['w']*_MPDFK;
2257 $h = -$pb['h']*_MPDFK;
2258 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2259
2260 // mPDF 5.7.3
2261 if (($this->writingHTMLfooter || $this->writingHTMLheader) && (!isset($pb['clippath']) || $pb['clippath']=='') ) {
2262 // Set clipping path
2263 $pb['clippath'] = sprintf(' q 0 w %.3F %.3F m %.3F %.3F l %.3F %.3F l %.3F %.3F l %.3F %.3F l W n ', $x, $y, $x, $y+$h, $x+$w, $y+$h, $x+$w, $y, $x, $y);
2264 }
2265
2266 if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
2267
2268 // mPDF 5.7.3
2269 if ($this->writingHTMLfooter || $this->writingHTMLheader) { // Write each (tiles) image rather than use as a pattern
2270 $iw = $pb['orig_w']/_MPDFK;
2271 $ih = $pb['orig_h']/_MPDFK;
2272
2273 $w = $pb['w'];
2274 $h = $pb['h'];
2275 $x0 = $pb['x'];
2276 $y0 = $pb['y'];
2277
2278 if (isset($pb['bpa']) && $pb['bpa']) {
2279 $w = $pb['bpa']['w'];
2280 $h = $pb['bpa']['h'];
2281 $x0 = $pb['bpa']['x'];
2282 $y0 = $pb['bpa']['y'];
2283 }
2284
2285 if (isset($pb['size']['w']) && $pb['size']['w']) {
2286 $size = $pb['size'];
2287
2288 if ($size['w']=='contain') {
2289 // 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.
2290 // Same as resize==3
2291 $ih = $ih * $pb['bpa']['w']/$iw;
2292 $iw = $pb['bpa']['w'];
2293 if ($ih > $pb['bpa']['h']) {
2294 $iw = $iw * $pb['bpa']['h']/$ih;
2295 $ih = $pb['bpa']['h'];
2296 }
2297 }
2298 else if ($size['w']=='cover') {
2299 // 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.
2300 $ih = $ih * $pb['bpa']['w']/$iw;
2301 $iw = $pb['bpa']['w'];
2302 if ($ih < $pb['bpa']['h']) {
2303 $iw = $iw * $ih/$pb['bpa']['h'];
2304 $ih = $pb['bpa']['h'];
2305 }
2306 }
2307 else {
2308 if (stristr($size['w'] ,'%')) {
2309 $size['w'] += 0;
2310 $size['w'] /= 100;
2311 $size['w'] = ($pb['bpa']['w'] * $size['w']);
2312 }
2313 if (stristr($size['h'] ,'%')) {
2314 $size['h'] += 0;
2315 $size['h'] /= 100;
2316 $size['h'] = ($pb['bpa']['h'] * $size['h']);
2317 }
2318 if ($size['w']=='auto' && $size['h']=='auto') {
2319 $iw = $iw;
2320 $ih = $ih;
2321 }
2322 else if ($size['w']=='auto' && $size['h']!='auto') {
2323 $iw = $iw * $size['h']/$ih;
2324 $ih = $size['h'];
2325 }
2326 else if ($size['w']!='auto' && $size['h']=='auto') {
2327 $ih = $ih * $size['w']/$iw;
2328 $iw = $size['w'];
2329 }
2330 else {
2331 $iw = $size['w'];
2332 $ih = $size['h'];
2333 }
2334 }
2335 }
2336
2337 // Number to repeat
2338 if ($pb['x_repeat']) { $nx = ceil($pb['w']/$iw)+1; }
2339 else { $nx = 1; }
2340 if ($pb['y_repeat']) { $ny = ceil($pb['h']/$ih)+1; }
2341 else { $ny = 1; }
2342
2343 $x_pos = $pb['x_pos'];
2344 if (stristr($x_pos ,'%') ) {
2345 $x_pos += 0;
2346 $x_pos /= 100;
2347 $x_pos = ($pb['bpa']['w'] * $x_pos) - ($iw * $x_pos);
2348 }
2349 $y_pos = $pb['y_pos'];
2350 if (stristr($y_pos ,'%') ) {
2351 $y_pos += 0;
2352 $y_pos /= 100;
2353 $y_pos = ($pb['bpa']['h'] * $y_pos) - ($ih * $y_pos);
2354 }
2355 if ($nx>1) {
2356 while($x_pos>($pb['x']-$pb['bpa']['x'])) { $x_pos -= $iw; }
2357 }
2358 if ($ny>1) {
2359 while($y_pos>($pb['y']-$pb['bpa']['y'])) { $y_pos -= $ih; }
2360 }
2361 for($xi=0;$xi<$nx;$xi++) {
2362 for($yi=0;$yi<$ny;$yi++) {
2363 $x = $x0 + $x_pos + ($iw*$xi);
2364 $y = $y0 + $y_pos + ($ih*$yi);
2365 if ($pb['opacity']>0 && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
2366 else { $opac = ''; }
2367 $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";
2368 }
2369 }
2370 }
2371 else {
2372 if (($pb['opacity']>0 || $pb['opacity']==='0') && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
2373 else { $opac = ''; }
2374 $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $x, $y, $w, $h) ."\n";
2375 }
2376
2377 if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
2378 }
2379 }
2380 }
2381 /*-- END BACKGROUNDS --*/
2382 return $s;
2383 }
2384
2385 // mPDF 5.6.01 - LAYERS
2386 function BeginLayer($id) {
2387 if($this->current_layer>0) $this->EndLayer();
2388 if ($id < 1) { return false; }
2389 if (!isset($this->layers[$id])) {
2390 $this->layers[$id] = array('name'=>'Layer '.($id) );
2391 if (($this->PDFA || $this->PDFX)) { $this->PDFAXwarnings[] = "Cannot use layers when using PDFA or PDFX"; return ''; }
2392 else if (!$this->PDFA && !$this->PDFX) { $this->pdf_version='1.5'; }
2393 }
2394 $this->current_layer = $id;
2395 $this->_out('/OCZ-index /ZI'.$id.' BDC');
2396
2397 $this->pageoutput[$this->page] = array();
2398 }
2399
2400 function EndLayer() {
2401 if($this->current_layer>0) {
2402 $this->_out('EMCZ-index');
2403 $this->current_layer = 0;
2404 }
2405 }
2406
2407
2408
2409 // Depracated - can use AddPage for all
2410 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='')
2411 {
2412 $this->AddPage($orientation,$condition,$resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue,$pagesel,$newformat);
2413 }
2414
2415
2416 function AddPageByArray($a) {
2417 if (!is_array($a)) { $a = array(); }
2418 $orientation = (isset($a['orientation']) ? $a['orientation'] : '');
2419 $condition = (isset($a['condition']) ? $a['condition'] : (isset($a['type']) ? $a['type'] : ''));
2420 $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : '');
2421 $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : '');
2422 $suppress = (isset($a['suppress']) ? $a['suppress'] : '');
2423 $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
2424 $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
2425 $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
2426 $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
2427 $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
2428 $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
2429 $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
2430 $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
2431 $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
2432 $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
2433 $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
2434 $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
2435 $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
2436 $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
2437 $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : ''));
2438 $newformat = (isset($a['newformat']) ? $a['newformat'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
2439
2440 $this->AddPage($orientation,$condition,$resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue,$pagesel,$newformat);
2441
2442 }
2443
2444
2445 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='')
2446 {
2447 /*-- CSS-FLOAT --*/
2448 // Float DIV
2449 // Cannot do with columns on, or if any change in page orientation/margins etc.
2450 // If next page already exists - i.e background /headers and footers already written
2451 if ($this->state > 0 && $this->page < count($this->pages)) {
2452 $bak_cml = $this->cMarginL;
2453 $bak_cmr = $this->cMarginR;
2454 $bak_dw = $this->divwidth;
2455 // Paint Div Border if necessary
2456 if ($this->blklvl > 0) {
2457 $save_tr = $this->table_rotate; // *TABLES*
2458 $this->table_rotate = 0; // *TABLES*
2459 if ($this->y == $this->blk[$this->blklvl]['y0']) { $this->blk[$this->blklvl]['startpage']++; }
2460 if (($this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table'] ) { $toplvl = $this->blklvl; }
2461 else { $toplvl = $this->blklvl-1; }
2462 $sy = $this->y;
2463 for ($bl=1;$bl<=$toplvl;$bl++) {
2464 $this->PaintDivBB('pagebottom',0,$bl);
2465 }
2466 $this->y = $sy;
2467 $this->table_rotate = $save_tr; // *TABLES*
2468 }
2469 $s = $this->PrintPageBackgrounds();
2470
2471 // Writes after the marker so not overwritten later by page background etc.
2472 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
2473 $this->pageBackgrounds = array();
2474 $family=$this->FontFamily;
2475 $style=$this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
2476 $size=$this->FontSizePt;
2477 $lw=$this->LineWidth;
2478 $dc=$this->DrawColor;
2479 $fc=$this->FillColor;
2480 $tc=$this->TextColor;
2481 $cf=$this->ColorFlag;
2482
2483 $this->printfloatbuffer();
2484
2485 //Move to next page
2486 $this->page++;
2487 $this->ResetMargins();
2488 $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
2489 $this->x=$this->lMargin;
2490 $this->y=$this->tMargin;
2491 $this->FontFamily='';
2492 $this->_out('2 J');
2493 $this->LineWidth=$lw;
2494 $this->_out(sprintf('%.3F w',$lw*_MPDFK));
2495 if($family) $this->SetFont($family,$style,$size,true,true);
2496 $this->DrawColor=$dc;
2497 if($dc!=$this->defDrawColor) $this->_out($dc);
2498 $this->FillColor=$fc;
2499 if($fc!=$this->defFillColor) $this->_out($fc);
2500 $this->TextColor=$tc;
2501 $this->ColorFlag=$cf;
2502 for($bl=1;$bl<=$this->blklvl;$bl++) {
2503 $this->blk[$bl]['y0'] = $this->y;
2504 // Don't correct more than once for background DIV containing a Float
2505 if (!isset($this->blk[$bl]['marginCorrected'][$this->page])) { $this->blk[$bl]['x0'] += $this->MarginCorrection; }
2506 $this->blk[$bl]['marginCorrected'][$this->page] = true;
2507 }
2508 $this->cMarginL = $bak_cml;
2509 $this->cMarginR = $bak_cmr;
2510 $this->divwidth = $bak_dw;
2511 return '';
2512 }
2513 /*-- END CSS-FLOAT --*/
2514
2515 //Start a new page
2516 if($this->state==0) $this->Open();
2517
2518 $bak_cml = $this->cMarginL;
2519 $bak_cmr = $this->cMarginR;
2520 $bak_dw = $this->divwidth;
2521
2522
2523 $bak_lh = $this->lineheight;
2524
2525 $orientation = substr(strtoupper($orientation),0,1);
2526 $condition = strtoupper($condition);
2527
2528
2529 if ($condition == 'NEXT-EVEN') { // always adds at least one new page to create an Even page
2530 if (!$this->mirrorMargins) { $condition = ''; }
2531 else {
2532 if ($pagesel) { $pbch = $pagesel; $pagesel = ''; } // *CSS-PAGE*
2533 else { $pbch = false; } // *CSS-PAGE*
2534 $this->AddPage($this->CurOrientation,'O');
2535 if ($pbch ) { $pagesel = $pbch; } // *CSS-PAGE*
2536 $condition = '';
2537 }
2538 }
2539 if ($condition == 'NEXT-ODD') { // always adds at least one new page to create an Odd page
2540 if (!$this->mirrorMargins) { $condition = ''; }
2541 else {
2542 if ($pagesel) { $pbch = $pagesel; $pagesel = ''; } // *CSS-PAGE*
2543 else { $pbch = false; } // *CSS-PAGE*
2544 $this->AddPage($this->CurOrientation,'E');
2545 if ($pbch ) { $pagesel = $pbch; } // *CSS-PAGE*
2546 $condition = '';
2547 }
2548 }
2549
2550
2551 if ($condition == 'E') { // only adds new page if needed to create an Even page
2552 if (!$this->mirrorMargins || ($this->page)%2==0) { return false; }
2553 }
2554 if ($condition == 'O') { // only adds new page if needed to create an Odd page
2555 if (!$this->mirrorMargins || ($this->page)%2==1) { return false; }
2556 }
2557
2558 if ($resetpagenum || $pagenumstyle || $suppress) {
2559 $this->PageNumSubstitutions[] = array('from'=>($this->page+1), 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=>$suppress);
2560 }
2561
2562
2563 $save_tr = $this->table_rotate; // *TABLES*
2564 $this->table_rotate = 0; // *TABLES*
2565 $save_kwt = $this->kwt;
2566 $this->kwt = 0;
2567 // mPDF 5.6.01 - LAYERS
2568 $save_layer = $this->current_layer;
2569 $save_vis = $this->visibility;
2570
2571 if($this->visibility!='visible')
2572 $this->SetVisibility('visible');
2573 // mPDF 5.6.01 - LAYERS
2574 $this->EndLayer();
2575
2576 // Paint Div Border if necessary
2577 //PAINTS BACKGROUND COLOUR OR BORDERS for DIV - DISABLED FOR COLUMNS (cf. AcceptPageBreak) AT PRESENT in ->PaintDivBB
2578 if (!$this->ColActive && $this->blklvl > 0) {
2579 if (isset($this->blk[$this->blklvl]['y0']) && $this->y == $this->blk[$this->blklvl]['y0']) {
2580 if (isset($this->blk[$this->blklvl]['startpage'])) { $this->blk[$this->blklvl]['startpage']++; }
2581 else { $this->blk[$this->blklvl]['startpage'] = 1; }
2582 }
2583 if ((isset($this->blk[$this->blklvl]['y0']) && $this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table'] ) { $toplvl = $this->blklvl; }
2584 else { $toplvl = $this->blklvl-1; }
2585 $sy = $this->y;
2586 for ($bl=1;$bl<=$toplvl;$bl++) {
2587
2588 // mPDF 5.6.01 - LAYERS
2589 if ($this->blk[$bl]['z-index']>0) {
2590 $this->BeginLayer($this->blk[$bl]['z-index']);
2591 }
2592 if (isset($this->blk[$bl]['visibility']) && $this->blk[$bl]['visibility'] && $this->blk[$bl]['visibility']!='visible') {
2593 $this->SetVisibility($this->blk[$bl]['visibility']);
2594 }
2595
2596 $this->PaintDivBB('pagebottom',0,$bl);
2597 }
2598 $this->y = $sy;
2599 // RESET block y0 and x0 - see below
2600 }
2601
2602 if($this->visibility!='visible')
2603 $this->SetVisibility('visible');
2604 // mPDF 5.6.01 - LAYERS
2605 $this->EndLayer();
2606
2607 // BODY Backgrounds
2608 if ($this->page > 0) {
2609 $s = '';
2610 $s .= $this->PrintBodyBackgrounds();
2611
2612 $s .= $this->PrintPageBackgrounds();
2613 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', "\n".$s."\n".'\\1', $this->pages[$this->page]);
2614 $this->pageBackgrounds = array();
2615 }
2616
2617 $save_kt = $this->keep_block_together;
2618 $this->keep_block_together = 0;
2619
2620 $save_cols = false;
2621 /*-- COLUMNS --*/
2622 if ($this->ColActive) {
2623 $save_cols = true;
2624 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
2625 $this->SetColumns(0);
2626 }
2627 /*-- END COLUMNS --*/
2628
2629
2630 $family=$this->FontFamily;
2631 $style=$this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
2632 $size=$this->FontSizePt;
2633 $this->ColumnAdjust = true; // enables column height adjustment for the page
2634 $lw=$this->LineWidth;
2635 $dc=$this->DrawColor;
2636 $fc=$this->FillColor;
2637 $tc=$this->TextColor;
2638 $cf=$this->ColorFlag;
2639 if($this->page>0)
2640 {
2641 //Page footer
2642 $this->InFooter=true;
2643
2644 $this->Reset();
2645 $this->pageoutput[$this->page] = array();
2646
2647 $this->Footer();
2648 //Close page
2649 $this->_endpage();
2650 }
2651
2652
2653 //Start new page
2654 $this->_beginpage($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat);
2655 if ($this->docTemplate) {
2656 $pagecount = $this->SetSourceFile($this->docTemplate);
2657 if (($this->page - $this->docTemplateStart) > $pagecount) {
2658 if ($this->docTemplateContinue) {
2659 $tplIdx = $this->ImportPage($pagecount);
2660 $this->UseTemplate($tplIdx);
2661 }
2662 }
2663 else {
2664 $tplIdx = $this->ImportPage(($this->page - $this->docTemplateStart));
2665 $this->UseTemplate($tplIdx);
2666 }
2667 }
2668 if ($this->pageTemplate) {
2669 $this->UseTemplate($this->pageTemplate);
2670 }
2671
2672 // Tiling Patterns
2673 $this->_out('___PAGE___START'.$this->uniqstr);
2674 $this->_out('___BACKGROUND___PATTERNS'.$this->uniqstr);
2675 $this->_out('___HEADER___MARKER'.$this->uniqstr);
2676 $this->pageBackgrounds = array();
2677
2678 //Set line cap style to square
2679 $this->SetLineCap(2);
2680 //Set line width
2681 $this->LineWidth=$lw;
2682 $this->_out(sprintf('%.3F w',$lw*_MPDFK));
2683 //Set font
2684 if($family) $this->SetFont($family,$style,$size,true,true); // forces write
2685 //Set colors
2686 $this->DrawColor=$dc;
2687 if($dc!=$this->defDrawColor) $this->_out($dc);
2688 $this->FillColor=$fc;
2689 if($fc!=$this->defFillColor) $this->_out($fc);
2690 $this->TextColor=$tc;
2691 $this->ColorFlag=$cf;
2692
2693 //Page header
2694 $this->Header();
2695
2696 //Restore line width
2697 if($this->LineWidth!=$lw)
2698 {
2699 $this->LineWidth=$lw;
2700 $this->_out(sprintf('%.3F w',$lw*_MPDFK));
2701 }
2702 //Restore font
2703 if($family) $this->SetFont($family,$style,$size,true,true); // forces write
2704 //Restore colors
2705 if($this->DrawColor!=$dc)
2706 {
2707 $this->DrawColor=$dc;
2708 $this->_out($dc);
2709 }
2710 if($this->FillColor!=$fc)
2711 {
2712 $this->FillColor=$fc;
2713 $this->_out($fc);
2714 }
2715 $this->TextColor=$tc;
2716 $this->ColorFlag=$cf;
2717 $this->InFooter=false;
2718
2719 // mPDF 5.6.01 - LAYERS
2720 if ($save_layer>0)
2721 $this->BeginLayer($save_layer);
2722
2723 if($save_vis!='visible')
2724 $this->SetVisibility($save_vis);
2725
2726 /*-- COLUMNS --*/
2727 if ($save_cols) {
2728 // Restore columns
2729 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
2730 }
2731 if ($this->ColActive) { $this->SetCol(0); }
2732 /*-- END COLUMNS --*/
2733
2734
2735 //RESET BLOCK BORDER TOP
2736 if (!$this->ColActive) {
2737 for($bl=1;$bl<=$this->blklvl;$bl++) {
2738 $this->blk[$bl]['y0'] = $this->y;
2739 if (isset($this->blk[$bl]['x0'])) { $this->blk[$bl]['x0'] += $this->MarginCorrection; }
2740 else { $this->blk[$bl]['x0'] = $this->MarginCorrection; }
2741 // Added mPDF 3.0 Float DIV
2742 $this->blk[$bl]['marginCorrected'][$this->page] = true;
2743 }
2744 }
2745
2746
2747 $this->table_rotate = $save_tr; // *TABLES*
2748 $this->kwt = $save_kwt;
2749
2750 $this->keep_block_together = $save_kt ;
2751
2752 $this->cMarginL = $bak_cml;
2753 $this->cMarginR = $bak_cmr;
2754 $this->divwidth = $bak_dw;
2755
2756 $this->lineheight = $bak_lh;
2757 }
2758
2759
2760 function PageNo() {
2761 //Get current page number
2762 return $this->page;
2763 }
2764
2765 function AddSpotColorsFromFile($file) {
2766 $colors = @file($file) or die("Cannot load spot colors file - ".$file);
2767 foreach($colors AS $sc) {
2768 list($name, $c, $m, $y, $k) = preg_split("/\t/",$sc);
2769 $c = intval($c);
2770 $m = intval($m);
2771 $y = intval($y);
2772 $k = intval($k);
2773 $this->AddSpotColor($name, $c, $m, $y, $k);
2774 }
2775 }
2776
2777 function AddSpotColor($name, $c, $m, $y, $k) {
2778 $name = strtoupper(trim($name));
2779 if(!isset($this->spotColors[$name])) {
2780 $i=count($this->spotColors)+1;
2781 $this->spotColors[$name]=array('i'=>$i,'c'=>$c,'m'=>$m,'y'=>$y,'k'=>$k);
2782 $this->spotColorIDs[$i]=$name;
2783 }
2784 }
2785
2786 function SetColor($col, $type='') {
2787 $out = '';
2788 if ($col{0}==3 || $col{0}==5) { // RGB / RGBa
2789 $out = sprintf('%.3F %.3F %.3F rg',ord($col{1})/255,ord($col{2})/255,ord($col{3})/255);
2790 }
2791 else if ($col{0}==1) { // GRAYSCALE
2792 $out = sprintf('%.3F g',ord($col{1})/255);
2793 }
2794 else if ($col{0}==2) { // SPOT COLOR
2795 $out = sprintf('/CS%d cs %.3F scn',ord($col{1}),ord($col{2})/100);
2796 }
2797 else if ($col{0}==4 || $col{0}==6) { // CMYK / CMYKa
2798 $out = sprintf('%.3F %.3F %.3F %.3F k', ord($col{1})/100, ord($col{2})/100, ord($col{3})/100, ord($col{4})/100);
2799 }
2800 if ($type=='Draw') { $out = strtoupper($out); } // e.g. rg => RG
2801 else if ($type=='CodeOnly') { $out = preg_replace('/\s(rg|g|k)/','',$out); }
2802 return $out;
2803 }
2804
2805
2806 function SetDColor($col, $return=false) {
2807 $out = $this->SetColor($col, 'Draw');
2808 if ($return) { return $out; }
2809 if ($out=='') { return ''; }
2810 $this->DrawColor = $out;
2811 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); }
2812 $this->pageoutput[$this->page]['DrawColor'] = $this->DrawColor;
2813 }
2814
2815 function SetFColor($col, $return=false) {
2816 $out = $this->SetColor($col, 'Fill');
2817 if ($return) { return $out; }
2818 if ($out=='') { return ''; }
2819 $this->FillColor = $out;
2820 $this->ColorFlag = ($out != $this->TextColor);
2821 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); }
2822 $this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
2823 }
2824
2825 function SetTColor($col, $return=false) {
2826 $out = $this->SetColor($col, 'Text');
2827 if ($return) { return $out; }
2828 if ($out=='') { return ''; }
2829 $this->TextColor = $out;
2830 $this->ColorFlag = ($this->FillColor != $out);
2831 }
2832
2833
2834 function SetDrawColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2835 //Set color for all stroking operations
2836 $col = array();
2837 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
2838 else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
2839 else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
2840 $out = $this->SetDColor($col, $return);
2841 return $out;
2842 }
2843
2844 function SetFillColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2845 //Set color for all filling operations
2846 $col = array();
2847 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
2848 else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
2849 else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
2850 $out = $this->SetFColor($col, $return);
2851 return $out;
2852 }
2853
2854 function SetTextColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
2855 //Set color for text
2856 $col = array();
2857 if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
2858 else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
2859 else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
2860 $out = $this->SetTColor($col, $return);
2861 return $out;
2862 }
2863
2864 function _getCharWidth(&$cw, $u, $isdef=true) {
2865 if ($u==0) { $w = false; }
2866 else { $w = (ord($cw[$u*2]) << 8) + ord($cw[$u*2+1]); }
2867 if ($w == 65535) { return 0; }
2868 else if ($w) { return $w; }
2869 else if ($isdef) { return false; }
2870 else { return 0; }
2871 }
2872
2873 function _charDefined(&$cw, $u) {
2874 if ($u==0) { return false; }
2875 $w = (ord($cw[$u*2]) << 8) + ord($cw[$u*2+1]);
2876 if ($w) { return true; }
2877 else { return false; }
2878 }
2879
2880 function GetCharWidthCore($c) {
2881 //Get width of a single character in the current Core font
2882 $c = (string)$c;
2883 $w = 0;
2884 // Soft Hyphens chr(173)
2885 if ($c == chr(173) && $this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
2886 return 0;
2887 }
2888 else if ($this->S && isset($this->upperCase[ord($c)])) {
2889 $charw = $this->CurrentFont['cw'][chr($this->upperCase[ord($c)])];
2890 if ($charw!==false) {
2891 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2892 $w+=$charw;
2893 }
2894 }
2895 else if (isset($this->CurrentFont['cw'][$c])) {
2896 $w += $this->CurrentFont['cw'][$c];
2897 }
2898 else if (isset($this->CurrentFont['cw'][ord($c)])) {
2899 $w += $this->CurrentFont['cw'][ord($c)];
2900 }
2901 $w *= ($this->FontSize/ 1000);
2902 if ($this->minwSpacing || $this->fixedlSpacing) {
2903 if ($c==' ') $nb_spaces = 1;
2904 else $nb_spaces = 0;
2905 $w += $this->fixedlSpacing + ($nb_spaces * $this->minwSpacing);
2906 }
2907 return ($w);
2908 }
2909
2910 function GetCharWidthNonCore($c, $addSubset=true) {
2911 //Get width of a single character in the current Non-Core font
2912 $c = (string)$c;
2913 $w = 0;
2914 $unicode = $this->UTF8StringToArray($c, $addSubset);
2915 $char = $unicode[0];
2916 /*-- CJK-FONTS --*/
2917 if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
2918 if ($char == 173) { return 0; } // Soft Hyphens
2919 elseif (isset($this->CurrentFont['cw'][$char])) { $w+=$this->CurrentFont['cw'][$char]; }
2920 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2921 else { $w += 500; }
2922 }
2923 else {
2924 /*-- END CJK-FONTS --*/
2925 if ($char == 173) { return 0; } // Soft Hyphens
2926 else if ($this->S && isset($this->upperCase[$char])) {
2927 $charw = $this->_getCharWidth($this->CurrentFont['cw'],$this->upperCase[$char]);
2928 if ($charw!==false) {
2929 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2930 $w+=$charw;
2931 }
2932 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
2933 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2934 else { $w += 500; }
2935 }
2936 else {
2937 $charw = $this->_getCharWidth($this->CurrentFont['cw'],$char);
2938 if ($charw!==false) { $w+=$charw; }
2939 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
2940 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2941 else { $w += 500; }
2942 }
2943 } // *CJK-FONTS*
2944 $w *= ($this->FontSize/ 1000);
2945 if ($this->minwSpacing || $this->fixedlSpacing) {
2946 if ($c==' ') $nb_spaces = 1;
2947 else $nb_spaces = 0;
2948 $w += $this->fixedlSpacing + ($nb_spaces * $this->minwSpacing);
2949 }
2950 return ($w);
2951 }
2952
2953
2954 function GetCharWidth($c, $addSubset=true) {
2955 if (!$this->usingCoreFont) {
2956 return $this->GetCharWidthNonCore($c, $addSubset);
2957 }
2958 else {
2959 return $this->GetCharWidthCore($c);
2960 }
2961 }
2962
2963 function GetStringWidth($s, $addSubset=true) {
2964 //Get width of a string in the current font
2965 $s = (string)$s;
2966 $cw = &$this->CurrentFont['cw'];
2967 $w = 0;
2968 $kerning = 0;
2969 $lastchar = 0;
2970 $nb_carac = 0;
2971 $nb_spaces = 0;
2972 // mPDF ITERATION
2973 if ($this->iterationCounter) $s = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/', '\\1', $s);
2974
2975 if (!$this->usingCoreFont) {
2976 $s = str_replace("\xc2\xad",'',$s );
2977 $unicode = $this->UTF8StringToArray($s, $addSubset);
2978 if ($this->minwSpacing || $this->fixedlSpacing) {
2979 $nb_carac = count($unicode);
2980 $nb_spaces = mb_substr_count($s,' ', $this->mb_enc);
2981 }
2982 /*-- CJK-FONTS --*/
2983 if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
2984 foreach($unicode as $char) {
2985 if (isset($cw[$char])) { $w+=$cw[$char]; }
2986 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
2987 else { $w += 500; }
2988 }
2989 }
2990 else {
2991 /*-- END CJK-FONTS --*/
2992 foreach($unicode as $char) {
2993 if ($this->S && isset($this->upperCase[$char])) {
2994 $charw = $this->_getCharWidth($cw,$this->upperCase[$char]);
2995 if ($charw!==false) {
2996 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
2997 $w+=$charw;
2998 }
2999 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
3000 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
3001 else { $w += 500; }
3002 }
3003 else {
3004 $charw = $this->_getCharWidth($cw,$char);
3005 if ($charw!==false) { $w+=$charw; }
3006 elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
3007 elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
3008 else { $w += 500; }
3009 if ($this->kerning && $this->useKerning && $lastchar) {
3010 if (isset($this->CurrentFont['kerninfo'][$lastchar][$char])) {
3011 $kerning += $this->CurrentFont['kerninfo'][$lastchar][$char];
3012 }
3013 }
3014 $lastchar = $char;
3015 }
3016 }
3017 } // *CJK-FONTS*
3018
3019 }
3020 else {
3021 if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
3022 $s = str_replace(chr(173),'',$s );
3023 }
3024 $nb_carac = $l = strlen($s);
3025 if ($this->minwSpacing || $this->fixedlSpacing) {
3026 $nb_spaces = substr_count($s,' ');
3027 }
3028 for($i=0; $i<$l; $i++) {
3029 if ($this->S && isset($this->upperCase[ord($s[$i])])) {
3030 $charw = $cw[chr($this->upperCase[ord($s[$i])])];
3031 if ($charw!==false) {
3032 $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
3033 $w+=$charw;
3034 }
3035 }
3036 else if (isset($cw[$s[$i]])) {
3037 $w += $cw[$s[$i]];
3038 }
3039 else if (isset($cw[ord($s[$i])])) {
3040 $w += $cw[ord($s[$i])];
3041 }
3042 if ($this->kerning && $this->useKerning && $i>0) {
3043 if (isset($this->CurrentFont['kerninfo'][$s[($i-1)]][$s[$i]])) {
3044 $kerning += $this->CurrentFont['kerninfo'][$s[($i-1)]][$s[$i]];
3045 }
3046 }
3047 }
3048 }
3049 unset($cw);
3050 if ($this->kerning && $this->useKerning) { $w += $kerning; }
3051 $w *= ($this->FontSize/ 1000);
3052 $w += (($nb_carac + $nb_spaces) * $this->fixedlSpacing) + ($nb_spaces * $this->minwSpacing);
3053 return ($w);
3054 }
3055
3056 function SetLineWidth($width) {
3057 //Set line width
3058 $this->LineWidth=$width;
3059 $lwout = (sprintf('%.3F w',$width*_MPDFK));
3060 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)) {
3061 $this->_out($lwout);
3062 }
3063 $this->pageoutput[$this->page]['LineWidth'] = $lwout;
3064 }
3065
3066 function Line($x1,$y1,$x2,$y2) {
3067 //Draw a line
3068 $this->_out(sprintf('%.3F %.3F m %.3F %.3F l S',$x1*_MPDFK,($this->h-$y1)*_MPDFK,$x2*_MPDFK,($this->h-$y2)*_MPDFK));
3069 }
3070
3071 function Arrow($x1,$y1,$x2,$y2,$headsize=3,$fill='B',$angle=25) {
3072 //F == fill //S == stroke //B == stroke and fill
3073 // angle = splay of arrowhead - 1 - 89 degrees
3074 if($fill=='F') $fill='f';
3075 elseif($fill=='FD' or $fill=='DF' or $fill=='B') $fill='B';
3076 else $fill='S';
3077 $a = atan2(($y2-$y1),($x2-$x1));
3078 $b = $a + deg2rad($angle);
3079 $c = $a - deg2rad($angle);
3080 $x3 = $x2 - ($headsize* cos($b));
3081 $y3 = $this->h-($y2 - ($headsize* sin($b)));
3082 $x4 = $x2 - ($headsize* cos($c));
3083 $y4 = $this->h-($y2 - ($headsize* sin($c)));
3084
3085 $x5 = $x3-($x3-$x4)/2; // mid point of base of arrowhead - to join arrow line to
3086 $y5 = $y3-($y3-$y4)/2;
3087
3088 $s = '';
3089 $s.=sprintf('%.3F %.3F m %.3F %.3F l S',$x1*_MPDFK,($this->h-$y1)*_MPDFK,$x5*_MPDFK,$y5*_MPDFK);
3090 $this->_out($s);
3091
3092 $s = '';
3093 $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);
3094 $s.=$fill;
3095 $this->_out($s);
3096 }
3097
3098
3099 function Rect($x,$y,$w,$h,$style='') {
3100 //Draw a rectangle
3101 if($style=='F') $op='f';
3102 elseif($style=='FD' or $style=='DF') $op='B';
3103 else $op='S';
3104 $this->_out(sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$h*_MPDFK,$op));
3105 }
3106
3107 function AddFont($family,$style='') {
3108 if(empty($family)) { return; }
3109 $family = strtolower($family);
3110 $style=strtoupper($style);
3111 $style=str_replace('U','',$style);
3112 if($style=='IB') $style='BI';
3113 $fontkey = $family.$style;
3114 // check if the font has been already added
3115 if(isset($this->fonts[$fontkey])) {
3116 return;
3117 }
3118
3119 /*-- CJK-FONTS --*/
3120 if (in_array($family,$this->available_CJK_fonts)) {
3121 if (empty($this->Big5_widths)) { require(_MPDF_PATH . 'includes/CJKdata.php'); }
3122 $this->AddCJKFont($family); // don't need to add style
3123 return;
3124 }
3125 /*-- END CJK-FONTS --*/
3126
3127 if ($this->usingCoreFont) { die("mPDF Error - problem with Font management"); }
3128
3129 $stylekey = $style;
3130 if (!$style) { $stylekey = 'R'; }
3131
3132 if (!isset($this->fontdata[$family][$stylekey]) || !$this->fontdata[$family][$stylekey]) {
3133 die('mPDF Error - Font is not supported - '.$family.' '.$style);
3134 }
3135
3136 $name = '';
3137 $originalsize = 0;
3138 $sip = false;
3139 $smp = false;
3140 $unAGlyphs = false; // mPDF 5.4.05
3141 $haskerninfo = false;
3142 $BMPselected = false;
3143 @include(_MPDF_TTFONTDATAPATH.$fontkey.'.mtx.php');
3144
3145 $ttffile = '';
3146 if (defined('_MPDF_SYSTEM_TTFONTS')) {
3147 $ttffile = _MPDF_SYSTEM_TTFONTS.$this->fontdata[$family][$stylekey];
3148 if (!file_exists($ttffile)) { $ttffile = ''; }
3149 }
3150 if (!$ttffile) {
3151 $ttffile = _MPDF_TTFONTPATH.$this->fontdata[$family][$stylekey];
3152 if (!file_exists($ttffile)) { die("mPDF Error - cannot find TTF TrueType font file - ".$ttffile); }
3153 }
3154 $ttfstat = stat($ttffile);
3155
3156 if (isset($this->fontdata[$family]['TTCfontID'][$stylekey])) { $TTCfontID = $this->fontdata[$family]['TTCfontID'][$stylekey]; }
3157 else { $TTCfontID = 0; }
3158
3159
3160 $BMPonly = false;
3161 if (in_array($family,$this->BMPonly)) { $BMPonly = true; }
3162 $regenerate = false;
3163 if ($BMPonly && !$BMPselected) { $regenerate = true; }
3164 else if (!$BMPonly && $BMPselected) { $regenerate = true; }
3165 if ($this->useKerning && !$haskerninfo) { $regenerate = true; }
3166 // mPDF 5.4.05
3167 if (isset($this->fontdata[$family]['unAGlyphs']) && $this->fontdata[$family]['unAGlyphs'] && !$unAGlyphs) {
3168 $regenerate = true;
3169 $unAGlyphs = true;
3170 }
3171 else if ((!isset($this->fontdata[$family]['unAGlyphs']) || !$this->fontdata[$family]['unAGlyphs']) && $unAGlyphs) {
3172 $regenerate = true;
3173 $unAGlyphs = false;
3174 }
3175 if (!isset($name) || $originalsize != $ttfstat['size'] || $regenerate) {
3176 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
3177 $ttf = new TTFontFile();
3178 $ttf->getMetrics($ttffile, $TTCfontID, $this->debugfonts, $BMPonly, $this->useKerning, $unAGlyphs); // mPDF 5.4.05
3179 $cw = $ttf->charWidths;
3180 $kerninfo = $ttf->kerninfo;
3181 $haskerninfo = true;
3182 $name = preg_replace('/[ ()]/','',$ttf->fullName);
3183 $sip = $ttf->sipset;
3184 $smp = $ttf->smpset;
3185
3186 $desc= array('Ascent'=>round($ttf->ascent),
3187 'Descent'=>round($ttf->descent),
3188 'CapHeight'=>round($ttf->capHeight),
3189 'Flags'=>$ttf->flags,
3190 'FontBBox'=>'['.round($ttf->bbox[0])." ".round($ttf->bbox[1])." ".round($ttf->bbox[2])." ".round($ttf->bbox[3]).']',
3191 'ItalicAngle'=>$ttf->italicAngle,
3192 'StemV'=>round($ttf->stemV),
3193 'MissingWidth'=>round($ttf->defaultWidth));
3194 $panose = '';
3195 // mPDF 5.5.19
3196 if (count($ttf->panose)) {
3197 $panoseArray = array_merge(array($ttf->sFamilyClass, $ttf->sFamilySubClass), $ttf->panose);
3198 foreach($panoseArray as $value)
3199 $panose .= ' '.dechex($value);
3200 }
3201 $up = round($ttf->underlinePosition);
3202 $ut = round($ttf->underlineThickness);
3203 $originalsize = $ttfstat['size']+0;
3204 $type = 'TTF';
3205 //Generate metrics .php file
3206 $s='<?php'."\n";
3207 $s.='$name=\''.$name."';\n";
3208 $s.='$type=\''.$type."';\n";
3209 $s.='$desc='.var_export($desc,true).";\n";
3210 $s.='$up='.$up.";\n";
3211 $s.='$ut='.$ut.";\n";
3212 $s.='$ttffile=\''.$ttffile."';\n";
3213 $s.='$TTCfontID=\''.$TTCfontID."';\n";
3214 $s.='$originalsize='.$originalsize.";\n";
3215 if ($sip) $s.='$sip=true;'."\n";
3216 else $s.='$sip=false;'."\n";
3217 if ($smp) $s.='$smp=true;'."\n";
3218 else $s.='$smp=false;'."\n";
3219 if ($BMPonly) $s.='$BMPselected=true;'."\n";
3220 else $s.='$BMPselected=false;'."\n";
3221 $s.='$fontkey=\''.$fontkey."';\n";
3222 $s.='$panose=\''.$panose."';\n";
3223 if ($this->useKerning) {
3224 $s.='$kerninfo='.var_export($kerninfo,true).";\n";
3225 $s.='$haskerninfo=true;'."\n";
3226 }
3227 else $s.='$haskerninfo=false;'."\n";
3228 // mPDF 5.4.05
3229 if ($this->fontdata[$family]['unAGlyphs']) {
3230 $s.='$unAGlyphs=true;'."\n";
3231 }
3232 else $s.='$unAGlyphs=false;'."\n";
3233 $s.="?>";
3234 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
3235 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.mtx.php',"w");
3236 fwrite($fh,$s,strlen($s));
3237 fclose($fh);
3238 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.cw.dat',"wb");
3239 fwrite($fh,$cw,strlen($cw));
3240 fclose($fh);
3241 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cgm');
3242 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.z');
3243 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cw127.php');
3244 @unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cw');
3245 }
3246 else if ($this->debugfonts) { $this->Error('Cannot write to the font caching directory - '._MPDF_TTFONTDATAPATH); }
3247 unset($ttf);
3248 }
3249 else {
3250 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$fontkey.'.cw.dat');
3251 }
3252
3253 if (isset($this->fontdata[$family]['indic']) && $this->fontdata[$family]['indic']) { $indic = true; }
3254 else { $indic = false; }
3255 if (isset($this->fontdata[$family]['sip-ext']) && $this->fontdata[$family]['sip-ext']) { $sipext = $this->fontdata[$family]['sip-ext']; }
3256 else { $sipext = ''; }
3257
3258
3259 $i = count($this->fonts)+$this->extraFontSubsets+1;
3260 if ($sip || $smp) {
3261 $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
3262 }
3263 else {
3264 $ss = array();
3265 for ($s=32; $s<128; $s++) { $ss[$s] = $s; }
3266 $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
3267 }
3268 if ($this->useKerning && $haskerninfo) { $this->fonts[$fontkey]['kerninfo'] = $kerninfo; }
3269 $this->FontFiles[$fontkey]=array('length1'=>$originalsize, 'type'=>"TTF", 'ttffile'=>$ttffile, 'sip'=>$sip, 'smp'=>$smp);
3270 unset($cw);
3271 }
3272
3273
3274
3275 function SetFont($family,$style='',$size=0, $write=true, $forcewrite=false) {
3276 $family=strtolower($family);
3277 if (!$this->onlyCoreFonts) {
3278 if ($family == 'sans' || $family == 'sans-serif') { $family = $this->sans_fonts[0]; }
3279 if ($family == 'serif') { $family = $this->serif_fonts[0]; }
3280 if ($family == 'mono' || $family == 'monospace') { $family = $this->mono_fonts[0]; }
3281 }
3282 if (isset($this->fonttrans[$family]) && $this->fonttrans[$family]) { $family = $this->fonttrans[$family]; }
3283 if($family=='') {
3284 if ($this->FontFamily) { $family=$this->FontFamily; }
3285 else if ($this->default_font) { $family=$this->default_font; }
3286 else { $this->Error("No font or default font set!"); }
3287 }
3288 $this->ReqFontStyle = $style; // required or requested style - used later for artificial bold/italic
3289
3290 if (($family == 'csymbol') || ($family == 'czapfdingbats') || ($family == 'ctimes') || ($family == 'ccourier') || ($family == 'chelvetica')) {
3291 if ($this->PDFA || $this->PDFX) {
3292 if ($family == 'csymbol' || $family == 'czapfdingbats') {
3293 $this->Error("Symbol and Zapfdingbats cannot be embedded in mPDF (required for PDFA1-b or PDFX/1-a).");
3294 }
3295 if ($family == 'ctimes' || $family == 'ccourier' || $family == 'chelvetica') {
3296 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.)"; }
3297 if ($family == 'chelvetica') { $family = 'sans'; }
3298 if ($family == 'ctimes') { $family = 'serif'; }
3299 if ($family == 'ccourier') { $family = 'mono'; }
3300 }
3301 $this->usingCoreFont = false;
3302 }
3303 else { $this->usingCoreFont = true; }
3304 if($family=='csymbol' || $family=='czapfdingbats') { $style=''; }
3305 }
3306 else { $this->usingCoreFont = false; }
3307
3308 $this->U=false;
3309 $this->S=false;
3310 if ($style) {
3311 $style=strtoupper($style);
3312 if(strpos($style,'U')!==false) {
3313 $this->U=true;
3314 $style=str_replace('U','',$style);
3315 }
3316 if(strpos($style,'S')!==false) {
3317 $this->S=true;
3318 // Small Caps
3319 if (empty($this->upperCase)) { @include(_MPDF_PATH.'includes/upperCase.php'); }
3320 $style=str_replace('S','',$style);
3321 }
3322 if ($style=='IB') $style='BI';
3323 }
3324 if ($size==0) $size=$this->FontSizePt;
3325
3326 $fontkey=$family.$style;
3327
3328 $stylekey = $style;
3329 if (!$stylekey) { $stylekey = "R"; }
3330
3331 if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
3332 if(!isset($this->fonts[$fontkey]) || count($this->default_available_fonts) != count($this->available_unifonts) ) { // not already added
3333 /*-- CJK-FONTS --*/
3334 // CJK fonts
3335 if (in_array($fontkey,$this->available_CJK_fonts)) {
3336 if(!isset($this->fonts[$fontkey])) { // already added
3337 if (empty($this->Big5_widths)) { require(_MPDF_PATH . 'includes/CJKdata.php'); }
3338 $this->AddCJKFont($family); // don't need to add style
3339 }
3340 }
3341 // Test to see if requested font/style is available - or substitute
3342 else
3343 /*-- END CJK-FONTS --*/
3344 if (!in_array($fontkey,$this->available_unifonts)) {
3345 // If font[nostyle] exists - set it
3346 if (in_array($family,$this->available_unifonts)) {
3347 $style = '';
3348 }
3349
3350 // Else if only one font available - set it (assumes if only one font available it will not have a style)
3351 else if (count($this->available_unifonts) == 1) {
3352 $family = $this->available_unifonts[0];
3353 $style = '';
3354 }
3355
3356 else {
3357 $found = 0;
3358 // else substitute font of similar type
3359 if (in_array($family,$this->sans_fonts)) {
3360 $i = array_intersect($this->sans_fonts,$this->available_unifonts);
3361 if (count($i)) {
3362 $i = array_values($i);
3363 // with requested style if possible
3364 if (!in_array(($i[0].$style),$this->available_unifonts)) {
3365 $style = '';
3366 }
3367 $family = $i[0];
3368 $found = 1;
3369 }
3370 }
3371 else if (in_array($family,$this->serif_fonts)) {
3372 $i = array_intersect($this->serif_fonts,$this->available_unifonts);
3373 if (count($i)) {
3374 $i = array_values($i);
3375 // with requested style if possible
3376 if (!in_array(($i[0].$style),$this->available_unifonts)) {
3377 $style = '';
3378 }
3379 $family = $i[0];
3380 $found = 1;
3381 }
3382 }
3383 else if (in_array($family,$this->mono_fonts)) {
3384 $i = array_intersect($this->mono_fonts,$this->available_unifonts);
3385 if (count($i)) {
3386 $i = array_values($i);
3387 // with requested style if possible
3388 if (!in_array(($i[0].$style),$this->available_unifonts)) {
3389 $style = '';
3390 }
3391 $family = $i[0];
3392 $found = 1;
3393 }
3394 }
3395
3396 if (!$found) {
3397 // set first available font
3398 $fs = $this->available_unifonts[0];
3399 preg_match('/^([a-z_0-9\-]+)([BI]{0,2})$/',$fs,$fas); // Allow "-"
3400 // with requested style if possible
3401 $ws = $fas[1].$style;
3402 if (in_array($ws,$this->available_unifonts)) {
3403 $family = $fas[1]; // leave $style as is
3404 }
3405 else if (in_array($fas[1],$this->available_unifonts)) {
3406 // or without style
3407 $family = $fas[1];
3408 $style = '';
3409 }
3410 else {
3411 // or with the style specified
3412 $family = $fas[1];
3413 $style = $fas[2];
3414 }
3415 }
3416 }
3417 $fontkey = $family.$style;
3418 }
3419 }
3420 // try to add font (if not already added)
3421 $this->AddFont($family, $style);
3422
3423 //Test if font is already selected
3424 if($this->FontFamily == $family && $this->FontFamily == $this->currentfontfamily && $this->FontStyle == $style && $this->FontStyle == $this->currentfontstyle && $this->FontSizePt == $size && $this->FontSizePt == $this->currentfontsize && !$forcewrite) {
3425 return $family;
3426 }
3427
3428 $fontkey = $family.$style;
3429
3430 //Select it
3431 $this->FontFamily = $family;
3432 $this->FontStyle = $style;
3433 $this->FontSizePt = $size;
3434 $this->FontSize = $size / _MPDFK;
3435 $this->CurrentFont = &$this->fonts[$fontkey];
3436 if ($write) {
3437 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
3438 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); }
3439 $this->pageoutput[$this->page]['Font'] = $fontout;
3440 }
3441
3442
3443
3444 // Added - currentfont (lowercase) used in HTML2PDF
3445 $this->currentfontfamily=$family;
3446 $this->currentfontsize=$size;
3447 $this->currentfontstyle=$style.($this->U ? 'U' : '').($this->S ? 'S' : '');
3448 $this->setMBencoding('UTF-8');
3449 }
3450
3451 else { // if using core fonts
3452
3453
3454 if ($this->PDFA || $this->PDFX) {
3455 $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.');
3456 }
3457 $this->setMBencoding('windows-1252');
3458
3459 //Test if font is already selected
3460 if(($this->FontFamily == $family) AND ($this->FontStyle == $style) AND ($this->FontSizePt == $size) && !$forcewrite) {
3461 return $family;
3462 }
3463
3464 if (!isset($this->CoreFonts[$fontkey])) {
3465 if (in_array($family,$this->serif_fonts)) { $family = 'ctimes'; }
3466 else if (in_array($family,$this->mono_fonts)) { $family = 'ccourier'; }
3467 else { $family = 'chelvetica'; }
3468 $this->usingCoreFont = true;
3469 $fontkey = $family.$style;
3470 }
3471
3472 if(!isset($this->fonts[$fontkey])) {
3473 // STANDARD CORE FONTS
3474 if (isset($this->CoreFonts[$fontkey])) {
3475 //Load metric file
3476 $file=$family;
3477 if($family=='ctimes' || $family=='chelvetica' || $family=='ccourier') { $file.=strtolower($style); }
3478 $file.='.php';
3479 include(_MPDF_PATH.'font/'.$file);
3480 if(!isset($cw)) { $this->Error('Could not include font metric file'); }
3481 $i=count($this->fonts)+$this->extraFontSubsets+1;
3482 $this->fonts[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts[$fontkey],'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw);
3483 if ($this->useKerning) { $this->fonts[$fontkey]['kerninfo'] = $kerninfo; }
3484 }
3485 else {
3486 die('mPDF error - Font not defined');
3487 }
3488 }
3489 //Test if font is already selected
3490 if(($this->FontFamily == $family) AND ($this->FontStyle == $style) AND ($this->FontSizePt == $size) && !$forcewrite) {
3491 return $family;
3492 }
3493 //Select it
3494 $this->FontFamily=$family;
3495 $this->FontStyle=$style;
3496 $this->FontSizePt=$size;
3497 $this->FontSize=$size/_MPDFK;
3498 $this->CurrentFont=&$this->fonts[$fontkey];
3499 if ($write) {
3500 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
3501 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); }
3502 $this->pageoutput[$this->page]['Font'] = $fontout;
3503 }
3504 // Added - currentfont (lowercase) used in HTML2PDF
3505 $this->currentfontfamily=$family;
3506 $this->currentfontsize=$size;
3507 $this->currentfontstyle=$style.($this->U ? 'U' : '').($this->S ? 'S' : '');
3508
3509 }
3510
3511 return $family;
3512 }
3513
3514 function SetFontSize($size,$write=true) {
3515 //Set font size in points
3516 if($this->FontSizePt==$size) return;
3517 $this->FontSizePt=$size;
3518 $this->FontSize=$size/_MPDFK;
3519 $this->currentfontsize=$size;
3520 if ($write) {
3521 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
3522 // Edited mPDF 3.0
3523 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); }
3524 $this->pageoutput[$this->page]['Font'] = $fontout;
3525 }
3526 }
3527
3528 function AddLink() {
3529 //Create a new internal link
3530 $n=count($this->links)+1;
3531 $this->links[$n]=array(0,0);
3532 return $n;
3533 }
3534
3535 function SetLink($link,$y=0,$page=-1) {
3536 //Set destination of internal link
3537 if($y==-1) $y=$this->y;
3538 if($page==-1) $page=$this->page;
3539 $this->links[$link]=array($page,$y);
3540 }
3541
3542 function Link($x,$y,$w,$h,$link) {
3543 $l = array($x*_MPDFK,$this->hPt-$y*_MPDFK,$w*_MPDFK,$h*_MPDFK,$link);
3544 if ($this->keep_block_together) { // Save to array - don't write yet
3545 $this->ktLinks[$this->page][]= $l;
3546 return;
3547 }
3548 else if ($this->table_rotate) { // *TABLES*
3549 $this->tbrot_Links[$this->page][]= $l; // *TABLES*
3550 return; // *TABLES*
3551 } // *TABLES*
3552 else if ($this->kwt) {
3553 $this->kwt_Links[$this->page][]= $l;
3554 return;
3555 }
3556
3557 if ($this->writingHTMLheader || $this->writingHTMLfooter) {
3558 $this->HTMLheaderPageLinks[]= $l;
3559 return;
3560 }
3561 //Put a link on the page
3562 $this->PageLinks[$this->page][]= $l;
3563 // Save cross-reference to Column buffer
3564 $ref = count($this->PageLinks[$this->page])-1; // *COLUMNS*
3565 $this->columnLinks[$this->CurrCol][INTVAL($this->x)][INTVAL($this->y)] = $ref; // *COLUMNS*
3566
3567 }
3568
3569 function Text($x,$y,$txt) {
3570 // Output a string
3571 // Called (internally) by Watermark and _tableWrite [rotated cells]
3572 // Expects input to be mb_encoded if necessary and RTL reversed
3573
3574 // ARTIFICIAL BOLD AND ITALIC
3575 $s = 'q ';
3576 if ($this->falseBoldWeight && strpos($this->ReqFontStyle,"B") !== false && strpos($this->FontStyle,"B") === false) {
3577 $s .= '2 Tr 1 J 1 j ';
3578 $s .= sprintf('%.3F w ',($this->FontSize/130)*_MPDFK*$this->falseBoldWeight);
3579 $tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3580 if($this->FillColor!=$tc) { $s .= $tc.' '; } // stroke (outline) = same colour as text(fill)
3581 }
3582 if (strpos($this->ReqFontStyle,"I") !== false && strpos($this->FontStyle,"I") === false) {
3583 $aix = '1 0 0.261799 1 %.3F %.3F Tm';
3584 }
3585 else { $aix = '%.3F %.3F Td'; }
3586
3587 if($this->ColorFlag) $s.=$this->TextColor.' ';
3588
3589 $this->CurrentFont['used']= true;
3590 if ($this->CurrentFont['type']=='TTF' && ($this->CurrentFont['sip'] || $this->CurrentFont['smp'])) {
3591 $txt2 = str_replace(chr(194).chr(160),chr(32),$txt);
3592 $txt2 = $this->UTF8toSubset($txt2);
3593 $s.=sprintf('BT '.$aix.' %s Tj ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$txt2);
3594 }
3595 else if (!$this->usingCoreFont) {
3596 $txt2 = str_replace(chr(194).chr(160),chr(32),$txt);
3597 $this->UTF8StringToArray($txt2); // this is just to add chars to subset list
3598 if ($this->kerning && $this->useKerning) { $s .= $this->_kern($txt2, '', $aix, $x, $y); }
3599 else {
3600 //Convert string to UTF-16BE without BOM
3601 $txt2= $this->UTF8ToUTF16BE($txt2, false);
3602 $s.=sprintf('BT '.$aix.' (%s) Tj ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$this->_escape($txt2));
3603 }
3604 }
3605 else {
3606 $txt2 = str_replace(chr(160),chr(32),$txt);
3607 if ($this->kerning && $this->useKerning) { $s .= $this->_kern($txt2, '', $aix, $x, $y); }
3608 else {
3609 $s.=sprintf('BT '.$aix.' (%s) Tj ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$this->_escape($txt2));
3610 }
3611 }
3612 if($this->U && $txt!='') {
3613 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3614 if($this->FillColor!=$c) { $s.= ' '.$c.' '; }
3615 if (isset($this->CurrentFont['up'])) { $up=$this->CurrentFont['up']; }
3616 else { $up = -100; }
3617 $adjusty = (-$up/1000* $this->FontSize);
3618 if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
3619 else { $ut = 60/1000* $this->FontSize; }
3620 $olw = $this->LineWidth;
3621 $s.=' '.(sprintf(' %.3F w',$ut*_MPDFK));
3622 $s.=' '.$this->_dounderline($x,$y + $adjusty,$txt);
3623 $s.=' '.(sprintf(' %.3F w',$olw*_MPDFK));
3624 if($this->FillColor!=$c) { $s.= ' '.$this->FillColor.' '; }
3625 }
3626 // STRIKETHROUGH
3627 if($this->strike && $txt!='') {
3628 $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
3629 if($this->FillColor!=$c) { $s.= ' '.$c.' '; }
3630 //Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
3631 if (isset($this->CurrentFont['desc']['CapHeight'])) { $ch=$this->CurrentFont['desc']['CapHeight']; }
3632 else { $ch = 700; }
3633 $adjusty = (-$ch/1000* $this->FontSize) * 0.35;
3634 if (isset($this->CurrentFont['ut'])) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
3635 else { $ut = 60/1000* $this->FontSize; }
3636 $olw = $this->LineWidth;
3637 $s.=' '.(sprintf(' %.3F w',$ut*_MPDFK));
3638 $s.=' '.$this->_dounderline($x,$y+$adjusty,$txt);
3639 $s.=' '.(sprintf(' %.3F w',$olw*_MPDFK));
3640 if($this->FillColor!=$c) { $s.= ' '.$this->FillColor.' '; }
3641 }
3642 $s .= 'Q';
3643 $this->_out($s);
3644 }
3645
3646 /*-- DIRECTW --*/
3647 function WriteText($x,$y,$txt) {
3648 // Output a string using Text() but does encoding and text reversing of RTL
3649 $txt = $this->purify_utf8_text($txt);
3650 if ($this->text_input_as_HTML) {
3651 $txt = $this->all_entities_to_utf8($txt);
3652 }
3653 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
3654 // DIRECTIONALITY
3655 if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *RTL*
3656 $this->magic_reverse_dir($txt, true, $this->directionality); // *RTL*
3657 // Font-specific ligature substitution for Indic fonts
3658 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($txt); // *INDIC*
3659 $this->Text($x,$y,$txt);
3660 }
3661
3662 function WriteCell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='', $currentx=0) {
3663 //Output a cell using Cell() but does encoding and text reversing of RTL
3664 $txt = $this->purify_utf8_text($txt);
3665 if ($this->text_input_as_HTML) {
3666 $txt = $this->all_entities_to_utf8($txt);
3667 }
3668 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
3669 // DIRECTIONALITY
3670 if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *RTL*
3671 $this->magic_reverse_dir($txt, true, $this->directionality); // *RTL*
3672 // Font-specific ligature substitution for Indic fonts
3673 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($txt); // *INDIC*
3674 $this->Cell($w,$h,$txt,$border,$ln,$align,$fill,$link, $currentx);
3675 }
3676 /*-- END DIRECTW --*/
3677
3678
3679 function ResetSpacing() {
3680 if ($this->ws != 0) { $this->_out('BT 0 Tw ET'); }
3681 $this->ws=0;
3682 if ($this->charspacing != 0) { $this->_out('BT 0 Tc ET'); }
3683 $this->charspacing=0;
3684 }
3685
3686
3687 function SetSpacing($cs,$ws) {
3688 if (intval($cs*1000)==0) { $cs = 0; }
3689 if ($cs) { $this->_out(sprintf('BT %.3F Tc ET',$cs)); }
3690 else if ($this->charspacing != 0) { $this->_out('BT 0 Tc ET'); }
3691 $this->charspacing=$cs;
3692 if (intval($ws*1000)==0) { $ws = 0; }
3693 if ($ws) { $this->_out(sprintf('BT %.3F Tw ET',$ws)); }
3694 else if ($this->ws != 0) { $this->_out('BT 0 Tw ET'); }
3695 $this->ws=$ws;
3696 }
3697
3698 // WORD SPACING
3699 function GetJspacing($nc,$ns,$w,$inclCursive) {
3700 $ws = 0;
3701 $charspacing = 0;
3702 $ww = $this->jSWord;
3703 $ncx = $nc-1;
3704 if ($nc == 0) { return array(0,0); }
3705 else if ($nc==1) { $charspacing = $w; }
3706 // Only word spacing allowed / possible
3707 else if ($this->fixedlSpacing !== false || $inclCursive) {
3708 if ($ns) { $ws = $w / $ns; }
3709 }
3710 else if (!$ns) {
3711 $charspacing = $w / ($ncx );
3712 if (($this->jSmaxChar > 0) && ($charspacing > $this->jSmaxChar)) {
3713 $charspacing = $this->jSmaxChar;
3714 }
3715 }
3716 else if ($ns == ($ncx )) {
3717 $charspacing = $w / $ns;
3718 }
3719 else {
3720 if ($this->usingCoreFont) {
3721 $cs = ($w * (1 - $this->jSWord)) / ($ncx );
3722 if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) {
3723 $cs = $this->jSmaxChar;
3724 $ww = 1 - (($cs * ($ncx ))/$w);
3725 }
3726 $charspacing = $cs;
3727 $ws = ($w * ($ww) ) / $ns;
3728 }
3729 else {
3730 $cs = ($w * (1 - $this->jSWord)) / ($ncx -$ns);
3731 if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) {
3732 $cs = $this->jSmaxChar;
3733 $ww = 1 - (($cs * ($ncx -$ns))/$w);
3734 }
3735 $charspacing = $cs;
3736 $ws = (($w * ($ww) ) / $ns) - $charspacing;
3737 }
3738 }
3739 return array($charspacing,$ws);
3740 }
3741
3742 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) {
3743 //Output a cell
3744 // Expects input to be mb_encoded if necessary and RTL reversed
3745 // NON_BREAKING SPACE
3746 if ($this->usingCoreFont) {
3747 $txt = str_replace(chr(160),chr(32),$txt);
3748 }
3749 else {
3750 $txt = str_replace(chr(194).chr(160),chr(32),$txt);
3751 }
3752
3753 $oldcolumn = $this->CurrCol;
3754 // Automatic page break
3755 // Allows PAGE-BREAK-AFTER = avoid to work
3756 if (!$this->tableLevel && (($this->y+$this->divheight>$this->PageBreakTrigger) || ($this->y+$h>$this->PageBreakTrigger) ||
3757 ($this->y+($h*2)+$this->blk[$this->blklvl]['padding_bottom']+$this->blk[$this->blklvl]['margin_bottom']>$this->PageBreakTrigger && $this->blk[$this->blklvl]['page_break_after_avoid'])) and !$this->InFooter and $this->AcceptPageBreak()) { // mPDF 5.7.2
3758 $x=$this->x;//Current X position
3759
3760
3761 // WORD SPACING
3762 $ws=$this->ws;//Word Spacing
3763 $charspacing=$this->charspacing;//Character Spacing
3764 $this->ResetSpacing();
3765
3766 $this->AddPage($this->CurOrientation);
3767 // Added to correct for OddEven Margins
3768 $x += $this->MarginCorrection;
3769 if ($currentx) {
3770 $currentx += $this->MarginCorrection;
3771 }
3772 $this->x=$x;
3773 // WORD SPACING
3774 $this->SetSpacing($charspacing,$ws);
3775 }
3776
3777 // Test: to put line through centre of cell: $this->Line($this->x,$this->y+($h/2),$this->x+50,$this->y+($h/2));
3778
3779 /*-- COLUMNS --*/
3780 // COLS
3781 // COLUMN CHANGE
3782 if ($this->CurrCol != $oldcolumn) {
3783 if ($currentx) {
3784 $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
3785 }
3786 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
3787 }
3788
3789 // COLUMNS Update/overwrite the lowest bottom of printing y value for a column
3790 if ($this->ColActive) {
3791 if ($h) { $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$h; }
3792 else { $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$this->divheight; }
3793 }
3794 /*-- END COLUMNS --*/
3795
3796 // KEEP BLOCK TOGETHER Update/overwrite the lowest bottom of printing y value on first page
3797 if ($this->keep_block_together) {
3798 if ($h) { $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$h; }
3799 // else { $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$this->divheight; }
3800 }
3801
3802 if($w==0) $w = $this->w-$this->rMargin-$this->x;
3803 $s='';
3804 if($fill==1 && $this->FillColor) {
3805 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.' '; }
3806 $this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
3807 }
3808
3809
3810 $boxtop = $this->y;
3811 $boxheight = $h;
3812 $boxbottom = $this->y+$h;
3813
3814 if($txt!='') {
3815 // FONT SIZE - this determines the baseline caculation
3816 if ($this->linemaxfontsize && !$this->processingHeader) { $bfs = $this->linemaxfontsize; }
3817 else { $bfs = $this->FontSize; }
3818 //Calculate baseline Superscript and Subscript Y coordinate adjustment
3819 $bfx = $this->baselineC;
3820 $baseline = $bfx*$bfs;
3821 // mPDF 5.7.3 inline text-decoration parameters
3822 if($this->SUP) { $baseline -= $this->textparam['text-baseline']; } // mPDF 5.7.1
3823 else if($this->SUB) { $baseline -= $this->textparam['text-baseline']; } // mPDF 5.7.1
3824 else if($this->bullet) { $baseline += ($bfx-0.7)*$this->FontSize; }
3825
3826 // Vertical align (for Images)
3827 if ($abovefont || $belowfont) { // from flowing block - valign always M
3828 $va = $abovefont + (0.5*$bfs);
3829 }
3830 else if ($this->lineheight_correction) {
3831 if ($valign == 'T') { $va = (0.5 * $bfs * $this->lineheight_correction); }
3832 else if ($valign == 'B') { $va = $h-(0.5 * $bfs * $this->lineheight_correction); }
3833 else { $va = 0.5*$h; } // Middle
3834 }
3835 else {
3836 if ($valign == 'T') { $va = (0.5 * $bfs * $this->default_lineheight_correction); }
3837 else if ($valign == 'B') { $va = $h-(0.5 * $bfs * $this->default_lineheight_correction); }
3838 else { $va = 0.5*$h; } // Middle
3839 }
3840
3841 // ONLY SET THESE IF WANT TO CONFINE BORDER +/- FILL TO FIT FONTSIZE - NOT FULL CELL AS IS ORIGINAL FUNCTION
3842 // spanfill or spanborder are set in FlowingBlock functions
3843 if ($spanfill || !empty($this->spanborddet) || $link!='') {
3844 $exth = 0.2; // Add to fontsize to increase height of background / link / border
3845 $boxtop = $this->y+$baseline+$va-($this->FontSize*(1+$exth/2)*(0.5+$bfx));
3846 $boxheight = $this->FontSize * (1+$exth);
3847 $boxbottom = $boxtop + $boxheight;
3848 }
3849 }
3850
3851 $bbw = $tbw = $lbw = $rbw = 0; // Border widths
3852 if (!empty($this->spanborddet)) {
3853 if (!isset($this->spanborddet['B'])) { $this->spanborddet['B'] = array('s' => 0, 'style' => '', 'w' => 0); }
3854 if (!isset($this->spanborddet['T'])) { $this->spanborddet['T'] = array('s' => 0, 'style' => '', 'w' => 0); }
3855 if (!isset($this->spanborddet['L'])) { $this->spanborddet['L'] = array('s' => 0, 'style' => '', 'w' => 0); }
3856 if (!isset($this->spanborddet['R'])) { $this->spanborddet['R'] = array('s' => 0, 'style' => '', 'w' => 0); }
3857 $bbw = $this->spanborddet['B']['w'];
3858 $tbw = $this->spanborddet['T']['w'];
3859 $lbw = $this->spanborddet['L']['w'];
3860 $rbw = $this->spanborddet['R']['w'];
3861 }
3862 if($fill==1 || $border==1 || !empty($this->spanborddet)) {
3863 if (!empty($this->spanborddet)) {
3864 if ($fill==1) {
3865 $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);
3866 }
3867 $s.= ' q ';
3868 $dashon = 3;
3869 $dashoff = 3.5;
3870 $dot = 2.5;
3871 if($tbw) {
3872 $short = 0;
3873 if ($this->spanborddet['T']['style'] == 'dashed') {
3874 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$tbw*$dashon*_MPDFK,$tbw*$dashoff*_MPDFK);
3875 }
3876 else if ($this->spanborddet['T']['style'] == 'dotted') {
3877 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$tbw*$dot*_MPDFK,-$tbw/2*_MPDFK);
3878 $short = $tbw/2;
3879 }
3880 else {
3881 $s.=' 0 j 0 J [] 0 d ';
3882 }
3883 $c = $this->SetDColor($this->spanborddet['T']['c'],true);
3884 if ($this->spanborddet['T']['style'] == 'double') {
3885 $s.=sprintf(' %s %.3F w ',$c,$tbw/3*_MPDFK);
3886 $xadj = $xadj2 = 0;
3887 if ($this->spanborddet['L']['style'] == 'double') { $xadj = $this->spanborddet['L']['w']*2/3; }
3888 if ($this->spanborddet['R']['style'] == 'double') { $xadj2 = $this->spanborddet['R']['w']*2/3; }
3889 $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);
3890 $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);
3891 }
3892 else {
3893 $s.=sprintf(' %s %.3F w ',$c,$tbw*_MPDFK);
3894 $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);
3895 }
3896 }
3897 if($bbw) {
3898 $short = 0;
3899 if ($this->spanborddet['B']['style'] == 'dashed') {
3900 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$bbw*$dashon*_MPDFK,$bbw*$dashoff*_MPDFK);
3901 }
3902 else if ($this->spanborddet['B']['style'] == 'dotted') {
3903 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$bbw*$dot*_MPDFK,-$bbw/2*_MPDFK);
3904 $short = $bbw/2;
3905 }
3906 else {
3907 $s.=' 0 j 0 J [] 0 d ';
3908 }
3909 $c = $this->SetDColor($this->spanborddet['B']['c'],true);
3910 if ($this->spanborddet['B']['style'] == 'double') {
3911 $s.=sprintf(' %s %.3F w ',$c,$bbw/3*_MPDFK);
3912 $xadj = $xadj2 = 0;
3913 if ($this->spanborddet['L']['style'] == 'double') { $xadj = $this->spanborddet['L']['w']*2/3; }
3914 if ($this->spanborddet['R']['style'] == 'double') { $xadj2 = $this->spanborddet['R']['w']*2/3; }
3915 $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);
3916 $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);
3917 }
3918 else {
3919 $s.=sprintf(' %s %.3F w ',$c,$bbw*_MPDFK);
3920 $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);
3921 }
3922 }
3923 if($lbw) {
3924 $short = 0;
3925 if ($this->spanborddet['L']['style'] == 'dashed') {
3926 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$lbw*$dashon*_MPDFK,$lbw*$dashoff*_MPDFK);
3927 }
3928 else if ($this->spanborddet['L']['style'] == 'dotted') {
3929 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$lbw*$dot*_MPDFK,-$lbw/2*_MPDFK);
3930 $short = $lbw/2;
3931 }
3932 else {
3933 $s.=' 0 j 0 J [] 0 d ';
3934 }
3935 $c = $this->SetDColor($this->spanborddet['L']['c'],true);
3936 if ($this->spanborddet['L']['style'] == 'double') {
3937 $s.=sprintf(' %s %.3F w ',$c,$lbw/3*_MPDFK);
3938 $yadj = $yadj2 = 0;
3939 if ($this->spanborddet['T']['style'] == 'double') { $yadj = $this->spanborddet['T']['w']*2/3; }
3940 if ($this->spanborddet['B']['style'] == 'double') { $yadj2 = $this->spanborddet['B']['w']*2/3; }
3941 $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);
3942 $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);
3943 }
3944 else {
3945 $s.=sprintf(' %s %.3F w ',$c,$lbw*_MPDFK);
3946 $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);
3947 }
3948 }
3949 if($rbw) {
3950 $short = 0;
3951 if ($this->spanborddet['R']['style'] == 'dashed') {
3952 $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$rbw*$dashon*_MPDFK,$rbw*$dashoff*_MPDFK);
3953 }
3954 else if ($this->spanborddet['R']['style'] == 'dotted') {
3955 $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$rbw*$dot*_MPDFK,-$rbw/2*_MPDFK);
3956 $short = $rbw/2;
3957 }
3958 else {
3959 $s.=' 0 j 0 J [] 0 d ';
3960 }
3961 $c = $this->SetDColor($this->spanborddet['R']['c'],true);
3962 if ($this->spanborddet['R']['style'] == 'double') {
3963 $s.=sprintf(' %s %.3F w ',$c,$rbw/3*_MPDFK);
3964 $yadj = $yadj2 = 0;
3965 if ($this->spanborddet['T']['style'] == 'double') { $yadj = $this->spanborddet['T']['w']*2/3; }
3966 if ($this->spanborddet['B']['style'] == 'double') { $yadj2 = $this->spanborddet['B']['w']*2/3; }
3967 $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);
3968 $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);
3969 }
3970 else {
3971 $s.=sprintf(' %s %.3F w ',$c,$rbw*_MPDFK);
3972 $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);
3973 }
3974 }
3975 $s.= ' Q ';
3976 }
3977 else {
3978 if ($fill==1) $op=($border==1) ? 'B' : 'f';
3979 else $op='S';
3980 $s.=sprintf('%.3F %.3F %.3F %.3F re %s ',$this->x*_MPDFK,($this->h-$boxtop)*_MPDFK,$w*_MPDFK,-$boxheight*_MPDFK,$op);
3981 }
3982 }
3983
3984 if(is_string($border)) {
3985 $x=$this->x;
3986 $y=$this->y;
3987 if(is_int(strpos($border,'L')))
3988 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-$boxtop)*_MPDFK,$x*_MPDFK,($this->h-($boxbottom))*_MPDFK);
3989 if(is_int(strpos($border,'T')))
3990 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-$boxtop)*_MPDFK,($x+$w)*_MPDFK,($this->h-$boxtop)*_MPDFK);
3991 if(is_int(strpos($border,'R')))
3992 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($x+$w)*_MPDFK,($this->h-$boxtop)*_MPDFK,($x+$w)*_MPDFK,($this->h-($boxbottom))*_MPDFK);
3993 if(is_int(strpos($border,'B')))
3994 $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-($boxbottom))*_MPDFK,($x+$w)*_MPDFK,($this->h-($boxbottom))*_MPDFK);
3995 }
3996
3997 if($txt!='') {
3998 if ($exactWidth)
3999 $stringWidth = $w;
4000 else
4001 $stringWidth = $this->GetStringWidth($txt) + ( $this->charspacing * mb_strlen( $txt, $this->mb_enc ) / _MPDFK )
4002 + ( $this->ws * mb_substr_count( $txt, ' ', $this->mb_enc ) / _MPDFK );
4003
4004 // Set x OFFSET FOR PRINTING
4005 if($align=='R') {
4006 $dx=$w-$this->cMarginR - $stringWidth - $lcpaddingR;
4007 }
4008 elseif($align=='C') {
4009 $dx=(($w - $stringWidth )/2);
4010 }
4011 elseif($align=='L' or $align=='J') $dx=$this->cMarginL + $lcpaddingL;
4012 else $dx = 0;
4013
4014 if($this->ColorFlag) $s .='q '.$this->TextColor.' ';
4015
4016 // OUTLINE
4017 if($this->textparam['outline-s'] && !$this->S) { // mPDF 5.6.07
4018 $s .=' '.sprintf('%.3F w',$this->LineWidth*_MPDFK).' ';
4019 $s .=" $this->DrawColor ";
4020 $s .=" 2 Tr ";
4021 }
4022 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
4023 $s .= ' 2 Tr 1 J 1 j ';
4024 $s .= ' '.sprintf('%.3F w',($this->FontSize/130)*_MPDFK*$this->falseBoldWeight).' ';
4025 $tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
4026 if($this->FillColor!=$tc) { $s .= ' '.$tc.' '; } // stroke (outline) = same colour as text(fill)
4027 }
4028 else { $s .=" 0 Tr "; } // mPDF 5.6.07
4029
4030 if (strpos($this->ReqFontStyle,"I") !== false && strpos($this->FontStyle,"I") === false) { // Artificial italic
4031 $aix = '1 0 0.261799 1 %.3F %.3F Tm ';
4032 }
4033 else { $aix = '%.3F %.3F Td '; }
4034
4035 // THE TEXT
4036 $sub = '';
4037 $this->CurrentFont['used']= true;
4038
4039 // WORD SPACING
4040 // IF multibyte - Tw has no effect - need to use alternative method - do word spacing using an adjustment before each space
4041 if ($this->ws && !$this->usingCoreFont && !$this->CurrentFont['sip'] && !$this->CurrentFont['smp'] && !$this->S) {
4042 $sub .= ' BT 0 Tw ET ';
4043 if ($this->kerning && $this->useKerning) { $sub .= $this->_kern($txt, 'MBTw', $aix, ($this->x+$dx), ($this->y+$baseline+$va)); }
4044 else {
4045 $space = " ";
4046 //Convert string to UTF-16BE without BOM
4047 $space= $this->UTF8ToUTF16BE($space , false);
4048 $space=$this->_escape($space );
4049 $sub .=sprintf('BT '.$aix,($this->x+$dx)*_MPDFK,($this->h-($this->y+$baseline+$va))*_MPDFK);
4050 $t = explode(' ',$txt);
4051 $sub .=sprintf(' %.3F Tc [',$this->charspacing);
4052 $numt = count($t);
4053 for($i=0;$i<$numt;$i++) {
4054 $tx = $t[$i];
4055 //Convert string to UTF-16BE without BOM
4056 $tx = $this->UTF8ToUTF16BE($tx , false);
4057 $tx = $this->_escape($tx);
4058 $sub .=sprintf('(%s) ',$tx);
4059 if (($i+1)<$numt) {
4060 $adj = -($this->ws)*1000/$this->FontSizePt;
4061 $sub .=sprintf('%d(%s) ',$adj,$space);
4062 }
4063 }
4064 $sub .='] TJ ';
4065 $sub .=' ET';
4066 }
4067 }
4068 else {
4069 $txt2= $txt;
4070 if ($this->CurrentFont['type']=='TTF' && ($this->CurrentFont['sip'] || $this->CurrentFont['smp'])) {
4071 if ($this->S) { $sub .= $this->_smallCaps($txt2, 'SIPSMP', $aix, $dx, _MPDFK, $baseline, $va); }
4072 else {
4073 $txt2 = $this->UTF8toSubset($txt2);
4074 $sub .=sprintf('BT '.$aix.' %s Tj ET',($this->x+$dx)*_MPDFK,($this->h-($this->y+$baseline+$va))*_MPDFK,$txt2);
4075 }
4076 }
4077 else {
4078 if ($this->S) { $sub .= $this->_smallCaps($txt2, '', $aix, $dx, _MPDFK, $baseline, $va); }
4079 else if ($this->kerning && $this->useKerning) { $sub .= $this->_kern($txt2, '', $aix, ($this->x+$dx), ($this->y+$baseline+$va)); }
4080 else {
4081 if (!$this->usingCoreFont) {
4082 $txt2 = $this->UTF8ToUTF16BE($txt2, false);
4083 }
4084 $txt2=$this->_escape($txt2);
4085 $sub .=sprintf('BT '.$aix.' (%s) Tj ET',($this->x+$dx)*_MPDFK,($this->h-($this->y+$baseline+$va))*_MPDFK,$txt2);
4086 }
4087 }
4088 }
4089 // UNDERLINE
4090 if($this->U) {
4091 // mPDF 5.7.3 inline text-decoration parameters
4092 $c = $this->textparam['u-decoration']['color'];
4093 if($this->FillColor!=$c) { $sub .= ' '.$c.' '; }
4094 // mPDF 5.7.3 inline text-decoration parameters
4095 $decorationfontkey = $this->textparam['u-decoration']['fontkey'];
4096 $decorationfontsize = $this->textparam['u-decoration']['fontsize'];
4097 if (isset($this->fonts[$decorationfontkey]['up'])) { $up=$this->fonts[$decorationfontkey]['up']; }
4098 else { $up = -100; }
4099 $adjusty = (-$up/1000* $decorationfontsize);
4100 if (isset($this->fonts[$decorationfontkey]['ut'])) { $ut=$this->fonts[$decorationfontkey]['ut']/1000* $decorationfontsize; }
4101 else { $ut = 60/1000* $decorationfontsize; }
4102 $ubaseline = $this->baselineC*$bfs - $this->textparam['u-decoration']['baseline'];
4103 $olw = $this->LineWidth;
4104 $sub .=' '.(sprintf(' %.3F w 0 j 0 J ',$ut*_MPDFK));
4105 $sub .=' '.$this->_dounderline($this->x+$dx,$this->y+$ubaseline+$va+$adjusty,$txt,$OTLdata,$textvar);
4106 $sub .=' '.(sprintf(' %.3F w 2 j 2 J ',$olw*_MPDFK));
4107 if($this->FillColor!=$c) { $sub .= ' '.$this->FillColor.' '; }
4108 }
4109
4110 // STRIKETHROUGH
4111 if($this->strike) {
4112 // mPDF 5.7.3 inline text-decoration parameters
4113 $c = $this->textparam['s-decoration']['color'];
4114 if($this->FillColor!=$c) { $sub .= ' '.$c.' '; }
4115 // mPDF 5.7.3 inline text-decoration parameters
4116 $decorationfontkey = $this->textparam['s-decoration']['fontkey'];
4117 $decorationfontsize = $this->textparam['s-decoration']['fontsize'];
4118 //Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
4119 if (isset($this->fonts[$decorationfontkey]['desc']['CapHeight'])) { $ch=$this->fonts[$decorationfontkey]['desc']['CapHeight']; }
4120 else { $ch = 700; }
4121 $adjusty = (-$ch/1000* $decorationfontsize) * $this->baselineS;
4122 if (isset($this->fonts[$decorationfontkey]['ut'])) { $ut=$this->fonts[$decorationfontkey]['ut']/1000* $decorationfontsize; }
4123 else { $ut = 60/1000* $decorationfontsize; }
4124 $sbaseline = $this->baselineC*$bfs - $this->textparam['s-decoration']['baseline'];
4125 $olw = $this->LineWidth;
4126 $sub .=' '.(sprintf(' %.3F w 0 j 0 J ',$ut*_MPDFK));
4127 $sub .=' '.$this->_dounderline($this->x+$dx,$this->y+$sbaseline+$va+$adjusty,$txt,$OTLdata,$textvar);
4128 $sub .=' '.(sprintf(' %.3F w 2 j 2 J ',$olw*_MPDFK));
4129 if($this->FillColor!=$c) { $sub .= ' '.$this->FillColor.' '; }
4130 }
4131
4132 // TEXT SHADOW
4133 if ($this->textshadow) { // First to process is last in CSS comma separated shadows
4134 foreach($this->textshadow AS $ts) {
4135 $s .= ' q ';
4136 $s .= $this->SetTColor($ts['col'], true)."\n";
4137 if ($ts['col']{0}==5 && ord($ts['col']{4})<100) { // RGBa
4138 $s .= $this->SetAlpha(ord($ts['col']{4})/100, 'Normal', true, 'F')."\n";
4139 }
4140 else if ($ts['col']{0}==6 && ord($ts['col']{5})<100) { // CMYKa
4141 $s .= $this->SetAlpha(ord($ts['col']{5})/100, 'Normal', true, 'F')."\n";
4142 }
4143 else if ($ts['col']{0}==1 && $ts['col']{2}==1 && ord($ts['col']{3})<100) { // Gray
4144 $s .= $this->SetAlpha(ord($ts['col']{3})/100, 'Normal', true, 'F')."\n";
4145 }
4146 $s .= sprintf(' 1 0 0 1 %.4F %.4F cm', $ts['x']*_MPDFK, -$ts['y']*_MPDFK)."\n";
4147 $s .= $sub;
4148 $s .= ' Q ';
4149 }
4150 }
4151
4152 $s .= $sub;
4153
4154 // COLOR
4155 if($this->ColorFlag) $s .=' Q';
4156
4157 // LINK
4158 if($link!='') {
4159 $this->Link($this->x,$boxtop,$w,$boxheight,$link);
4160 }
4161 }
4162 if($s) $this->_out($s);
4163
4164 // WORD SPACING
4165 if ($this->ws && !$this->usingCoreFont) {
4166 $this->_out(sprintf('BT %.3F Tc ET',$this->charspacing));
4167 }
4168 $this->lasth=$h;
4169 if( strpos($txt,"\n") !== false) $ln=1; // cell recognizes \n from <BR> tag
4170 if($ln>0)
4171 {
4172 //Go to next line
4173 $this->y += $h;
4174 if($ln==1) {
4175 //Move to next line
4176 if ($currentx != 0) { $this->x=$currentx; }
4177 else { $this->x=$this->lMargin; }
4178 }
4179 }
4180 else $this->x+=$w;
4181
4182
4183 }
4184
4185
4186 function _kern($txt, $mode, $aix, $x, $y) {
4187 if ($mode == 'MBTw') { // Multibyte requiring word spacing
4188 $space = ' ';
4189 //Convert string to UTF-16BE without BOM
4190 $space= $this->UTF8ToUTF16BE($space , false);
4191 $space=$this->_escape($space );
4192 $s = sprintf(' BT '.$aix,$x*_MPDFK,($this->h-$y)*_MPDFK);
4193 $t = explode(' ',$txt);
4194 for($i=0;$i<count($t);$i++) {
4195 $tx = $t[$i];
4196
4197 $tj = '(';
4198 $unicode = $this->UTF8StringToArray($tx);
4199 for($ti=0;$ti<count($unicode);$ti++) {
4200 if ($ti > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($ti-1)]][$unicode[$ti]])) {
4201 $kern = -$this->CurrentFont['kerninfo'][$unicode[($ti-1)]][$unicode[$ti]];
4202 $tj .= sprintf(')%d(',$kern);
4203 }
4204 $tc = code2utf($unicode[$ti]);
4205 $tc = $this->UTF8ToUTF16BE($tc, false);
4206 $tj .= $this->_escape($tc);
4207 }
4208 $tj .= ')';
4209 $s.=sprintf(' %.3F Tc [%s] TJ',$this->charspacing,$tj);
4210
4211
4212 if (($i+1)<count($t)) {
4213 $s.=sprintf(' %.3F Tc (%s) Tj',$this->ws+$this->charspacing,$space);
4214 }
4215 }
4216 $s.=' ET ';
4217 }
4218 else if (!$this->usingCoreFont) {
4219 $s = '';
4220 $tj = '(';
4221 $unicode = $this->UTF8StringToArray($txt);
4222 for($i=0;$i<count($unicode);$i++) {
4223 if ($i > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($i-1)]][$unicode[$i]])) {
4224 $kern = -$this->CurrentFont['kerninfo'][$unicode[($i-1)]][$unicode[$i]];
4225 $tj .= sprintf(')%d(',$kern);
4226 }
4227 $tx = code2utf($unicode[$i]);
4228 $tx = $this->UTF8ToUTF16BE($tx, false);
4229 $tj .= $this->_escape($tx);
4230 }
4231 $tj .= ')';
4232 $s.=sprintf(' BT '.$aix.' [%s] TJ ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$tj);
4233 }
4234 else { // CORE Font
4235 $s = '';
4236 $tj = '(';
4237 $l = strlen($txt);
4238 for($i=0;$i<$l;$i++) {
4239 if ($i > 0 && isset($this->CurrentFont['kerninfo'][$txt[($i-1)]][$txt[$i]])) {
4240 $kern = -$this->CurrentFont['kerninfo'][$txt[($i-1)]][$txt[$i]];
4241 $tj .= sprintf(')%d(',$kern);
4242 }
4243 $tj .= $this->_escape($txt[$i]);
4244 }
4245 $tj .= ')';
4246 $s.=sprintf(' BT '.$aix.' [%s] TJ ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$tj);
4247 }
4248
4249 return $s;
4250 }
4251
4252
4253 function _smallCaps($txt, $mode, $aix, $dx, $k, $baseline, $va) {
4254 $upp = false;
4255 $str = array();
4256 $bits = array();
4257 if (!$this->usingCoreFont) {
4258 $unicode = $this->UTF8StringToArray($txt);
4259 foreach($unicode as $char) {
4260 if ($this->ws && $char == 32) { // space
4261 if (count($str)) { $bits[] = array($upp, $str, false); }
4262 $bits[] = array(false, array(32), true);
4263 $str = array();
4264 $upp = false;
4265 }
4266 else if (isset($this->upperCase[$char])) {
4267 if (!$upp) {
4268 if (count($str)) { $bits[] = array($upp, $str, false); }
4269 $str = array();
4270 }
4271 $str[] = $this->upperCase[$char];
4272 if ((!isset($this->CurrentFont['sip']) || !$this->CurrentFont['sip']) && (!isset($this->CurrentFont['smp']) || !$this->CurrentFont['smp'])) {
4273 $this->CurrentFont['subset'][$this->upperCase[$char]] = $this->upperCase[$char];
4274 }
4275 $upp = true;
4276 }
4277 else {
4278 if ($upp) {
4279 if (count($str)) { $bits[] = array($upp, $str, false); }
4280 $str = array();
4281 }
4282 $str[] = $char;
4283 $upp = false;
4284 }
4285 }
4286 }
4287 else {
4288 for($i=0;$i<strlen($txt);$i++) {
4289 if (isset($this->upperCase[ord($txt[$i])]) && $this->upperCase[ord($txt[$i])] < 256) {
4290 if (!$upp) {
4291 if (count($str)) { $bits[] = array($upp, $str, false); }
4292 $str = array();
4293 }
4294 $str[] = $this->upperCase[ord($txt[$i])];
4295 $upp = true;
4296 }
4297 else {
4298 if ($upp) {
4299 if (count($str)) { $bits[] = array($upp, $str, false); }
4300 $str = array();
4301 }
4302 $str[] = ord($txt[$i]);
4303 $upp = false;
4304 }
4305 }
4306 }
4307 if (count($str)) { $bits[] = array($upp, $str, false); }
4308
4309 $fid = $this->CurrentFont['i'];
4310
4311 $s=sprintf(' BT '.$aix,($this->x+$dx)*$k,($this->h-($this->y+$baseline+$va))*$k);
4312 foreach($bits AS $b) {
4313 if ($b[0]) { $upp = true; }
4314 else { $upp = false; }
4315
4316 $size = count ($b[1]);
4317 $txt = '';
4318 for ($i = 0; $i < $size; $i++) {
4319 $txt .= code2utf($b[1][$i]);
4320 }
4321 if ($this->usingCoreFont) {
4322 $txt = utf8_decode($txt);
4323 }
4324 if ($mode == 'SIPSMP') {
4325 $txt = $this->UTF8toSubset($txt);
4326 }
4327 else {
4328 if (!$this->usingCoreFont) {
4329 $txt = $this->UTF8ToUTF16BE($txt, false);
4330 }
4331 $txt=$this->_escape($txt);
4332 $txt = '('.$txt.')';
4333 }
4334 if ($b[2]) { // space
4335 $s.=sprintf(' /F%d %.3F Tf %d Tz', $fid, $this->FontSizePt, 100);
4336 $s.=sprintf(' %.3F Tc', ($this->charspacing+$this->ws));
4337 $s.=sprintf(' %s Tj', $txt);
4338 }
4339 else if ($upp) {
4340 $s.=sprintf(' /F%d %.3F Tf', $fid, $this->FontSizePt*$this->smCapsScale);
4341 $s.=sprintf(' %d Tz', $this->smCapsStretch);
4342 $s.=sprintf(' %.3F Tc', ($this->charspacing*100/$this->smCapsStretch));
4343 $s.=sprintf(' %s Tj', $txt);
4344 }
4345 else {
4346 $s.=sprintf(' /F%d %.3F Tf %d Tz', $fid, $this->FontSizePt, 100);
4347 $s.=sprintf(' %.3F Tc', ($this->charspacing));
4348 $s.=sprintf(' %s Tj', $txt);
4349 }
4350 }
4351 $s.=' ET ';
4352 return $s;
4353 }
4354
4355
4356 function MultiCell($w,$h,$txt,$border=0,$align='',$fill=0,$link='',$directionality='ltr',$encoded=false)
4357 {
4358 // Parameter (pre-)encoded - When called internally from ToC or textarea: mb_encoding already done - but not reverse RTL/Indic
4359 if (!$encoded) {
4360 $txt = $this->purify_utf8_text($txt);
4361 if ($this->text_input_as_HTML) {
4362 $txt = $this->all_entities_to_utf8($txt);
4363 }
4364 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
4365 // Font-specific ligature substitution for Indic fonts
4366 else if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { // *INDIC*
4367 $this->ConvertIndic($tmp); // *INDIC*
4368 } // *INDIC*
4369 if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *RTL*
4370 }
4371 if (!$align) { $align = $this->defaultAlign; }
4372
4373 //Output text with automatic or explicit line breaks
4374 $cw=&$this->CurrentFont['cw'];
4375 if($w==0) $w=$this->w-$this->rMargin-$this->x;
4376
4377 $wmax = ($w - ($this->cMarginL+$this->cMarginR));
4378 if ($this->usingCoreFont) {
4379 $s=str_replace("\r",'',$txt);
4380 $nb=strlen($s);
4381 while($nb>0 and $s[$nb-1]=="\n") $nb--;
4382 }
4383 else {
4384 $s=str_replace("\r",'',$txt);
4385 $nb=mb_strlen($s, $this->mb_enc );
4386 while($nb>0 and mb_substr($s,$nb-1,1,$this->mb_enc )=="\n") $nb--;
4387 }
4388 $b=0;
4389 if($border) {
4390 if($border==1) {
4391 $border='LTRB';
4392 $b='LRT';
4393 $b2='LR';
4394 }
4395 else {
4396 $b2='';
4397 if(is_int(strpos($border,'L'))) $b2.='L';
4398 if(is_int(strpos($border,'R'))) $b2.='R';
4399 $b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
4400 }
4401 }
4402 $sep=-1;
4403 $i=0;
4404 $j=0;
4405 $l=0;
4406 $ns=0;
4407 $nl=1;
4408
4409
4410
4411 if (!$this->usingCoreFont) {
4412 $checkCursive=false;
4413 if ($this->biDirectional) { $checkCursive=true; }
4414 else if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { $checkCursive=true; } // *INDIC*
4415 while($i<$nb) {
4416 //Get next character
4417 $c = mb_substr($s,$i,1,$this->mb_enc );
4418 if($c == "\n") {
4419 //Explicit line break
4420 // WORD SPACING
4421 $this->ResetSpacing();
4422 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
4423 // DIRECTIONALITY
4424 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4425
4426 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4427 $i++;
4428 $sep=-1;
4429 $j=$i;
4430 $l=0;
4431 $ns=0;
4432 $nl++;
4433 if($border and $nl==2) $b=$b2;
4434 continue;
4435 }
4436 if($c == " ") {
4437 $sep=$i;
4438 $ls=$l;
4439 $ns++;
4440 }
4441
4442 $l += $this->GetCharWidthNonCore($c);
4443
4444 if($l>$wmax) {
4445 //Automatic line break
4446 if($sep==-1) { // Only one word
4447 if($i==$j) $i++;
4448 // WORD SPACING
4449 $this->ResetSpacing();
4450 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
4451 // DIRECTIONALITY
4452 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4453
4454 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4455 }
4456 else {
4457 $tmp = rtrim(mb_substr($s,$j,$sep-$j,$this->mb_enc));
4458 if($align=='J') {
4459 //////////////////////////////////////////
4460 // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
4461 // WORD SPACING UNICODE
4462 // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
4463 $tmp = str_replace(chr(194).chr(160),chr(32),$tmp );
4464 $len_ligne = $this->GetStringWidth($tmp );
4465 $nb_carac = mb_strlen( $tmp , $this->mb_enc ) ;
4466 $nb_spaces = mb_substr_count( $tmp ,' ', $this->mb_enc ) ;
4467
4468 $inclCursive=false;
4469 if ($checkCursive) {
4470 if (preg_match("/([".$this->pregRTLchars."])/u", $tmp)) { $inclCursive = true; } // *RTL*
4471 if (preg_match("/([".$this->pregHIchars.$this->pregBNchars.$this->pregPAchars."])/u", $tmp)) { $inclCursive = true; } // *INDIC*
4472 }
4473 list($charspacing,$ws) = $this->GetJspacing($nb_carac,$nb_spaces,((($wmax) - $len_ligne) * _MPDFK),$inclCursive);
4474 $this->SetSpacing($charspacing,$ws);
4475 //////////////////////////////////////////
4476 }
4477
4478 // DIRECTIONALITY
4479 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4480
4481 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4482 $i=$sep+1;
4483 }
4484 $sep=-1;
4485 $j=$i;
4486 $l=0;
4487 $ns=0;
4488 $nl++;
4489 if($border and $nl==2) $b=$b2;
4490 }
4491 else $i++;
4492 }
4493 //Last chunk
4494 // WORD SPACING
4495
4496 $this->ResetSpacing();
4497
4498 }
4499
4500
4501 else {
4502
4503 while($i<$nb) {
4504 //Get next character
4505 $c=$s[$i];
4506 if($c == "\n") {
4507 //Explicit line break
4508 // WORD SPACING
4509 $this->ResetSpacing();
4510 $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
4511 $i++;
4512 $sep=-1;
4513 $j=$i;
4514 $l=0;
4515 $ns=0;
4516 $nl++;
4517 if($border and $nl==2) $b=$b2;
4518 continue;
4519 }
4520 if($c == " ") {
4521 $sep=$i;
4522 $ls=$l;
4523 $ns++;
4524 }
4525
4526 $l += $this->GetCharWidthCore($c);
4527 if($l>$wmax) {
4528 //Automatic line break
4529 if($sep==-1) {
4530 if($i==$j) $i++;
4531 // WORD SPACING
4532 $this->ResetSpacing();
4533 $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
4534 }
4535 else {
4536 if($align=='J') {
4537 $tmp = rtrim(substr($s,$j,$sep-$j));
4538 //////////////////////////////////////////
4539 // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
4540 // WORD SPACING NON_UNICDOE/CJK
4541 // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
4542 $tmp = str_replace(chr(160),chr(32),$tmp);
4543 $len_ligne = $this->GetStringWidth($tmp );
4544 $nb_carac = strlen( $tmp ) ;
4545 $nb_spaces = substr_count( $tmp ,' ' ) ;
4546 list($charspacing,$ws) = $this->GetJspacing($nb_carac,$nb_spaces,((($wmax) - $len_ligne) * _MPDFK),false);
4547 $this->SetSpacing($charspacing,$ws);
4548 //////////////////////////////////////////
4549 }
4550 $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill,$link);
4551 $i=$sep+1;
4552 }
4553 $sep=-1;
4554 $j=$i;
4555 $l=0;
4556 $ns=0;
4557 $nl++;
4558 if($border and $nl==2) $b=$b2;
4559 }
4560 else $i++;
4561 }
4562 //Last chunk
4563 // WORD SPACING
4564
4565 $this->ResetSpacing();
4566
4567 }
4568 //Last chunk
4569 if($border and is_int(strpos($border,'B'))) $b.='B';
4570 if (!$this->usingCoreFont) {
4571 $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
4572 // DIRECTIONALITY
4573 $this->magic_reverse_dir($tmp, true, $directionality); // *RTL*
4574 $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link);
4575 }
4576 else { $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link); }
4577 $this->x=$this->lMargin;
4578 }
4579
4580
4581 /*-- DIRECTW --*/
4582 function Write($h,$txt,$currentx=0,$link='',$directionality='ltr',$align='') {
4583 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
4584 if (empty($this->directw)) { $this->directw = new directw($this); }
4585 $this->directw->Write($h,$txt,$currentx,$link,$directionality,$align);
4586 }
4587 /*-- END DIRECTW --*/
4588
4589
4590 /*-- HTML-CSS --*/
4591 function saveInlineProperties() {
4592 $saved = array();
4593 $saved[ 'family' ] = $this->FontFamily;
4594 $saved[ 'style' ] = $this->FontStyle;
4595 $saved[ 'sizePt' ] = $this->FontSizePt;
4596 $saved[ 'size' ] = $this->FontSize;
4597 $saved[ 'HREF' ] = $this->HREF;
4598 $saved[ 'underline' ] = $this->U;
4599 $saved[ 'smCaps' ] = $this->S;
4600 $saved[ 'strike' ] = $this->strike;
4601 $saved[ 'textshadow' ] = $this->textshadow;
4602 $saved[ 'SUP' ] = $this->SUP;
4603 $saved[ 'SUB' ] = $this->SUB;
4604 $saved[ 'linewidth' ] = $this->LineWidth;
4605 $saved[ 'drawcolor' ] = $this->DrawColor;
4606 $saved[ 'textparam' ] = $this->textparam;
4607 $saved[ 'toupper' ] = $this->toupper;
4608 $saved[ 'tolower' ] = $this->tolower;
4609 $saved[ 'capitalize' ] = $this->capitalize;
4610 $saved[ 'fontkerning' ] = $this->kerning;
4611 $saved[ 'lSpacingCSS' ] = $this->lSpacingCSS;
4612 $saved[ 'wSpacingCSS' ] = $this->wSpacingCSS;
4613 $saved[ 'I' ] = $this->I;
4614 $saved[ 'B' ] = $this->B;
4615 $saved[ 'colorarray' ] = $this->colorarray;
4616 $saved[ 'bgcolorarray' ] = $this->spanbgcolorarray;
4617 $saved[ 'border' ] = $this->spanborddet;
4618 $saved[ 'color' ] = $this->TextColor;
4619 $saved[ 'bgcolor' ] = $this->FillColor;
4620 $saved[ 'lang' ] = $this->currentLang;
4621 $saved[ 'display_off' ] = $this->inlineDisplayOff;
4622
4623 return $saved;
4624 }
4625
4626 function restoreInlineProperties( &$saved) {
4627 $FontFamily = $saved[ 'family' ];
4628 $this->FontStyle = $saved[ 'style' ];
4629 $this->FontSizePt = $saved[ 'sizePt' ];
4630 $this->FontSize = $saved[ 'size' ];
4631
4632 $this->currentLang = $saved['lang'];
4633 if ($this->useLang && !$this->usingCoreFont) {
4634 if ($this->currentLang != $this->default_lang && ((strlen($this->currentLang) == 5 && $this->currentLang != 'UTF-8') || strlen($this->currentLang ) == 2)) {
4635 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($this->currentLang, $this->useAdobeCJK);
4636 if ($mpdf_pdf_unifonts) { $this->RestrictUnicodeFonts($mpdf_pdf_unifonts); }
4637 else { $this->RestrictUnicodeFonts($this->default_available_fonts ); }
4638 }
4639 else {
4640 $this->RestrictUnicodeFonts($this->default_available_fonts );
4641 }
4642 }
4643
4644 $this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well
4645
4646 $this->HREF = $saved[ 'HREF' ];
4647 $this->U = $saved[ 'underline' ];
4648 $this->S = $saved[ 'smCaps' ];
4649 $this->strike = $saved[ 'strike' ];
4650 $this->textshadow = $saved[ 'textshadow' ];
4651 $this->SUP = $saved[ 'SUP' ];
4652 $this->SUB = $saved[ 'SUB' ];
4653 $this->LineWidth = $saved[ 'linewidth' ];
4654 $this->DrawColor = $saved[ 'drawcolor' ];
4655 $this->textparam = $saved[ 'textparam' ];
4656 $this->inlineDisplayOff = $saved['display_off'];
4657
4658 $this->toupper = $saved[ 'toupper' ];
4659 $this->tolower = $saved[ 'tolower' ];
4660 $this->capitalize = $saved[ 'capitalize' ];
4661 $this->kerning = $saved[ 'fontkerning' ];
4662 $this->lSpacingCSS = $saved[ 'lSpacingCSS' ];
4663 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
4664 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
4665 }
4666 else { $this->fixedlSpacing = false; }
4667 $this->wSpacingCSS = $saved[ 'wSpacingCSS' ];
4668 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
4669 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
4670 }
4671 else { $this->minwSpacing = 0; }
4672
4673 $this->SetFont($FontFamily, $saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ],false);
4674
4675 $this->currentfontstyle = $saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : '');
4676 $this->currentfontsize = $saved[ 'sizePt' ];
4677 $this->SetStylesArray(array('S'=>$this->S, 'U'=>$this->U, 'B'=>$saved[ 'B' ], 'I'=>$saved[ 'I' ]));
4678
4679 $this->TextColor = $saved[ 'color' ];
4680 $this->FillColor = $saved[ 'bgcolor' ];
4681 $this->colorarray = $saved[ 'colorarray' ];
4682 $cor = $saved[ 'colorarray' ];
4683 if ($cor) $this->SetTColor($cor);
4684 $this->spanbgcolorarray = $saved[ 'bgcolorarray' ];
4685 $cor = $saved[ 'bgcolorarray' ];
4686 if ($cor) $this->SetFColor($cor);
4687 $this->spanborddet = $saved[ 'border' ];
4688 }
4689
4690
4691
4692 // Used when ColActive for tables - updated to return first block with background fill OR borders
4693 function GetFirstBlockFill() {
4694 // Returns the first blocklevel that uses a bgcolor fill
4695 $startfill = 0;
4696 for ($i=1;$i<=$this->blklvl;$i++) {
4697 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'] ) {
4698 $startfill = $i;
4699 break;
4700 }
4701 }
4702 return $startfill;
4703 }
4704
4705 function SetBlockFill($blvl) {
4706 if ($this->blk[$blvl]['bgcolor']) {
4707 $this->SetFColor($this->blk[$blvl]['bgcolorarray']);
4708 return 1;
4709 }
4710 else {
4711 $this->SetFColor($this->ConvertColor(255));
4712 return 0;
4713 }
4714 }
4715
4716
4717 //-------------------------FLOWING BLOCK------------------------------------//
4718 //The following functions were originally written by Damon Kohler //
4719 //--------------------------------------------------------------------------//
4720
4721 function saveFont() {
4722 $saved = array();
4723 $saved[ 'family' ] = $this->FontFamily;
4724 $saved[ 'style' ] = $this->FontStyle;
4725 $saved[ 'sizePt' ] = $this->FontSizePt;
4726 $saved[ 'size' ] = $this->FontSize;
4727 $saved[ 'curr' ] = &$this->CurrentFont;
4728 $saved[ 'color' ] = $this->TextColor;
4729 $saved[ 'spanbgcolor' ] = $this->spanbgcolor;
4730 $saved[ 'spanbgcolorarray' ] = $this->spanbgcolorarray;
4731 $saved[ 'bord' ] = $this->spanborder;
4732 $saved[ 'border' ] = $this->spanborddet;
4733 $saved[ 'HREF' ] = $this->HREF;
4734 $saved[ 'underline' ] = $this->U;
4735 $saved[ 'smCaps' ] = $this->S;
4736 $saved[ 'strike' ] = $this->strike;
4737 $saved[ 'textshadow' ] = $this->textshadow;
4738 $saved[ 'SUP' ] = $this->SUP;
4739 $saved[ 'SUB' ] = $this->SUB;
4740 $saved[ 'linewidth' ] = $this->LineWidth;
4741 $saved[ 'drawcolor' ] = $this->DrawColor;
4742 $saved[ 'textparam' ] = $this->textparam;
4743 $saved[ 'ReqFontStyle' ] = $this->ReqFontStyle;
4744 $saved[ 'fontkerning' ] = $this->kerning;
4745 $saved[ 'fixedlSpacing' ] = $this->fixedlSpacing;
4746 $saved[ 'minwSpacing' ] = $this->minwSpacing;
4747 return $saved;
4748 }
4749
4750 function restoreFont( &$saved, $write=true) {
4751 if (!isset($saved) || empty($saved)) return;
4752
4753 $this->FontFamily = $saved[ 'family' ];
4754 $this->FontStyle = $saved[ 'style' ];
4755 $this->FontSizePt = $saved[ 'sizePt' ];
4756 $this->FontSize = $saved[ 'size' ];
4757 $this->CurrentFont = &$saved[ 'curr' ];
4758 $this->TextColor = $saved[ 'color' ];
4759 $this->spanbgcolor = $saved[ 'spanbgcolor' ];
4760 $this->spanbgcolorarray = $saved[ 'spanbgcolorarray' ];
4761 $this->spanborder = $saved[ 'bord' ];
4762 $this->spanborddet = $saved[ 'border' ];
4763 $this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well
4764 $this->HREF = $saved[ 'HREF' ];
4765 $this->U = $saved[ 'underline' ];
4766 $this->S = $saved[ 'smCaps' ];
4767 $this->kerning = $saved[ 'fontkerning' ];
4768 $this->fixedlSpacing = $saved[ 'fixedlSpacing' ];
4769 $this->minwSpacing = $saved[ 'minwSpacing' ];
4770 $this->strike = $saved[ 'strike' ];
4771 $this->textshadow = $saved[ 'textshadow' ];
4772 $this->SUP = $saved[ 'SUP' ];
4773 $this->SUB = $saved[ 'SUB' ];
4774 $this->LineWidth = $saved[ 'linewidth' ];
4775 $this->DrawColor = $saved[ 'drawcolor' ];
4776 $this->textparam = $saved[ 'textparam' ];
4777 if ($write) {
4778 $this->SetFont($saved[ 'family' ],$saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ],true,true); // force output
4779 $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
4780 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); }
4781 $this->pageoutput[$this->page]['Font'] = $fontout;
4782 }
4783 else
4784 $this->SetFont($saved[ 'family' ],$saved[ 'style' ].($this->U ? 'U' : '').($this->S ? 'S' : ''),$saved[ 'sizePt' ]);
4785 $this->ReqFontStyle = $saved[ 'ReqFontStyle' ];
4786 }
4787
4788 function newFlowingBlock( $w, $h, $a = '', $is_table = false, $is_list = false, $blockstate = 0, $newblock=true, $blockdir='ltr')
4789 {
4790 if (!$a) {
4791 if ($blockdir=='rtl') { $a = 'R'; }
4792 else { $a = 'L'; }
4793 }
4794 $this->flowingBlockAttr[ 'width' ] = ($w * _MPDFK);
4795 // line height in user units
4796 $this->flowingBlockAttr[ 'is_table' ] = $is_table;
4797 $this->flowingBlockAttr[ 'is_list' ] = $is_list;
4798 $this->flowingBlockAttr[ 'height' ] = $h;
4799 $this->flowingBlockAttr[ 'lineCount' ] = 0;
4800 $this->flowingBlockAttr[ 'align' ] = $a;
4801 $this->flowingBlockAttr[ 'font' ] = array();
4802 $this->flowingBlockAttr[ 'content' ] = array();
4803 $this->flowingBlockAttr[ 'contentB' ] = array();
4804 $this->flowingBlockAttr[ 'contentWidth' ] = 0;
4805 $this->flowingBlockAttr[ 'blockstate' ] = $blockstate;
4806
4807 $this->flowingBlockAttr[ 'newblock' ] = $newblock;
4808 $this->flowingBlockAttr[ 'valign' ] = 'M';
4809 $this->flowingBlockAttr['blockdir'] = $blockdir;
4810
4811 }
4812
4813 function finishFlowingBlock($endofblock=false, $next='') {
4814 $currentx = $this->x;
4815 //prints out the last chunk
4816 $is_table = $this->flowingBlockAttr[ 'is_table' ];
4817 $is_list = $this->flowingBlockAttr[ 'is_list' ];
4818 $maxWidth =& $this->flowingBlockAttr[ 'width' ];
4819 $lineHeight =& $this->flowingBlockAttr[ 'height' ];
4820 $align =& $this->flowingBlockAttr[ 'align' ];
4821 $content =& $this->flowingBlockAttr[ 'content' ];
4822 $contentB =& $this->flowingBlockAttr[ 'contentB' ];
4823 $font =& $this->flowingBlockAttr[ 'font' ];
4824 $contentWidth =& $this->flowingBlockAttr[ 'contentWidth' ];
4825 $lineCount =& $this->flowingBlockAttr[ 'lineCount' ];
4826 $valign =& $this->flowingBlockAttr[ 'valign' ];
4827 $blockstate = $this->flowingBlockAttr[ 'blockstate' ];
4828
4829 $newblock = $this->flowingBlockAttr[ 'newblock' ];
4830 $blockdir = $this->flowingBlockAttr['blockdir'];
4831
4832
4833 // *********** BLOCK BACKGROUND COLOR *****************//
4834 if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
4835 $fill = 0;
4836 }
4837 else {
4838 $this->SetFColor($this->ConvertColor(255));
4839 $fill = 0;
4840 }
4841
4842 $hanger = ''; // mPDF 5.6.40
4843
4844 // Always right trim!
4845 // Right trim content and adjust width if need to justify (later)
4846 if (isset($content[count($content)-1]) && preg_match('/[ ]+$/',$content[count($content)-1], $m)) {
4847 $strip = strlen($m[0]);
4848 $content[count($content)-1] = substr($content[count($content)-1],0,(strlen($content[count($content)-1])-$strip));
4849 $this->restoreFont( $font[ count($content)-1 ],false );
4850 $contentWidth -= $this->GetStringWidth($m[0]) * _MPDFK;
4851 }
4852
4853 // the amount of space taken up so far in user units
4854 $usedWidth = 0;
4855
4856 // COLS
4857 $oldcolumn = $this->CurrCol;
4858
4859 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
4860
4861 // Print out each chunk
4862
4863 /*-- TABLES --*/
4864 if ($is_table) {
4865 $ipaddingL = 0;
4866 $ipaddingR = 0;
4867 $paddingL = 0;
4868 $paddingR = 0;
4869 }
4870 else {
4871 /*-- END TABLES --*/
4872 $ipaddingL = $this->blk[$this->blklvl]['padding_left'];
4873 $ipaddingR = $this->blk[$this->blklvl]['padding_right'];
4874 $paddingL = ($ipaddingL * _MPDFK);
4875 $paddingR = ($ipaddingR * _MPDFK);
4876 $this->cMarginL = $this->blk[$this->blklvl]['border_left']['w'];
4877 $this->cMarginR = $this->blk[$this->blklvl]['border_right']['w'];
4878
4879 // Added mPDF 3.0 Float DIV
4880 $fpaddingR = 0;
4881 $fpaddingL = 0;
4882 /*-- CSS-FLOAT --*/
4883 if (count($this->floatDivs)) {
4884 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
4885 if ($r_exists) { $fpaddingR = $r_width; }
4886 if ($l_exists) { $fpaddingL = $l_width; }
4887 }
4888 /*-- END CSS-FLOAT --*/
4889
4890 $usey = $this->y + 0.002;
4891 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
4892 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
4893 }
4894 /*-- CSS-IMAGE-FLOAT --*/
4895 // If float exists at this level
4896 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
4897 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
4898 /*-- END CSS-IMAGE-FLOAT --*/
4899 } // *TABLES*
4900
4901 // Set Current lineheight (correction factor)
4902 $lhfixed = false;
4903 /*-- LISTS --*/
4904 if ($is_list) {
4905 if (preg_match('/([0-9.,]+)mm/',$this->list_lineheight[$this->listlvl][$this->listOcc],$am)) {
4906 $lhfixed = true;
4907 $def_fontsize = $this->InlineProperties['LISTITEM'][$this->listlvl][$this->listOcc][$this->listnum]['size'];
4908 $this->lineheight_correction = $am[1] / $def_fontsize ;
4909 }
4910 else {
4911 $this->lineheight_correction = $this->list_lineheight[$this->listlvl][$this->listOcc];
4912 }
4913 }
4914 else
4915 /*-- END LISTS --*/
4916 /*-- TABLES --*/
4917 if ($is_table) {
4918 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight,$am)) {
4919 $lhfixed = true;
4920 $def_fontsize = $this->FontSize; // needs to be default font-size for block ****
4921 $this->lineheight_correction = $lineHeight / $def_fontsize ;
4922 }
4923 else {
4924 $this->lineheight_correction = $this->table_lineheight;
4925 }
4926 }
4927 else
4928 /*-- END TABLES --*/
4929 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
4930 if (preg_match('/([0-9.,]+)mm/',$this->blk[$this->blklvl]['line_height'],$am)) {
4931 $lhfixed = true;
4932 $def_fontsize = $this->blk[$this->blklvl]['InlineProperties']['size']; // needs to be default font-size for block ****
4933 $this->lineheight_correction = $am[1] / $def_fontsize ;
4934 }
4935 else {
4936 $this->lineheight_correction = $this->blk[$this->blklvl]['line_height'];
4937 }
4938 }
4939 else {
4940 $this->lineheight_correction = $this->normalLineheight;
4941 }
4942
4943 // correct lineheight to maximum fontsize
4944 if ($lhfixed) { $maxlineHeight = $this->lineheight; }
4945 else { $maxlineHeight = 0; }
4946 $this->forceExactLineheight = true;
4947 $maxfontsize = 0;
4948 // While we're at it, check if contains cursive text
4949 $checkCursive=false;
4950 if ($this->biDirectional) { $checkCursive=true; } // *RTL*
4951 foreach ( $content as $k => $chunk )
4952 {
4953 $this->restoreFont( $font[ $k ],false );
4954 if (!isset($this->objectbuffer[$k])) {
4955 // Soft Hyphens chr(173)
4956 if (!$this->usingCoreFont) {
4957 $content[$k] = $chunk = str_replace("\xc2\xad",'',$chunk );
4958 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { $checkCursive=true; } // *INDIC*
4959 }
4960 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
4961 $content[$k] = $chunk = str_replace(chr(173),'',$chunk );
4962 }
4963 // Special case of sub/sup carried over on its own to last line
4964 if (($this->SUB || $this->SUP) && count($content)==1) { $actfs = $this->FontSize*100/55; } // 55% is font change for sub/sup
4965 else { $actfs = $this->FontSize; }
4966 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
4967 if ($lhfixed && ($actfs > $def_fontsize || ($actfs > ($lineHeight * $this->lineheight_correction) && $is_list))) {
4968 $this->forceExactLineheight = false;
4969 }
4970 $maxfontsize = max($maxfontsize,$actfs);
4971 }
4972 }
4973
4974 if(isset($font[count($font)-1])) {
4975 $lastfontreqstyle = $font[count($font)-1]['ReqFontStyle'];
4976 $lastfontstyle = $font[count($font)-1]['style'];
4977 }
4978 else {
4979 $lastfontreqstyle=null;
4980 $lastfontstyle=null;
4981 }
4982 if ($blockdir == 'ltr' && strpos($lastfontreqstyle,"I") !== false && strpos($lastfontstyle,"I") === false) { // Artificial italic
4983 $lastitalic = $this->FontSize*0.15*_MPDFK;
4984 }
4985 else { $lastitalic = 0; }
4986
4987
4988 /*-- LISTS --*/
4989 if ($is_list && is_array($this->bulletarray) && count($this->bulletarray)) {
4990 $actfs = $this->bulletarray['fontsize'];
4991 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
4992 if ($lhfixed && $actfs > $def_fontsize) { $this->forceExactLineheight = false; }
4993 $maxfontsize = max($maxfontsize,$actfs);
4994 }
4995 /*-- END LISTS --*/
4996
4997 // when every text item checked i.e. $maxfontsize is set properly
4998
4999 $af = 0; // Above font
5000 $bf = 0; // Below font
5001 $mta = 0; // Maximum top-aligned
5002 $mba = 0; // Maximum bottom-aligned
5003
5004 foreach ( $content as $k => $chunk )
5005 {
5006 if (isset($this->objectbuffer[$k])) {
5007 $oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
5008 $va = $this->objectbuffer[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
5009 if ($lhfixed && $oh > $def_fontsize) { $this->forceExactLineheight = false; }
5010
5011 if ($va == 'BS') { // (BASELINE default)
5012 $af = max($af, ($oh - ($maxfontsize * (0.5 + $this->baselineC))));
5013 }
5014 else if ($va == 'M') {
5015 $af = max($af, ($oh - $maxfontsize)/2);
5016 $bf = max($bf, ($oh - $maxfontsize)/2);
5017 }
5018 else if ($va == 'TT') {
5019 $bf = max($bf, ($oh - $maxfontsize));
5020 }
5021 else if ($va == 'TB') {
5022 $af = max($af, ($oh - $maxfontsize));
5023 }
5024 else if ($va == 'T') {
5025 $mta = max($mta, $oh);
5026 }
5027 else if ($va == 'B') {
5028 $mba = max($mba, $oh);
5029 }
5030 }
5031 // mPDF 5.7.3 inline text-decoration parameters
5032 else if (!$is_table && isset($font[$k]['textparam']['text-baseline'])) {
5033 if ($font[$k]['textparam']['text-baseline'] > 0) { // superscript
5034 $nh = ($maxfontsize * $this->baselineC) + $font[$k]['textparam']['text-baseline'] + ($font[$k]['size'] * (1-$this->baselineC));
5035 if ($lhfixed && $nh > $def_fontsize) { $this->forceExactLineheight = false; }
5036 $af = max($af, ($nh-$maxfontsize));
5037 }
5038 else if ($font[$k]['textparam']['text-baseline'] < 0) { // subscript
5039 $nh = ($maxfontsize * (1-$this->baselineC)) - $font[$k]['textparam']['text-baseline'] + ($font[$k]['size'] * $this->baselineC);
5040 if ($lhfixed && $nh > $def_fontsize) { $this->forceExactLineheight = false; }
5041 $bf = max($bf, ($nh-$maxfontsize));
5042 }
5043 }
5044 }
5045 if ((!$lhfixed || !$this->forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
5046 $maxlineHeight = $maxfontsize + $af + $bf;
5047 }
5048 else if (!$lhfixed) { $af = $bf = ($maxlineHeight - $maxfontsize)/2; }
5049 if ($mta > $maxlineHeight) {
5050 $bf += ($mta - $maxlineHeight);
5051 $maxlineHeight = $mta;
5052 }
5053 if ($mba > $maxlineHeight) {
5054 $af += ($mba - $maxlineHeight);
5055 $maxlineHeight = $mba;
5056 }
5057
5058 $lineHeight = $maxlineHeight;
5059 // If NOT images, and maxfontsize NOT > lineHeight - this value determines text baseline positioning
5060 if ($lhfixed && $af==0 && $bf==0 && $maxfontsize<=($def_fontsize * $this->lineheight_correction * 0.8 )) {
5061 $this->linemaxfontsize = $def_fontsize;
5062 }
5063 else { $this->linemaxfontsize = $maxfontsize; }
5064
5065 // Get PAGEBREAK TO TEST for height including the bottom border/padding
5066 $check_h = max($this->divheight,$lineHeight);
5067
5068 // This fixes a proven bug...
5069 if ($endofblock && $newblock && $blockstate==0 && !$content) { $check_h = 0; }
5070 // but ? needs to fix potentially more widespread...
5071 // if (!$content) { $check_h = 0; }
5072
5073 if ($this->blklvl > 0 && !$is_table) {
5074 if ($endofblock && $blockstate > 1) {
5075 if ($this->blk[$this->blklvl]['page_break_after_avoid']) { $check_h += $lineHeight; }
5076 $check_h += ($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
5077 }
5078 // mPDF 5.4.03
5079 if (($newblock && ($blockstate==1 || $blockstate==3) && $lineCount == 0) || ($endofblock && $blockstate ==3 && $lineCount == 0)) {
5080 $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
5081 }
5082 }
5083
5084 // Force PAGE break if column height cannot take check-height
5085 if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) {
5086 $this->SetCol($this->NbCol-1);
5087 }
5088
5089 // mPDF 5.4.04
5090 // Avoid just border/background-color moved on to next page
5091 if ($endofblock && $blockstate > 1 && !$content) { $buff = $this->margBuffer; }
5092 else { $buff = 0; }
5093
5094
5095 // PAGEBREAK
5096 // mPDF 5.4.04
5097 if(!$is_table && ($this->y+$check_h) > ($this->PageBreakTrigger + $buff) and !$this->InFooter and $this->AcceptPageBreak()) {
5098 $bak_x=$this->x;//Current X position
5099 // WORD SPACING
5100 $ws=$this->ws;//Word Spacing
5101 $charspacing=$this->charspacing;//Character Spacing
5102 $this->ResetSpacing();
5103
5104 $this->AddPage($this->CurOrientation);
5105
5106 $this->x=$bak_x;
5107 // Added to correct for OddEven Margins
5108 $currentx += $this->MarginCorrection;
5109 $this->x += $this->MarginCorrection;
5110
5111 // WORD SPACING
5112 $this->SetSpacing($charspacing,$ws);
5113 }
5114
5115 if ($this->keep_block_together && !$is_table && $this->kt_p00 < $this->page && ($this->y+$check_h) > $this->kt_y00) {
5116 $this->printdivbuffer();
5117 $this->keep_block_together = 0;
5118 }
5119
5120 /*-- COLUMNS --*/
5121 // COLS
5122 // COLUMN CHANGE
5123 if ($this->CurrCol != $oldcolumn) {
5124 $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
5125 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
5126 $oldcolumn = $this->CurrCol;
5127 }
5128
5129
5130 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; }
5131 /*-- END COLUMNS --*/
5132
5133 // TOP MARGIN
5134 if ($newblock && ($blockstate==1 || $blockstate==3) && ($this->blk[$this->blklvl]['margin_top']) && $lineCount == 0 && !$is_table && !$is_list) {
5135 $this->DivLn($this->blk[$this->blklvl]['margin_top'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
5136 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5137 }
5138
5139 if ($newblock && ($blockstate==1 || $blockstate==3) && $lineCount == 0 && !$is_table && !$is_list) {
5140 $this->blk[$this->blklvl]['y0'] = $this->y;
5141 $this->blk[$this->blklvl]['startpage'] = $this->page;
5142 if ($this->blk[$this->blklvl]['float']) { $this->blk[$this->blklvl]['float_start_y'] = $this->y; } // mPDF 5.6.63
5143 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5144 }
5145
5146 // Paragraph INDENT
5147 $WidthCorrection = 0;
5148 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align != 'C')) {
5149 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->blk[$this->blklvl]['InlineProperties']['size'],false);
5150 $WidthCorrection = ($ti*_MPDFK);
5151 }
5152
5153
5154 // PADDING and BORDER spacing/fill
5155 if (($newblock) && ($blockstate==1 || $blockstate==3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 0) && (!$is_table) && (!$is_list)) {
5156 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
5157 $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'],-3,true,false,1);
5158 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5159 $this->x = $currentx;
5160 }
5161
5162
5163 // Added mPDF 3.0 Float DIV
5164 $fpaddingR = 0;
5165 $fpaddingL = 0;
5166 /*-- CSS-FLOAT --*/
5167 if (count($this->floatDivs)) {
5168 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
5169 if ($r_exists) { $fpaddingR = $r_width; }
5170 if ($l_exists) { $fpaddingL = $l_width; }
5171 }
5172 /*-- END CSS-FLOAT --*/
5173
5174 $usey = $this->y + 0.002;
5175 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
5176 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
5177 }
5178 /*-- CSS-IMAGE-FLOAT --*/
5179 // If float exists at this level
5180 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
5181 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
5182 /*-- END CSS-IMAGE-FLOAT --*/
5183
5184 if ($content) {
5185
5186 // In FinishFlowing Block no lines are justified as it is always last line
5187 // but if CJKorphan has allowed content width to go over max width, use J charspacing to compress line
5188 // JUSTIFICATION J - NOT!
5189 $nb_carac = 0;
5190 $nb_spaces = 0;
5191 $jcharspacing = 0;
5192 $jws = 0;
5193 $inclCursive=false;
5194 $dottab = false; // mPDF 5.6.19
5195 foreach ( $content as $k => $chunk ) {
5196 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
5197 if ($this->usingCoreFont) {
5198 $chunk = str_replace(chr(160),chr(32),$chunk );
5199 }
5200 else {
5201 $chunk = str_replace(chr(194).chr(160),chr(32),$chunk );
5202 }
5203 $nb_carac += mb_strlen( $chunk, $this->mb_enc );
5204 $nb_spaces += mb_substr_count( $chunk,' ', $this->mb_enc );
5205 if ($checkCursive) {
5206 if (preg_match("/([".$this->pregRTLchars."])/u", $chunk)) { $inclCursive = true; } // *RTL*
5207 if (preg_match("/([".$this->pregHIchars.$this->pregBNchars.$this->pregPAchars."])/u", $chunk)) { $inclCursive = true; } // *INDIC*
5208 }
5209 }
5210 else if ($this->objectbuffer[$k]['type']=='dottab') { $dottab = $this->objectbuffer[$k]['outdent']; } // mPDF 5.6.19
5211 }
5212 // 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)
5213 // If "orphans" in fact is just a final space - ignore this
5214 // mPDF 5.6.40
5215 $lastchar = mb_substr($content[(count($content)-1)],mb_strlen($content[(count($content)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
5216 if (preg_match("/[".$this->CJKoverflow."]/u", $lastchar)) { $CJKoverflow = true; }
5217 else {$CJKoverflow = false; }
5218 if ((((($contentWidth + $lastitalic) > $maxWidth) && ($content[count($content)-1] != ' ') ) ||
5219 (!$endofblock && $align=='J' && ($next=='image' || $next=='select' || $next=='input' || $next=='textarea' || ($next=='br' && $this->justifyB4br)))) && !($CJKoverflow && $this->allowCJKoverflow) ) { // mPDF 5.6.40
5220 // WORD SPACING
5221 list($jcharspacing,$jws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$contentWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*_MPDFK)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) )),$inclCursive);
5222 }
5223 /*-- CJK-FONTS --*/
5224 // mPDF 5.6.40
5225 else if ($this->checkCJK && $align=='J' && $CJKoverflow && $this->allowCJKoverflow && $this->CJKforceend) {
5226 // force-end overhang
5227 $hanger = mb_substr($content[count($content)-1],mb_strlen($content[count($content)-1],$this->mb_enc)-1,1,$this->mb_enc );
5228 if (preg_match("/[".$this->CJKoverflow."]/u", $hanger)) {
5229 $content[count($content)-1] = mb_substr($content[count($content)-1],0,mb_strlen($content[count($content)-1],$this->mb_enc)-1,$this->mb_enc );
5230 $this->restoreFont( $font[ count($content)-1 ],false );
5231 $contentWidth -= $this->GetStringWidth($hanger) * _MPDFK;
5232 $nb_carac -= 1;
5233 list($jcharspacing,$jws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$contentWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*_MPDFK)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) )),$inclCursive);
5234 }
5235 }
5236 /*-- END CJK-FONTS --*/
5237
5238 // Check if will fit at word/char spacing of previous line - if so continue it
5239 // but only allow a maximum of $this->jSmaxWordLast and $this->jSmaxCharLast
5240 else if ($contentWidth < ($maxWidth - $lastitalic-$WidthCorrection - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK))) && !$this->fixedlSpacing) {
5241 if ($this->ws > $this->jSmaxWordLast) {
5242 $jws = $this->jSmaxWordLast;
5243 }
5244 if ($this->charspacing > $this->jSmaxCharLast) {
5245 $jcharspacing = $this->jSmaxCharLast;
5246 }
5247 $check = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) ) - ( $jcharspacing * $nb_carac) - ( $jws * $nb_spaces);
5248 if ($check <= 0) {
5249 $jcharspacing = 0;
5250 $jws = 0;
5251 }
5252 }
5253
5254 $empty = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
5255
5256 $empty -= ($jcharspacing * $nb_carac);
5257 $empty -= ($jws * $nb_spaces);
5258
5259 $empty /= _MPDFK;
5260
5261 if (!$is_table) {
5262 $this->maxPosR = max($this->maxPosR , ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin'] - $empty));
5263 $this->maxPosL = min($this->maxPosL , ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $empty));
5264 }
5265
5266 $arraysize = count($content);
5267
5268 $margins = ($this->cMarginL+$this->cMarginR) + ($ipaddingL+$ipaddingR + $fpaddingR + $fpaddingR );
5269
5270 if (!$is_table) { $this->DivLn($lineHeight,$this->blklvl,false); } // false -> don't advance y
5271
5272 // DIRECTIONALITY RTL
5273 $all_rtl = false;
5274 $contains_rtl = false;
5275 /*-- RTL --*/
5276 if ($blockdir == 'rtl' || $this->biDirectional) {
5277 $all_rtl = true;
5278 foreach ( $content as $k => $chunk ) {
5279 $reversed = $this->magic_reverse_dir($chunk, false, $blockdir);
5280 if ($reversed > 0) { $contains_rtl = true; }
5281 if ($reversed < 2) { $all_rtl = false; }
5282 $content[$k] = $chunk;
5283 }
5284 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) {
5285 $content = array_reverse($content,false);
5286 $contentB = array_reverse($contentB,false);
5287 }
5288 }
5289 /*-- END RTL --*/
5290
5291 $this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL;
5292 if ($dottab !== false && $blockdir=='rtl') { $this->x -= $dottab; } // mPDF 5.6.19
5293 else if ($align == 'R') { $this->x += $empty; }
5294 else if ($align == 'J' && $blockdir == 'rtl') { $this->x += $empty; }
5295 else if ($align == 'C') { $this->x += ($empty / 2); }
5296
5297 // Paragraph INDENT
5298 $WidthCorrection = 0;
5299 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align !='C')) {
5300 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->blk[$this->blklvl]['InlineProperties']['size'],false);
5301 $this->x += $ti;
5302 }
5303
5304
5305 foreach ( $content as $k => $chunk )
5306 {
5307
5308 // FOR IMAGES
5309 if ((($blockdir == 'rtl') && ($contains_rtl )) || $all_rtl ) { $dirk = $arraysize-1 - $k; } else { $dirk = $k; }
5310
5311 $va = 'M'; // default for text
5312 if (isset($this->objectbuffer[$dirk]) && $this->objectbuffer[$dirk]) {
5313 $xadj = $this->x - $this->objectbuffer[$dirk]['OUTER-X'];
5314 $this->objectbuffer[$dirk]['OUTER-X'] += $xadj;
5315 $this->objectbuffer[$dirk]['BORDER-X'] += $xadj;
5316 $this->objectbuffer[$dirk]['INNER-X'] += $xadj;
5317 $va = $this->objectbuffer[$dirk]['vertical-align'];
5318 $yadj = $this->y - $this->objectbuffer[$dirk]['OUTER-Y'];
5319 if ($va == 'BS') {
5320 $yadj += $af + ($this->linemaxfontsize * (0.5 + $this->baselineC)) - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
5321 }
5322 else if ($va == 'M' || $va == '') {
5323 $yadj += $af + ($this->linemaxfontsize /2) - ($this->objectbuffer[$dirk]['OUTER-HEIGHT']/2);
5324 }
5325 else if ($va == 'TB') {
5326 $yadj += $af + $this->linemaxfontsize - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
5327 }
5328 else if ($va == 'TT') {
5329 $yadj += $af;
5330 }
5331 else if ($va == 'B') {
5332 $yadj += $af + $this->linemaxfontsize + $bf - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
5333 }
5334 else if ($va == 'T') {
5335 $yadj += 0;
5336 }
5337 $this->objectbuffer[$dirk]['OUTER-Y'] += $yadj;
5338 $this->objectbuffer[$dirk]['BORDER-Y'] += $yadj;
5339 $this->objectbuffer[$dirk]['INNER-Y'] += $yadj;
5340 }
5341
5342
5343 // DIRECTIONALITY RTL
5344 if ((($blockdir == 'rtl') && ($contains_rtl )) || $all_rtl ) { $this->restoreFont( $font[ $arraysize-1 - $k ] ); }
5345 else { $this->restoreFont( $font[ $k ] ); }
5346
5347 // mPDF 5.6.13 Decimal alignment - set in _tableWrite
5348 if ($is_table && substr($align,0,1)=='D' && $k==0 ) {
5349 $dp = $this->decimal_align[substr($align,0,2)];
5350 $s = preg_split('/'.preg_quote($dp,'/').'/', $content[0], 2); // ? needs to be /u if not core
5351 $s0 = $this->GetStringWidth($s[0], false);
5352 $this->x += ($this->decimal_offset - $s0);
5353 }
5354
5355 $this->SetSpacing(($this->fixedlSpacing*_MPDFK)+$jcharspacing,($this->fixedlSpacing+$this->minwSpacing)*_MPDFK+$jws);
5356 $this->fixedlSpacing = false;
5357 $this->minwSpacing = 0;
5358
5359 // mPDF 5.6.26
5360 $save_vis = $this->visibility;
5361 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->textparam['visibility'] != $this->visibility) {
5362 $this->SetVisibility($this->textparam['visibility']);
5363 }
5364
5365 // *********** SPAN BACKGROUND COLOR ***************** //
5366 if (isset($this->spanbgcolor) && $this->spanbgcolor) {
5367 $cor = $this->spanbgcolorarray;
5368 $this->SetFColor($cor);
5369 $save_fill = $fill; $spanfill = 1; $fill = 1;
5370 }
5371 if (!empty($this->spanborddet)) {
5372 if (strpos($contentB[$k],'L')!==false && isset($this->spanborddet['L'])) $this->x += $this->spanborddet['L']['w'];
5373 if (strpos($contentB[$k],'L')===false) $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0;
5374 if (strpos($contentB[$k],'R')===false) $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0;
5375 }
5376 // WORD SPACING
5377 $stringWidth = $this->GetStringWidth($chunk ) + ( $this->charspacing * mb_strlen($chunk,$this->mb_enc ) / _MPDFK )
5378 + ( $this->ws * mb_substr_count($chunk,' ',$this->mb_enc ) / _MPDFK );
5379 if (isset($this->objectbuffer[$dirk])) {
5380 if ($this->objectbuffer[$dirk]['type']=='dottab') {
5381 $this->objectbuffer[$dirk]['OUTER-WIDTH'] +=$empty;
5382 $this->objectbuffer[$dirk]['OUTER-WIDTH'] +=$this->objectbuffer[$dirk]['outdent']; // mPDF 5.6.19
5383 }
5384 $stringWidth = $this->objectbuffer[$dirk]['OUTER-WIDTH'];
5385 }
5386
5387 if ($stringWidth==0) { $stringWidth = 0.000001; }
5388 if ($k == $arraysize-1) {
5389 // mPDF 5.6.40
5390 if ($this->checkCJK && $CJKoverflow && $align=='J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) {
5391 // force-end overhang
5392 $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
5393 $this->Cell( $this->GetStringWidth($hanger), $lineHeight, $hanger, '', 1, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
5394 }
5395 else {
5396 $this->Cell( $stringWidth, $lineHeight, $chunk, '', 1, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
5397 }
5398 }
5399 else $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, 0, 0,0,'M', $fill, $af, $bf, true );//first or middle part
5400
5401
5402 if (!empty($this->spanborddet)) {
5403 if (strpos($contentB[$k],'R')!==false && $k != $arraysize-1) $this->x += $this->spanborddet['R']['w'];
5404 }
5405 // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
5406 if (isset($spanfill) && $spanfill) {
5407 $fill = $save_fill; $spanfill = 0;
5408 if ($fill) { $this->SetFColor($bcor); }
5409 }
5410 // mPDF 5.6.26
5411 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->visibility != $save_vis) {
5412 $this->SetVisibility($save_vis);
5413 }
5414
5415 }
5416
5417 $this->printobjectbuffer($is_table, $blockdir);
5418
5419 $this->objectbuffer = array();
5420
5421 $this->ResetSpacing();
5422
5423 /*-- LISTS --*/
5424 // LIST BULLETS/NUMBERS
5425 if ($is_list && is_array($this->bulletarray) && ($lineCount == 0) ) {
5426
5427 $savedFont = $this->saveFont();
5428
5429 $bull = $this->bulletarray;
5430 if (isset($bull['level']) && isset($bull['occur']) && isset($this->InlineProperties['LIST'][$bull['level']][$bull['occur']])) {
5431 $this->restoreInlineProperties($this->InlineProperties['LIST'][$bull['level']][$bull['occur']]);
5432 }
5433 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']]); }
5434 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
5435 $this->bullet = true;
5436 $this->SetFont('czapfdingbats','',$this->FontSizePt/2.5);
5437 }
5438 else { $this->SetFont($this->FontFamily,$this->FontStyle,$this->FontSizePt,true,true); } // force output
5439 //Output bullet
5440 $this->x = $currentx;
5441 if (isset($bull['x'])) { $this->x += $bull['x']; }
5442 $this->y -= $lineHeight;
5443 if (isset($bull['col']) && $bull['col']) { $this->SetTColor($bull['col']); } // mPDF 5.6.67
5444
5445 if (isset($bull['txt'])) { $this->Cell($bull['w'], $lineHeight,$bull['txt'],'','',$bull['align'],0,'',0,-$this->cMarginL, -$this->cMarginR ); }
5446 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
5447 $this->bullet = false;
5448 }
5449 $this->x = $currentx; // Reset
5450 $this->y += $lineHeight;
5451
5452 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5453
5454 $this->restoreFont( $savedFont );
5455 // $font = array( $savedFont );
5456
5457 $this->bulletarray = array(); // prevents repeat of bullet/number if <li>....<br />.....</li>
5458 }
5459 /*-- END LISTS --*/
5460
5461
5462 } // END IF CONTENT
5463
5464 /*-- CSS-IMAGE-FLOAT --*/
5465 // Update values if set to skipline
5466 if ($this->floatmargins) { $this->_advanceFloatMargins(); }
5467
5468
5469 if ($endofblock && $blockstate>1) {
5470 // If float exists at this level
5471 if (isset($this->floatmargins['R']['y1'])) { $fry1 = $this->floatmargins['R']['y1']; }
5472 else { $fry1 = 0; }
5473 if (isset($this->floatmargins['L']['y1'])) { $fly1 = $this->floatmargins['L']['y1']; }
5474 else { $fly1 = 0; }
5475 if ($this->y < $fry1 || $this->y < $fly1) {
5476 $drop = max($fry1,$fly1) - $this->y;
5477 $this->DivLn($drop);
5478 $this->x = $currentx;
5479 }
5480 }
5481 /*-- END CSS-IMAGE-FLOAT --*/
5482
5483
5484 // PADDING and BORDER spacing/fill
5485 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)) {
5486 // If CSS height set, extend bottom - if on same page as block started, and CSS HEIGHT > actual height,
5487 // and does not force pagebreak
5488 $extra = 0;
5489 if ($this->blk[$this->blklvl]['css_set_height'] && $this->blk[$this->blklvl]['startpage']==$this->page) {
5490 // predicted height
5491 $h1 = ($this->y-$this->blk[$this->blklvl]['y0']) + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'];
5492 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; }
5493 if($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra > $this->PageBreakTrigger) {
5494 $extra = $this->PageBreakTrigger - ($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
5495 }
5496 }
5497
5498 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
5499 $this->DivLn($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra,-3,true,false,2);
5500 $this->x = $currentx;
5501
5502 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5503
5504 }
5505
5506 // SET Bottom y1 of block (used for painting borders)
5507 if (($endofblock) && ($blockstate > 1) && (!$is_table) && (!$is_list)) {
5508 $this->blk[$this->blklvl]['y1'] = $this->y;
5509 }
5510
5511 // BOTTOM MARGIN
5512 if (($endofblock) && ($blockstate > 1) && ($this->blk[$this->blklvl]['margin_bottom']) && (!$is_table) && (!$is_list)) {
5513 if($this->y+$this->blk[$this->blklvl]['margin_bottom'] < $this->PageBreakTrigger and !$this->InFooter) {
5514 $this->DivLn($this->blk[$this->blklvl]['margin_bottom'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
5515 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5516 }
5517 }
5518
5519 // Reset lineheight
5520 $lineHeight = $this->divheight;
5521 }
5522
5523
5524
5525
5526
5527 function printobjectbuffer($is_table=false, $blockdir=false) {
5528 if (!$blockdir) { $blockdir = $this->directionality; }
5529 if ($is_table && $this->shrin_k > 1) { $k = $this->shrin_k; }
5530 else { $k = 1; }
5531 $save_y = $this->y;
5532 $save_x = $this->x;
5533 $save_currentfontfamily = $this->FontFamily;
5534 $save_currentfontsize = $this->FontSizePt;
5535 $save_currentfontstyle = $this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
5536 if ($blockdir == 'rtl') { $rtlalign = 'R'; } else { $rtlalign = 'L'; }
5537 foreach ($this->objectbuffer AS $ib => $objattr) {
5538 if ($objattr['type'] == 'bookmark' || $objattr['type'] == 'indexentry' || $objattr['type'] == 'toc') {
5539 $x = $objattr['OUTER-X'];
5540 $y = $objattr['OUTER-Y'];
5541 $this->y = $y - $this->FontSize/2;
5542 $this->x = $x;
5543 if ($objattr['type'] == 'bookmark' ) { $this->Bookmark($objattr['CONTENT'],$objattr['bklevel'] ,$y - $this->FontSize); } // *BOOKMARKS*
5544 if ($objattr['type'] == 'indexentry') { $this->IndexEntry($objattr['CONTENT']); } // *INDEX*
5545 if ($objattr['type'] == 'toc') { $this->TOC_Entry($objattr['CONTENT'], $objattr['toclevel'], $objattr['toc_id']); } // *TOC*
5546 }
5547 /*-- ANNOTATIONS --*/
5548 else if ($objattr['type'] == 'annot') {
5549 if ($objattr['POS-X']) { $x = $objattr['POS-X']; }
5550 else if ($this->annotMargin<>0) { $x = -$objattr['OUTER-X']; }
5551 else { $x = $objattr['OUTER-X']; }
5552 if ($objattr['POS-Y']) { $y = $objattr['POS-Y']; }
5553 else { $y = $objattr['OUTER-Y'] - $this->FontSize/2; }
5554 // Create a dummy entry in the _out/columnBuffer with position sensitive data,
5555 // linking $y-1 in the Columnbuffer with entry in $this->columnAnnots
5556 // and when columns are split in length will not break annotation from current line
5557 $this->y = $y-1;
5558 $this->x = $x-1;
5559 $this->Line($x-1,$y-1,$x-1,$y-1);
5560 $this->Annotation($objattr['CONTENT'], $x , $y , $objattr['ICON'], $objattr['AUTHOR'], $objattr['SUBJECT'], $objattr['OPACITY'], $objattr['COLOR'], $objattr['POPUP'], $objattr['FILE']);
5561 }
5562 /*-- END ANNOTATIONS --*/
5563 else {
5564 $y = $objattr['OUTER-Y'];
5565 $x = $objattr['OUTER-X'];
5566 $w = $objattr['OUTER-WIDTH'];
5567 $h = $objattr['OUTER-HEIGHT'];
5568 if (isset($objattr['text'])) { $texto = $objattr['text']; }
5569 $this->y = $y;
5570 $this->x = $x;
5571 if (isset($objattr['fontfamily'])) { $this->SetFont($objattr['fontfamily'],'',$objattr['fontsize'] ); }
5572 }
5573
5574 // HR
5575 if ($objattr['type'] == 'hr') {
5576 $this->SetDColor($objattr['color']);
5577 switch($objattr['align']) {
5578 case 'C':
5579 $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
5580 $empty /= 2;
5581 $x += $empty;
5582 break;
5583 case 'R':
5584 $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
5585 $x += $empty;
5586 break;
5587 }
5588 $oldlinewidth = $this->LineWidth;
5589 $this->SetLineWidth($objattr['linewidth']/$k );
5590 $this->y += ($objattr['linewidth']/2) + $objattr['margin_top']/$k;
5591 $this->Line($x,$this->y,$x+$objattr['INNER-WIDTH'],$this->y);
5592 $this->SetLineWidth($oldlinewidth);
5593 $this->SetDColor($this->ConvertColor(0));
5594 }
5595 // IMAGE
5596 if ($objattr['type'] == 'image') {
5597 // mPDF 5.7.3 TRANSFORMS
5598 if (isset($objattr['transform'])) {
5599 $this->_out("\n".'% BTR'); // Begin Transform
5600 }
5601 if (isset($objattr['z-index']) && $objattr['z-index'] > 0 && $this->currentlayer==0) {
5602 $this->BeginLayer($objattr['z-index']);
5603 }
5604 if(isset($objattr['visibility']) && $objattr['visibility']!='visible' && $objattr['visibility']) {
5605 $this->SetVisibility($objattr['visibility']);
5606 }
5607 if (isset($objattr['opacity'])) { $this->SetAlpha($objattr['opacity']); }
5608 $rotate = 0;
5609 $obiw = $objattr['INNER-WIDTH'];
5610 $obih = $objattr['INNER-HEIGHT'];
5611 $sx = $objattr['INNER-WIDTH']*_MPDFK / $objattr['orig_w'];
5612 $sy = abs($objattr['INNER-HEIGHT'])*_MPDFK / abs($objattr['orig_h']);
5613 $sx = ($objattr['INNER-WIDTH']*_MPDFK / $objattr['orig_w']);
5614 $sy = ($objattr['INNER-HEIGHT']*_MPDFK / $objattr['orig_h']);
5615
5616 if (isset($objattr['ROTATE'])) { $rotate = $objattr['ROTATE']; }
5617 if ($rotate==90) {
5618 // Clockwise
5619 $obiw = $objattr['INNER-HEIGHT'];
5620 $obih = $objattr['INNER-WIDTH'];
5621 $tr = $this->transformTranslate(0, -$objattr['INNER-WIDTH'], true) ;
5622 $tr .= ' '. $this->transformRotate(90, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-WIDTH'] ),true) ;
5623 $sx = $obiw*_MPDFK / $objattr['orig_h'];
5624 $sy = $obih*_MPDFK / $objattr['orig_w'];
5625 }
5626 else if ($rotate==-90 || $rotate==270) {
5627 // AntiClockwise
5628 $obiw = $objattr['INNER-HEIGHT'];
5629 $obih = $objattr['INNER-WIDTH'];
5630 $tr = $this->transformTranslate($objattr['INNER-WIDTH'], ($objattr['INNER-HEIGHT']-$objattr['INNER-WIDTH']), true) ;
5631 $tr .= ' '. $this->transformRotate(-90, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-WIDTH'] ),true) ;
5632 $sx = $obiw*_MPDFK / $objattr['orig_h'];
5633 $sy = $obih*_MPDFK / $objattr['orig_w'];
5634 }
5635 else if ($rotate==180) {
5636 // Mirror
5637 $tr = $this->transformTranslate($objattr['INNER-WIDTH'], -$objattr['INNER-HEIGHT'], true) ;
5638 $tr .= ' '. $this->transformRotate(180, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-HEIGHT'] ),true) ;
5639 }
5640 else { $tr = ''; }
5641 $tr = trim($tr);
5642 if ($tr) { $tr .= ' '; }
5643 $gradmask = '';
5644
5645 // mPDF 5.7.3 TRANSFORMS
5646 $tr2 = '';
5647 if (isset($objattr['transform'])) {
5648 $maxsize_x = $w;
5649 $maxsize_y = $h;
5650 $cx = $x + $w/2;
5651 $cy = $y + $h/2;
5652 preg_match_all('/(translatex|translatey|translate|scalex|scaley|scale|rotate|skewX|skewY|skew)\((.*?)\)/is',$objattr['transform'],$m);
5653 if (count($m[0])) {
5654 for($i=0; $i<count($m[0]); $i++) {
5655 $c = strtolower($m[1][$i]);
5656 $v = trim($m[2][$i]);
5657 $vv = preg_split('/[ ,]+/',$v);
5658 if ($c=='translate' && count($vv)) {
5659 $translate_x = $this->ConvertSize($vv[0],$maxsize_x,false,false);
5660 if (count($vv)==2) { $translate_y = $this->ConvertSize($vv[1],$maxsize_y,false,false); }
5661 else { $translate_y = 0; }
5662 $tr2 .= $this->transformTranslate($translate_x, $translate_y, true).' ';
5663 }
5664 else if ($c=='translatex' && count($vv)) {
5665 $translate_x = $this->ConvertSize($vv[0],$maxsize_x,false,false);
5666 $tr2 .= $this->transformTranslate($translate_x, 0, true).' ';
5667 }
5668 else if ($c=='translatey' && count($vv)) {
5669 $translate_y = $this->ConvertSize($vv[1],$maxsize_y,false,false);
5670 $tr2 .= $this->transformTranslate(0, $translate_y, true).' ';
5671 }
5672 else if ($c=='scale' && count($vv)) {
5673 $scale_x = $vv[0] * 100;
5674 if (count($vv)==2) { $scale_y = $vv[1] * 100; }
5675 else { $scale_y = $scale_x; }
5676 $tr2 .= $this->transformScale($scale_x, $scale_y, $cx, $cy, true).' ';
5677 }
5678 else if ($c=='scalex' && count($vv)) {
5679 $scale_x = $vv[0] * 100;
5680 $tr2 .= $this->transformScale($scale_x, 0, $cx, $cy, true).' ';
5681 }
5682 else if ($c=='scaley' && count($vv)) {
5683 $scale_y = $vv[1] * 100;
5684 $tr2 .= $this->transformScale(0, $scale_y, $cx, $cy, true).' ';
5685 }
5686 else if ($c=='skew' && count($vv)) {
5687 $angle_x = $this->ConvertAngle($vv[0], false);
5688 if (count($vv)==2) { $angle_y = $this->ConvertAngle($vv[1], false); }
5689 else { $angle_y = 0; }
5690 $tr2 .= $this->transformSkew($angle_x, $angle_y, $cx, $cy, true).' ';
5691 }
5692 else if ($c=='skewx' && count($vv)) {
5693 $angle = $this->ConvertAngle($vv[0], false);
5694 $tr2 .= $this->transformSkew($angle, 0, $cx, $cy, true).' ';
5695 }
5696 else if ($c=='skewy' && count($vv)) {
5697 $angle = $this->ConvertAngle($vv[0], false);
5698 $tr2 .= $this->transformSkew(0, $angle, $cx, $cy, true).' ';
5699 }
5700 else if ($c=='rotate' && count($vv)) {
5701 $angle = $this->ConvertAngle($vv[0]);
5702 $tr2 .= $this->transformRotate($angle, $cx, $cy, true).' ';
5703 }
5704 }
5705 }
5706 }
5707 // mPDF 5.7.3 TRANSFORMS / BACKGROUND COLOR
5708 // Transform also affects image background
5709 if ($tr2) { $this->_out('q '.$tr2.' '); }
5710 if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
5711 $bgcol = $objattr['bgcolor'];
5712 $this->SetFColor($bgcol);
5713 $this->Rect($x,$y,$w,$h, 'F');
5714 $this->SetFColor($this->ConvertColor(255));
5715 }
5716 if ($tr2) { $this->_out('Q'); }
5717
5718 /*-- BACKGROUNDS --*/
5719 if (isset($objattr['GRADIENT-MASK'])) {
5720 $g = $this->grad->parseMozGradient( $objattr['GRADIENT-MASK'] );
5721 if ($g) {
5722 $dummy = $this->grad->Gradient($objattr['INNER-X'], $objattr['INNER-Y'], $obiw, $obih, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true, true);
5723 $gradmask = '/TGS'.count($this->gradients).' gs ';
5724 // $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");
5725 }
5726 }
5727 /*-- END BACKGROUNDS --*/
5728 /*-- IMAGES-WMF --*/
5729 if (isset($objattr['itype']) && $objattr['itype']=='wmf') {
5730 $outstring = sprintf('q '.$tr.$tr2.'%.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']); // mPDF 5.7.3 TRANSFORMS
5731 }
5732 else
5733 /*-- END IMAGES-WMF --*/
5734 if (isset($objattr['itype']) && $objattr['itype']=='svg') {
5735 $outstring = sprintf('q '.$tr.$tr2.'%.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']); // mPDF 5.7.3 TRANSFORMS
5736 }
5737 else {
5738 $outstring = sprintf("q ".$tr.$tr2."%.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'] ); // mPDF 5.7.3 TRANSFORMS
5739 }
5740 $this->_out($outstring);
5741 // LINK
5742 if (isset($objattr['link'])) $this->Link($objattr['INNER-X'],$objattr['INNER-Y'],$objattr['INNER-WIDTH'],$objattr['INNER-HEIGHT'],$objattr['link']);
5743 if (isset($objattr['opacity'])) { $this->SetAlpha(1); }
5744
5745 // mPDF 5.7.3 TRANSFORMS
5746 // Transform also affects image borders
5747 if ($tr2) { $this->_out('q '.$tr2.' '); }
5748 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); }
5749 if ($tr2) { $this->_out('Q'); }
5750
5751 if(isset($objattr['visibility']) && $objattr['visibility']!='visible' && $objattr['visibility']) {
5752 $this->SetVisibility('visible');
5753 }
5754 if (isset($objattr['z-index']) && $objattr['z-index'] > 0 && $this->currentlayer==0) {
5755 $this->EndLayer();
5756 }
5757 // mPDF 5.7.3 TRANSFORMS
5758 if (isset($objattr['transform'])) {
5759 $this->_out("\n".'% ETR'); // Begin Transform
5760 }
5761 }
5762
5763 /*-- BARCODES --*/
5764 // BARCODE
5765 if ($objattr['type'] == 'barcode') {
5766 $bgcol = $this->ConvertColor(255);
5767 if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
5768 $bgcol = $objattr['bgcolor'];
5769 }
5770 $col = $this->ConvertColor(0);
5771 if (isset($objattr['color']) && $objattr['color']) {
5772 $col = $objattr['color'];
5773 }
5774 $this->SetFColor($bgcol);
5775 $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F');
5776 $this->SetFColor($this->ConvertColor(255));
5777 if (isset($objattr['BORDER-WIDTH'])) { $this->PaintImgBorder($objattr,$is_table); }
5778 if ($objattr['btype'] == 'EAN13' || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN' || $objattr['btype'] == 'UPCA' || $objattr['btype'] == 'UPCE' || $objattr['btype'] == 'EAN8') {
5779 $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);
5780 }
5781 // QR-code
5782 else if ($objattr['btype']=='QR') {
5783 if (!class_exists('QRcode', false)) {
5784 include(_MPDF_PATH.'qrcode/qrcode.class.php');
5785 }
5786 $this->qrcode = new QRcode($objattr['code'], $objattr['errorlevel']);
5787 $this->qrcode->displayFPDF($this, $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize']*25, array(255,255,255), array(0,0,0));
5788 }
5789 else {
5790 $this->WriteBarcode2($objattr['code'], $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize'], $objattr['bheight'], $bgcol, $col, $objattr['btype'], $objattr['pr_ratio'], $k);
5791 }
5792 }
5793 /*-- END BARCODES --*/
5794
5795 // TEXT CIRCLE
5796 if ($objattr['type'] == 'textcircle') {
5797 $bgcol = ''; // mPDF 5.5.14
5798 if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
5799 $bgcol = $objattr['bgcolor'];
5800 }
5801 $col = $this->ConvertColor(0);
5802 if (isset($objattr['color']) && $objattr['color']) {
5803 $col = $objattr['color'];
5804 }
5805 $this->SetTColor($col);
5806 $this->SetFColor($bgcol);
5807 if ($bgcol) $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F'); // mPDF 5.5.14
5808 $this->SetFColor($this->ConvertColor(255));
5809 if (isset($objattr['BORDER-WIDTH'])) { $this->PaintImgBorder($objattr,$is_table); }
5810 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
5811 if (empty($this->directw)) { $this->directw = new directw($this); }
5812 $save_lmfs = $this->linemaxfontsize;
5813 $this->linemaxfontsize = 0;
5814 if (isset($objattr['top-text'])) {
5815 $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
5816 }
5817 if (isset($objattr['bottom-text'])) {
5818 $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
5819 }
5820 $this->linemaxfontsize = $save_lmfs;
5821 }
5822
5823 $this->ResetSpacing();
5824
5825 // DOT-TAB
5826 if ($objattr['type'] == 'dottab') {
5827 // mPDF 5.6.19
5828 if (isset($objattr['fontfamily'])) { $this->SetFont($objattr['fontfamily'],'',$objattr['fontsize'] ); }
5829 $sp = $this->GetStringWidth(' ');
5830 $nb=floor(($w-2*$sp)/$this->GetStringWidth('.'));
5831 if ($nb>0) { $dots=' '.str_repeat('.',$nb).' '; }
5832 else { $dots=' '; }
5833 $col = $this->ConvertColor(0);
5834 if (isset($objattr['colorarray']) && ($objattr['colorarray'])) { // mPDF 5.6.19
5835 $col = $objattr['colorarray'];
5836 }
5837 $this->SetTColor($col);
5838 $save_dh = $this->divheight; // mPDF 5.6.19
5839 $save_sbd = $this->spanborddet;
5840 $save_u = $this->U;
5841 $save_s = $this->strike;
5842 $this->spanborddet = '';
5843 $this->divheight = 0; // mPDF 5.6.19
5844 $this->U = false;
5845 $this->strike = false;
5846 $this->Cell($w,$h,$dots,0,0,'C');
5847 $this->spanborddet = $save_sbd;
5848 $this->U = $save_u;
5849 $this->strike = $save_s;
5850 $this->divheight = $save_dh; // mPDF 5.6.19
5851 // mPDF 5.0
5852 $this->SetTColor($this->ConvertColor(0));
5853 }
5854
5855 /*-- FORMS --*/
5856 // TEXT/PASSWORD INPUT
5857 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD')) {
5858 $this->form->print_ob_text($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5859 }
5860
5861 // TEXTAREA
5862 if ($objattr['type'] == 'textarea') {
5863 $this->form->print_ob_textarea($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5864 }
5865
5866 // SELECT
5867 if ($objattr['type'] == 'select') {
5868 $this->form->print_ob_select($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5869 }
5870
5871
5872 // INPUT/BUTTON as IMAGE
5873 if ($objattr['type'] == 'input' && $objattr['subtype'] == 'IMAGE') {
5874 $this->form->print_ob_imageinput($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5875 }
5876
5877 // BUTTON
5878 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'SUBMIT' || $objattr['subtype'] == 'RESET' || $objattr['subtype'] == 'BUTTON')) {
5879 $this->form->print_ob_button($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
5880 }
5881
5882 // CHECKBOX
5883 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'CHECKBOX')) {
5884 $this->form->print_ob_checkbox($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir,$x,$y);
5885 }
5886 // RADIO
5887 if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'RADIO')) {
5888 $this->form->print_ob_radio($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir,$x,$y);
5889 }
5890 /*-- END FORMS --*/
5891 }
5892 $this->SetFont($save_currentfontfamily,$save_currentfontstyle,$save_currentfontsize);
5893 $this->y = $save_y;
5894 $this->x = $save_x;
5895 unset($content);
5896 }
5897
5898
5899 function WriteFlowingBlock( $s)
5900 {
5901 $currentx = $this->x;
5902 $is_table = $this->flowingBlockAttr[ 'is_table' ];
5903 $is_list = $this->flowingBlockAttr[ 'is_list' ];
5904 // width of all the content so far in points
5905 $contentWidth =& $this->flowingBlockAttr[ 'contentWidth' ];
5906 // cell width in points
5907 $maxWidth =& $this->flowingBlockAttr[ 'width' ];
5908 $lineCount =& $this->flowingBlockAttr[ 'lineCount' ];
5909 // line height in user units
5910 $lineHeight =& $this->flowingBlockAttr[ 'height' ];
5911 $align =& $this->flowingBlockAttr[ 'align' ];
5912 $content =& $this->flowingBlockAttr[ 'content' ];
5913 $contentB =& $this->flowingBlockAttr[ 'contentB' ];
5914 $font =& $this->flowingBlockAttr[ 'font' ];
5915 $valign =& $this->flowingBlockAttr[ 'valign' ];
5916 $blockstate = $this->flowingBlockAttr[ 'blockstate' ];
5917
5918 $newblock = $this->flowingBlockAttr[ 'newblock' ];
5919 $blockdir = $this->flowingBlockAttr['blockdir'];
5920 // *********** BLOCK BACKGROUND COLOR ***************** //
5921 if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
5922 $fill = 0;
5923 }
5924 else {
5925 $this->SetFColor($this->ConvertColor(255));
5926 $fill = 0;
5927 }
5928 $font[] = $this->saveFont();
5929 $content[] = '';
5930 $contentB[] = '';
5931 $currContent =& $content[ count( $content ) - 1 ];
5932 // where the line should be cutoff if it is to be justified
5933 $cutoffWidth = $contentWidth;
5934
5935 $CJKoverflow = false;
5936 $hanger = ''; // mPDF 5.6.40
5937
5938 // COLS
5939 $oldcolumn = $this->CurrCol;
5940
5941 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
5942
5943 /*-- TABLES --*/
5944 if ($is_table) {
5945 $ipaddingL = 0;
5946 $ipaddingR = 0;
5947 $paddingL = 0;
5948 $paddingR = 0;
5949 $cpaddingadjustL = 0;
5950 $cpaddingadjustR = 0;
5951 // Added mPDF 3.0
5952 $fpaddingR = 0;
5953 $fpaddingL = 0;
5954 }
5955 else {
5956 /*-- END TABLES --*/
5957 $ipaddingL = $this->blk[$this->blklvl]['padding_left'];
5958 $ipaddingR = $this->blk[$this->blklvl]['padding_right'];
5959 $paddingL = ($ipaddingL * _MPDFK);
5960 $paddingR = ($ipaddingR * _MPDFK);
5961 $this->cMarginL = $this->blk[$this->blklvl]['border_left']['w'];
5962 $cpaddingadjustL = -$this->cMarginL;
5963 $this->cMarginR = $this->blk[$this->blklvl]['border_right']['w'];
5964 $cpaddingadjustR = -$this->cMarginR;
5965 // Added mPDF 3.0 Float DIV
5966 $fpaddingR = 0;
5967 $fpaddingL = 0;
5968 /*-- CSS-FLOAT --*/
5969 if (count($this->floatDivs)) {
5970 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
5971 if ($r_exists) { $fpaddingR = $r_width; }
5972 if ($l_exists) { $fpaddingL = $l_width; }
5973 }
5974 /*-- END CSS-FLOAT --*/
5975
5976 $usey = $this->y + 0.002;
5977 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
5978 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
5979 }
5980 /*-- CSS-IMAGE-FLOAT --*/
5981 // If float exists at this level
5982 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
5983 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
5984 /*-- END CSS-IMAGE-FLOAT --*/
5985 } // *TABLES*
5986
5987 //OBJECTS - IMAGES & FORM Elements (NB has already skipped line/page if required - in printbuffer)
5988 if (substr($s,0,3) == "\xbb\xa4\xac") { //identifier has been identified!
5989 $objattr = $this->_getObjAttr($s);
5990 $h_corr = 0;
5991 if ($is_table) { // *TABLES*
5992 $maximumW = ($maxWidth/_MPDFK) - ($this->cellPaddingL + $this->cMarginL + $this->cellPaddingR + $this->cMarginR); // *TABLES*
5993 } // *TABLES*
5994 else { // *TABLES*
5995 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']; }
5996 $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 );
5997 } // *TABLES*
5998 $objattr = $this->inlineObject($objattr['type'],$this->lMargin + $fpaddingL + ($contentWidth/_MPDFK),($this->y + $h_corr), $objattr, $this->lMargin,($contentWidth/_MPDFK),$maximumW,$lineHeight,true,$is_table);
5999
6000 // SET LINEHEIGHT for this line ================ RESET AT END
6001 $lineHeight = MAX($lineHeight,$objattr['OUTER-HEIGHT']);
6002 $this->objectbuffer[count($content)-1] = $objattr;
6003 // if (isset($objattr['vertical-align'])) { $valign = $objattr['vertical-align']; }
6004 // else { $valign = ''; }
6005 $contentWidth += ($objattr['OUTER-WIDTH'] * _MPDFK);
6006 return;
6007 }
6008
6009 $lbw = $rbw = 0; // Border widths
6010 if (!empty($this->spanborddet)) {
6011 if (isset($this->spanborddet['L'])) $lbw = $this->spanborddet['L']['w'];
6012 if (isset($this->spanborddet['R'])) $rbw = $this->spanborddet['R']['w'];
6013 }
6014
6015 if ($this->usingCoreFont) {
6016 $tmp = strlen( $s );
6017 }
6018 else {
6019 $tmp = mb_strlen( $s, $this->mb_enc );
6020 }
6021
6022 // for every character in the string
6023 for ( $i = 0; $i < $tmp; $i++ ) {
6024 // extract the current character
6025 // get the width of the character in points
6026 if ($this->usingCoreFont) {
6027 $c = $s[$i];
6028 // Soft Hyphens chr(173)
6029 $cw = ($this->GetCharWidthCore($c) * _MPDFK);
6030 if ($this->kerning && $this->useKerning && $i > 0) {
6031 if (isset($this->CurrentFont['kerninfo'][$s[($i-1)]][$c])) {
6032 $cw += ($this->CurrentFont['kerninfo'][$s[($i-1)]][$c] * $this->FontSizePt / 1000 );
6033 }
6034 }
6035 }
6036 else {
6037 $c = mb_substr($s,$i,1,$this->mb_enc );
6038 $cw = ($this->GetCharWidthNonCore($c, false) * _MPDFK);
6039 if ($this->kerning && $this->useKerning && $i > 0) {
6040 $lastc = mb_substr($s,($i-1),1,$this->mb_enc );
6041 $ulastc = $this->UTF8StringToArray($lastc, false);
6042 $uc = $this->UTF8StringToArray($c, false);
6043 if (isset($this->CurrentFont['kerninfo'][$ulastc[0]][$uc[0]])) {
6044 $cw += ($this->CurrentFont['kerninfo'][$ulastc[0]][$uc[0]] * $this->FontSizePt / 1000 );
6045 }
6046 }
6047 }
6048
6049 if ($i==0) {
6050 $cw += $lbw*_MPDFK;
6051 $contentB[(count($contentB)-1)] .= 'L';
6052 }
6053 if ($i==($tmp-1)) {
6054 $cw += $rbw*_MPDFK;
6055 $contentB[(count($contentB)-1)] .= 'R';
6056 }
6057 // mPDF 5.6.45
6058 if ($c==' ') {
6059 $currContent .= $c;
6060 $cutoffWidth = $contentWidth;
6061 $contentWidth += $cw;
6062 continue;
6063 }
6064
6065 // Paragraph INDENT
6066 $WidthCorrection = 0;
6067 if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && (!$is_list) && ($align != 'C')) {
6068 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->blk[$this->blklvl]['InlineProperties']['size'],false); // mPDF 5.7.4
6069 $WidthCorrection = ($ti*_MPDFK);
6070 }
6071
6072 // Added mPDF 3.0 Float DIV
6073 $fpaddingR = 0;
6074 $fpaddingL = 0;
6075 /*-- CSS-FLOAT --*/
6076 if (count($this->floatDivs)) {
6077 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
6078 if ($r_exists) { $fpaddingR = $r_width; }
6079 if ($l_exists) { $fpaddingL = $l_width; }
6080 }
6081 /*-- END CSS-FLOAT --*/
6082
6083 $usey = $this->y + 0.002;
6084 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
6085 $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
6086 }
6087
6088 /*-- CSS-IMAGE-FLOAT --*/
6089 // If float exists at this level
6090 if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
6091 if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
6092 /*-- END CSS-IMAGE-FLOAT --*/
6093
6094
6095
6096 // try adding another char
6097 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
6098 // it won't fit, output what we already have
6099 $lineCount++;
6100
6101 // contains any content that didn't make it into this print
6102 $savedContent = '';
6103 $savedContentB = '';
6104 $savedFont = array();
6105 $savedObj = array();
6106 // mPDF 5.6.20
6107 $savedPreContent = array();
6108 $savedPreContentB = array();
6109 $savedPreFont = array();
6110
6111 // cut off and save any partial words at the end of the string
6112 $words = explode( ' ', $currContent );
6113 ///////////////////
6114 // HYPHENATION
6115 $currWord = $words[count($words)-1] ;
6116 $success = false;
6117
6118 // mPDF 5.6.21 Hard Hyphens -
6119 $hardsuccess = false;
6120 if ($this->textparam['hyphens'] != 2 && preg_match("/\-/",$currWord)) {
6121 $rem = $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
6122 list($hardsuccess,$pre,$post,$prelength) = $this->hardHyphenate($currWord, (($rem-$cutoffWidth)/_MPDFK -$this->GetCharWidth("-", false)) );
6123 if ($hardsuccess) {
6124 $already = array_pop( $words );
6125 $forward = mb_substr($already,$prelength+1,mb_strlen($already, $this->mb_enc), $this->mb_enc);
6126 $words[] = $pre.'-';
6127 $words[] = $forward;
6128 $currContent = mb_substr($currContent,0,mb_strlen($currContent, $this->mb_enc)+1-mb_strlen($post, $this->mb_enc), $this->mb_enc) . '-';
6129 }
6130 }
6131
6132 /*-- HYPHENATION --*/
6133 // Soft Hyphens chr(173)
6134 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
6135 $rem = $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
6136 list($success,$pre,$post,$prelength) = $this->softHyphenate($currWord, (($rem-$cutoffWidth)/_MPDFK -$this->GetCharWidth(" ", false)) );
6137 }
6138
6139 if (!$success && !$hardsuccess && $this->textparam['hyphens'] == 1 ) { // mPDF 5.6.06 // mPDF 5.6.21
6140 // Look ahead to get current word
6141 for($ac = $i; $ac<(mb_strlen($s)-1); $ac++) {
6142 $addc = mb_substr($s,$ac,1,$this->mb_enc );
6143 if ($addc == ' ') { break; }
6144 $currWord .= $addc;
6145 }
6146 $rem = $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
6147 list($success,$pre,$post,$prelength) = $this->hyphenateWord($currWord, (($rem-$cutoffWidth)/_MPDFK -$this->GetCharWidth(" ", false)) );
6148 }
6149 if ($success) {
6150 $already = array_pop( $words );
6151 $forward = mb_substr($already,$prelength,mb_strlen($already, $this->mb_enc), $this->mb_enc);
6152 $words[] = $pre.'-';
6153 $words[] = $forward;
6154 $currContent = mb_substr($currContent,0,mb_strlen($currContent, $this->mb_enc)+1-mb_strlen($post, $this->mb_enc), $this->mb_enc) . '-';
6155 }
6156 /*-- END HYPHENATION --*/
6157
6158 // mPDF 5.6.13 Decimal alignment (cancel if wraps to > 1 line)
6159 if ($is_table && substr($align,0,1)=='D' ) { $align=substr($align,2,1); }
6160
6161 /*-- CJK-FONTS --*/
6162 // mPDF 5.6.42
6163 if ($this->checkCJK) {
6164 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
6165 }
6166 // Next character is suitable to add as overhanging or squeezed punctuation
6167 if ($this->checkCJK && preg_match("/[".$this->CJKoverflow."]/u", $c) && $this->allowCJKorphans && !$CJKoverflow) {
6168 // add character onto this line
6169 $currContent .= $c;
6170 $cutoffWidth = $contentWidth;
6171 $contentWidth += $cw;
6172 $CJKoverflow = true;
6173 continue;
6174 }
6175 // Last character that fits is not allowed to end a line - move lastchar(s) to start of next line
6176 else if ($this->checkCJK && preg_match("/[".$this->CJKleading."]/u", $lastchar)) {
6177 //move lastchar(s) to next line
6178 $m0 = $lastchar;
6179 $m1 = $c;
6180 while(preg_match("/[".$this->CJKleading."]/u", $m0) && mb_strlen($words[(count($words)-1)], $this->mb_enc)>2) {
6181 // trim last letter off word[0]
6182 $words[(count($words)-1)] = mb_substr($words[(count($words)-1)],0,mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, $this->mb_enc);
6183 // and add it to savedContent for next line
6184 $savedContent = $m0.$savedContent;
6185 $m1 = $lastchar;
6186 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
6187 $m0 = $lastchar;
6188 }
6189 $lastContent = '';
6190 for ( $w = 0; $w < count( $words ) ; $w++) { $lastContent .= $words[ $w ]." "; }
6191 $savedFont = $this->saveFont();
6192 // replace the current content with the cropped version
6193 $currContent = rtrim( $lastContent );
6194 }
6195 // Next character is not allowed to start a new line
6196 else if ($this->checkCJK && preg_match("/[".$this->CJKfollowing."]/u", $c)) {
6197 // try squeezing another character(s) onto this line = Oikomi
6198 if ($this->allowCJKorphans && !$CJKoverflow) { // mPDF 5.6.40
6199 $lookahead = mb_substr($s,$i+1,1,$this->mb_enc );
6200 //if lookahead is not another following char
6201 if (!$lookahead || ($lookahead && !preg_match("/[".$this->CJKfollowing."]/u", $lookahead))) {
6202 $currContent .= $c;
6203 $cutoffWidth = $contentWidth;
6204 $contentWidth += $cw;
6205 if ($this->allowCJKoverflow && preg_match("/[".$this->CJKoverflow."]/u", $c)) { $CJKoverflow = true; }
6206 continue;
6207 }
6208 }
6209 // or move lastchar(s) to next line to keep $c company = Oidashi
6210 $m0 = $lastchar;
6211 $m1 = $c;
6212 while(preg_match("/[".$this->CJKfollowing."]/u", $m1) && mb_strlen($words[(count($words)-1)], $this->mb_enc)>2) {
6213 // trim last letter off word[0]
6214 $words[(count($words)-1)] = mb_substr($words[(count($words)-1)],0,mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, $this->mb_enc);
6215 // and add it to savedContent for next line
6216 $savedContent = $m0.$savedContent;
6217 $m1 = $lastchar;
6218 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
6219 $m0 = $lastchar;
6220 }
6221 $lastContent = '';
6222 for ( $w = 0; $w < count( $words ) ; $w++) { $lastContent .= $words[ $w ]." "; }
6223 $savedFont = $this->saveFont();
6224 // replace the current content with the cropped version
6225 $currContent = rtrim( $lastContent );
6226 }
6227 // mPDF 5.6.42
6228 else if ($this->checkCJK && preg_match("/([".$this->pregCJKchars."]+[0-9\x{ff10}-\x{ff19}]+$)/u", $words[0])) {
6229 $lookahead = mb_substr($s,$i,16,$this->mb_enc );
6230 //and if lookahead starts with a few numerals
6231 if ($lookahead && (preg_match("/^([0-9\x{ff10}-\x{ff19}]+[".$this->pregCJKchars."]+)/u", $lookahead) || preg_match("/^([0-9\x{ff10}-\x{ff19}]+$)/u", $lookahead)) ) {
6232 // or move lastchar(s) to next line to keep numerals together
6233 $m0 = $lastchar;
6234 while(preg_match("/[0-9\x{ff10}-\x{ff19}]/u", $m0) && mb_strlen($words[(count($words)-1)], $this->mb_enc)>2) {
6235 // trim last letter off word[0]
6236 $words[(count($words)-1)] = mb_substr($words[(count($words)-1)],0,mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, $this->mb_enc);
6237 // and add it to savedContent for next line
6238 $savedContent = $m0.$savedContent;
6239 $lastchar = mb_substr($words[(count($words)-1)],mb_strlen($words[(count($words)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
6240 $m0 = $lastchar;
6241 }
6242 }
6243 $lastContent = '';
6244 for ( $w = 0; $w < count( $words ) ; $w++) { $lastContent .= $words[ $w ]." "; }
6245 $savedFont = $this->saveFont();
6246 // replace the current content with the cropped version
6247 $currContent = rtrim( $lastContent );
6248 }
6249 else
6250 /*-- END CJK-FONTS --*/
6251 // if it looks like we didn't finish any words for this chunk
6252 if ( count( $words ) == 1 ) {
6253 // TO correct for error when word too wide for page - but only when one long word from left to right margin
6254 if (count($content) == 1 && $currContent != ' ') {
6255 $lastchar = mb_substr($words[0],mb_strlen($words[0], $this->mb_enc)-1, 1, $this->mb_enc);
6256 $lastContent = $words[0];
6257 $savedFont = $this->saveFont();
6258 // replace the current content with the cropped version
6259 $currContent = rtrim( $lastContent );
6260 }
6261 // mPDF 5.6.20
6262 else if ( count($content)>1
6263 && (!isset($this->objectbuffer[(count($content)-1)]) && !isset($this->objectbuffer[(count($content)-2)]))
6264 && substr($content[count($content)-2],-1,1) != ' '
6265 && substr($currContent,0,1) != ' '
6266 ) {
6267 // Go back to find a space in a previous chunk of content
6268 $found = false;
6269 for ($ix=count($content)-1;$ix>=0;$ix--) {
6270 // mPDF 5.6.29
6271 if ($this->usingCoreFont && preg_match('/[ '.chr(173).']/',$content[$ix],$m)) { $match = $m[0]; $found = $ix; break; }
6272 else if (!$this->usingCoreFont) {
6273 if (preg_match('/[ ]/',$content[$ix])) { $match = ' '; $found = $ix; break; }
6274 else if (preg_match('/[\x{00AD}]/u',$content[$ix])) {
6275 // even though it is UTF-8 replace it temporarily with chr(173)
6276 $content[$ix] = preg_replace('/[\x{00AD}]/u',chr(173),$content[$ix]);
6277 $match = chr(173); $found = $ix; break;
6278 }
6279 }
6280 }
6281 if ($found !== false) {
6282 $charpos = strrpos($content[$found],$match); // mPDF 5.6.29
6283 for ($ix=count($content)-1;$ix>$found;$ix--) {
6284 // save and crop off any subsequent chunks
6285 $savedPreContent[] = array_pop($content);
6286 $savedPreContentB[] = array_pop($contentB);
6287 $savedPreFont[] = array_pop($font);
6288 }
6289 if (substr($content[count($content)-1],$charpos+1,strlen($content[count($content)-1])-1) != '') {
6290 $savedPreContent[] = substr($content[count($content)-1],$charpos+1,strlen($content[count($content)-1])-1);
6291 $savedPreContentB[] = preg_replace('/L/','',$contentB[count($content)-1]); // ???
6292 $savedPreFont[] = $font[count($content)-1];
6293 }
6294 $savedContent = '';
6295 $savedContentB = '';
6296 $savedFont = array();
6297
6298 $currContent =& $content[ count( $content ) - 1 ];
6299 $currContent = substr($currContent,0,$charpos);
6300 if ($match == chr(173)) { $currContent .= '-'; } // mPDF 5.6.29
6301 if (strpos($contentB[(count($contentB)-1)],'R')!==false) { // ???
6302 $contentB[count($content)-1] = preg_replace('/R/','',$contentB[count($content)-1]); // ???
6303 }
6304
6305 $currContent = rtrim( $currContent );
6306 }
6307 else {
6308 $savedContent = array_pop( $content );
6309 $savedContentB = array_pop($contentB);
6310 $savedFont = array_pop( $font );
6311 $currContent =& $content[ count( $content ) - 1 ];
6312 $currContent = rtrim( $currContent );
6313 }
6314 }
6315 else {
6316 // save and crop off the content currently on the stack
6317 $savedContent = array_pop( $content );
6318 $savedContentB = array_pop($contentB); // mPDF 5.6.20
6319 $savedFont = array_pop( $font );
6320
6321 // mPDF 5.7.2
6322 // e.g: |first chunk |second chunk |[IndexEntry]|doesntfit
6323 if (isset($this->objectbuffer[(count($content)-1)]) && $this->objectbuffer[(count($content)-1)]['OUTER-WIDTH'] < 0.001) {
6324 $savedObj = $this->objectbuffer[(count($content)-1)];
6325 array_pop( $content );
6326 array_pop( $contentB );
6327 array_pop( $font );
6328 array_pop( $this->objectbuffer );
6329 }
6330
6331 // trim any trailing spaces off the last bit of content
6332 $currContent =& $content[ count( $content ) - 1 ];
6333 $currContent = rtrim( $currContent );
6334 }
6335 }
6336 else { // otherwise, we need to find which bit to cut off
6337 $lastContent = '';
6338 for ( $w = 0; $w < count( $words ) - 1; $w++) { $lastContent .= $words[ $w ]." "; }
6339 $savedContent = $words[ count( $words ) - 1 ];
6340 $savedFont = $this->saveFont();
6341 // replace the current content with the cropped version
6342 $currContent = rtrim( $lastContent );
6343 }
6344 // CJK - strip CJK space at end of line
6345 // &#x3000; = \xe3\x80\x80 = CJK space
6346 if ($this->checkCJK) { $currContent = preg_replace("/\xe3\x80\x80$/",'',$currContent) ; } // *CJK-FONTS*
6347
6348
6349 if (isset($this->objectbuffer[(count($content)-1)]) && $this->objectbuffer[(count($content)-1)]['type']=='dottab') {
6350 $savedObj = array_pop( $this->objectbuffer );
6351 $contentWidth -= ($this->objectbuffer[(count($content)-1)]['OUTER-WIDTH'] * _MPDFK);
6352 }
6353
6354 // Set Current lineheight (correction factor)
6355 $lhfixed = false;
6356 /*-- LISTS --*/
6357 if ($is_list) {
6358 if (preg_match('/([0-9.,]+)mm/',$this->list_lineheight[$this->listlvl][$this->listOcc],$am)) {
6359 $lhfixed = true;
6360 $def_fontsize = $this->InlineProperties['LISTITEM'][$this->listlvl][$this->listOcc][$this->listnum]['size'];
6361 $this->lineheight_correction = $am[1] / $def_fontsize ;
6362 }
6363 else {
6364 $this->lineheight_correction = $this->list_lineheight[$this->listlvl][$this->listOcc];
6365 }
6366 }
6367 else
6368 /*-- END LISTS --*/
6369 /*-- TABLES --*/
6370 if ($is_table) {
6371 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight,$am)) {
6372 $lhfixed = true;
6373 $def_fontsize = $this->FontSize; // needs to be default font-size for block ****
6374 $this->lineheight_correction = $lineHeight / $def_fontsize ;
6375 }
6376 else {
6377 $this->lineheight_correction = $this->table_lineheight;
6378 }
6379 }
6380 else
6381 /*-- END TABLES --*/
6382 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
6383 if (preg_match('/([0-9.,]+)mm/',$this->blk[$this->blklvl]['line_height'],$am)) {
6384 $lhfixed = true;
6385 $def_fontsize = $this->blk[$this->blklvl]['InlineProperties']['size']; // needs to be default font-size for block ****
6386 $this->lineheight_correction = $am[1] / $def_fontsize ;
6387 }
6388 else {
6389 $this->lineheight_correction = $this->blk[$this->blklvl]['line_height'];
6390 }
6391 }
6392 else {
6393 $this->lineheight_correction = $this->normalLineheight;
6394 }
6395 // update $contentWidth and $cutoffWidth since they changed with cropping
6396 // Also correct lineheight to maximum fontsize (not for tables)
6397 $contentWidth = 0;
6398 // correct lineheight to maximum fontsize
6399 if ($lhfixed) { $maxlineHeight = $this->lineheight; }
6400 else { $maxlineHeight = 0; }
6401 $this->forceExactLineheight = true;
6402 $maxfontsize = 0;
6403 // While we're at it, check for cursive text
6404 $checkCursive=false;
6405 if ($this->biDirectional) { $checkCursive=true; } // *RTL*
6406 foreach ( $content as $k => $chunk )
6407 {
6408 $this->restoreFont( $font[ $k ]);
6409 if (!isset($this->objectbuffer[$k])) {
6410 // mPDF 5.6.40
6411 if ($this->checkCJK && $k == count($content)-1 && $CJKoverflow && $align=='J' && $this->allowCJKoverflow && $this->CJKforceend) {
6412 // force-end overhang
6413 $hanger = mb_substr($chunk,mb_strlen($chunk,$this->mb_enc)-1,1,$this->mb_enc );
6414 $content[$k] = $chunk = mb_substr($chunk,0,mb_strlen($chunk,$this->mb_enc)-1,$this->mb_enc );
6415 }
6416 if (!$this->usingCoreFont) {
6417 $content[$k] = $chunk = str_replace("\xc2\xad",'',$chunk );
6418 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) { $checkCursive=true; } // *INDIC*
6419 }
6420 // Soft Hyphens chr(173)
6421 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
6422 $content[$k] = $chunk = str_replace(chr(173),'',$chunk );
6423 }
6424 $contentWidth += $this->GetStringWidth( $chunk ) * _MPDFK;
6425 if (!empty($this->spanborddet)) {
6426 if (strpos($contentB[$k],'L')!==false) $contentWidth += $this->spanborddet['L']['w'] * _MPDFK;
6427 if (strpos($contentB[$k],'R')!==false) $contentWidth += $this->spanborddet['R']['w'] * _MPDFK;
6428 }
6429 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$this->FontSize * $this->lineheight_correction ); }
6430 if ($lhfixed && ($this->FontSize > $def_fontsize || ($this->FontSize > ($lineHeight * $this->lineheight_correction) && $is_list))) {
6431 $this->forceExactLineheight = false;
6432 }
6433 $maxfontsize = max($maxfontsize,$this->FontSize);
6434 }
6435 }
6436
6437 $lastfontreqstyle = $font[count($font)-1]['ReqFontStyle'];
6438 $lastfontstyle = $font[count($font)-1]['style'];
6439 if ($blockdir == 'ltr' && strpos($lastfontreqstyle,"I") !== false && strpos($lastfontstyle,"I") === false) { // Artificial italic
6440 $lastitalic = $this->FontSize*0.15*_MPDFK;
6441 }
6442 else { $lastitalic = 0; }
6443
6444
6445 /*-- LISTS --*/
6446 if ($is_list && is_array($this->bulletarray) && $this->bulletarray) {
6447 $actfs = $this->bulletarray['fontsize'];
6448 if (!$lhfixed) { $maxlineHeight = max($maxlineHeight,$actfs * $this->lineheight_correction ); }
6449 if ($lhfixed && $actfs > $def_fontsize) { $this->forceExactLineheight = false; }
6450 $maxfontsize = max($maxfontsize,$actfs);
6451 }
6452 /*-- END LISTS --*/
6453
6454 // when every text item checked i.e. $maxfontsize is set properly
6455
6456 $af = 0; // Above font
6457 $bf = 0; // Below font
6458 $mta = 0; // Maximum top-aligned
6459 $mba = 0; // Maximum bottom-aligned
6460
6461 foreach ( $content as $k => $chunk ) {
6462 if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
6463 $contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * _MPDFK;
6464 $oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
6465 $va = $this->objectbuffer[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
6466 if ($lhfixed && $oh > $def_fontsize) { $this->forceExactLineheight = false; }
6467
6468 if ($va == 'BS') { // (BASELINE default)
6469 $af = max($af, ($oh - ($maxfontsize * (0.5 + $this->baselineC))));
6470 }
6471 else if ($va == 'M') {
6472 $af = max($af, ($oh - $maxfontsize)/2);
6473 $bf = max($bf, ($oh - $maxfontsize)/2);
6474 }
6475 else if ($va == 'TT') {
6476 $bf = max($bf, ($oh - $maxfontsize));
6477 }
6478 else if ($va == 'TB') {
6479 $af = max($af, ($oh - $maxfontsize));
6480 }
6481 else if ($va == 'T') {
6482 $mta = max($mta, $oh);
6483 }
6484 else if ($va == 'B') {
6485 $mba = max($mba, $oh);
6486 }
6487 }
6488 // mPDF 5.7.3 inline text-decoration parameters
6489 else if (!$is_table && isset($font[$k]['textparam']['text-baseline'])) {
6490 if ($font[$k]['textparam']['text-baseline'] > 0) { // superscript
6491 $nh = ($maxfontsize * $this->baselineC) + $font[$k]['textparam']['text-baseline'] + ($font[$k]['size'] * (1-$this->baselineC));
6492 if ($lhfixed && $nh > $def_fontsize) { $this->forceExactLineheight = false; }
6493 $af = max($af, ($nh-$maxfontsize));
6494 }
6495 else if ($font[$k]['textparam']['text-baseline'] < 0) { // subscript
6496 $nh = ($maxfontsize * (1-$this->baselineC)) - $font[$k]['textparam']['text-baseline'] + ($font[$k]['size'] * $this->baselineC);
6497 if ($lhfixed && $nh > $def_fontsize) { $this->forceExactLineheight = false; }
6498 $bf = max($bf, ($nh-$maxfontsize));
6499 }
6500 }
6501 }
6502 if ((!$lhfixed || !$this->forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
6503 $maxlineHeight = $maxfontsize + $af + $bf;
6504 }
6505 else if (!$lhfixed) { $af = $bf = ($maxlineHeight - $maxfontsize)/2; }
6506
6507 if ($mta > $maxlineHeight) {
6508 $bf += ($mta - $maxlineHeight);
6509 $maxlineHeight = $mta;
6510 }
6511 if ($mba > $maxlineHeight) {
6512 $af += ($mba - $maxlineHeight);
6513 $maxlineHeight = $mba;
6514 }
6515
6516
6517 $lineHeight = $maxlineHeight;
6518 $cutoffWidth = $contentWidth;
6519 // If NOT images, and maxfontsize NOT > lineHeight - this value determines text baseline positioning
6520 if ($lhfixed && $af==0 && $bf==0 && $maxfontsize<=($def_fontsize * $this->lineheight_correction * 0.8 )) {
6521 $this->linemaxfontsize = $def_fontsize;
6522 }
6523 else { $this->linemaxfontsize = $maxfontsize; }
6524
6525
6526 $inclCursive=false;
6527 foreach ( $content as $k => $chunk ) {
6528 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
6529 if ($this->usingCoreFont) {
6530 $content[$k] = str_replace(chr(160),chr(32),$chunk );
6531 }
6532 else {
6533 $content[$k] = str_replace(chr(194).chr(160),chr(32),$chunk );
6534 if ($checkCursive) {
6535 if (preg_match("/([".$this->pregRTLchars."])/u", $chunk)) { $inclCursive = true; } // *RTL*
6536 if (preg_match("/([".$this->pregHIchars.$this->pregBNchars.$this->pregPAchars."])/u", $chunk)) { $inclCursive = true; } // *INDIC*
6537 }
6538 }
6539 }
6540 }
6541
6542 // JUSTIFICATION J
6543 $jcharspacing = 0;
6544 $jws = 0;
6545 $nb_carac = 0;
6546 $nb_spaces = 0;
6547 // 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)
6548 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
6549 // JUSTIFY J (Use character spacing)
6550 // WORD SPACING
6551 foreach ( $content as $k => $chunk ) {
6552 if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
6553 $nb_carac += mb_strlen( $chunk, $this->mb_enc ) ;
6554 $nb_spaces += mb_substr_count( $chunk,' ', $this->mb_enc ) ;
6555 }
6556 }
6557 list($jcharspacing,$jws) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$cutoffWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*_MPDFK)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) )),$inclCursive);
6558 }
6559
6560
6561 // WORD SPACING
6562 $empty = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
6563
6564 $empty -= ($jcharspacing * $nb_carac);
6565 $empty -= ($jws * $nb_spaces);
6566
6567 $empty /= _MPDFK;
6568 $b = ''; //do not use borders
6569 // Get PAGEBREAK TO TEST for height including the top border/padding
6570 $check_h = max($this->divheight,$lineHeight);
6571 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($this->blklvl > 0) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6572 $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
6573 }
6574
6575 if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) {
6576 $this->SetCol($this->NbCol-1);
6577 }
6578
6579 // PAGEBREAK
6580 // 'If' below used in order to fix "first-line of other page with justify on" bug
6581 if(!$is_table && ($this->y+$check_h) > $this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
6582 $bak_x=$this->x;//Current X position
6583
6584 // WORD SPACING
6585 $ws=$this->ws;//Word Spacing
6586 $charspacing=$this->charspacing;//Character Spacing
6587 $this->ResetSpacing();
6588
6589 $this->AddPage($this->CurOrientation);
6590
6591 $this->x = $bak_x;
6592 // Added to correct for OddEven Margins
6593 $currentx += $this->MarginCorrection;
6594 $this->x += $this->MarginCorrection;
6595
6596 // WORD SPACING
6597 $this->SetSpacing($charspacing,$ws);
6598 }
6599
6600 if ($this->keep_block_together && !$is_table && $this->kt_p00 < $this->page && ($this->y+$check_h) > $this->kt_y00) {
6601 $this->printdivbuffer();
6602 $this->keep_block_together = 0;
6603 }
6604
6605 if ($this->kwt && !$is_table) { // mPDF 5.7+
6606 $this->printkwtbuffer();
6607 $this->kwt = false;
6608 }
6609
6610 /*-- COLUMNS --*/
6611 // COLS
6612 // COLUMN CHANGE
6613 if ($this->CurrCol != $oldcolumn) {
6614 $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
6615 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
6616 $oldcolumn = $this->CurrCol;
6617 }
6618
6619 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6620 /*-- END COLUMNS --*/
6621
6622 // TOP MARGIN
6623 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($this->blk[$this->blklvl]['margin_top']) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6624 $this->DivLn($this->blk[$this->blklvl]['margin_top'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
6625 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6626 }
6627
6628
6629 // Update y0 for top of block (used to paint border)
6630 if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6631 $this->blk[$this->blklvl]['y0'] = $this->y;
6632 $this->blk[$this->blklvl]['startpage'] = $this->page;
6633 if ($this->blk[$this->blklvl]['float']) { $this->blk[$this->blklvl]['float_start_y'] = $this->y; } // mPDF 5.6.63
6634 }
6635
6636 // TOP PADDING and BORDER spacing/fill
6637 if (($newblock) && ($blockstate==1 || $blockstate==3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 1) && (!$is_table) && (!$is_list)) {
6638 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
6639 $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'],-3,true,false,1);
6640 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6641 }
6642
6643 $arraysize = count($content);
6644
6645 $margins = ($this->cMarginL+$this->cMarginR) + ($ipaddingL+$ipaddingR + $fpaddingR + $fpaddingR );
6646
6647 // PAINT BACKGROUND FOR THIS LINE
6648 if (!$is_table) { $this->DivLn($lineHeight,$this->blklvl,false); } // false -> don't advance y
6649
6650 $this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL ;
6651 if ($align == 'R') { $this->x += $empty; }
6652 else if ($align == 'C') { $this->x += ($empty / 2); }
6653
6654 // Paragraph INDENT
6655 if (isset($this->blk[$this->blklvl]['text_indent']) && ($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 1) && (!$is_table) && ($blockdir !='rtl') && ($align !='C')) {
6656 $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->blk[$this->blklvl]['InlineProperties']['size'],false);
6657 $this->x += $ti;
6658 }
6659
6660 // DIRECTIONALITY RTL
6661 $all_rtl = false;
6662 $contains_rtl = false;
6663 /*-- RTL --*/
6664 if ($blockdir == 'rtl' || $this->biDirectional) {
6665 $all_rtl = true;
6666 foreach ( $content as $k => $chunk ) {
6667 $reversed = $this->magic_reverse_dir($chunk, false, $blockdir);
6668
6669 if ($reversed > 0) { $contains_rtl = true; }
6670 if ($reversed < 2) { $all_rtl = false; }
6671 $content[$k] = $chunk;
6672 }
6673 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) {
6674 $content = array_reverse($content,false);
6675 $contentB = array_reverse($contentB,false);
6676 }
6677 }
6678 /*-- END RTL --*/
6679
6680 foreach ( $content as $k => $chunk ) {
6681
6682 // FOR IMAGES - UPDATE POSITION
6683 if (($blockdir =='rtl' && $contains_rtl) || $all_rtl) { $dirk = $arraysize-1 - $k ; } else { $dirk = $k; }
6684
6685 $va = 'M'; // default for text
6686 if (isset($this->objectbuffer[$dirk]) && $this->objectbuffer[$dirk]) {
6687 $xadj = $this->x - $this->objectbuffer[$dirk]['OUTER-X'] ;
6688 $this->objectbuffer[$dirk]['OUTER-X'] += $xadj;
6689 $this->objectbuffer[$dirk]['BORDER-X'] += $xadj;
6690 $this->objectbuffer[$dirk]['INNER-X'] += $xadj;
6691 $va = $this->objectbuffer[$dirk]['vertical-align'];
6692 $yadj = $this->y - $this->objectbuffer[$dirk]['OUTER-Y'];
6693 if ($va == 'BS') {
6694 $yadj += $af + ($this->linemaxfontsize * (0.5 + $this->baselineC)) - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
6695 }
6696 else if ($va == 'M' || $va == '') {
6697 $yadj += $af + ($this->linemaxfontsize /2) - ($this->objectbuffer[$dirk]['OUTER-HEIGHT']/2);
6698 }
6699 else if ($va == 'TB') {
6700 $yadj += $af + $this->linemaxfontsize - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
6701 }
6702 else if ($va == 'TT') {
6703 $yadj += $af;
6704 }
6705 else if ($va == 'B') {
6706 $yadj += $af + $this->linemaxfontsize + $bf - $this->objectbuffer[$dirk]['OUTER-HEIGHT'];
6707 }
6708 else if ($va == 'T') {
6709 $yadj += 0;
6710 }
6711 $this->objectbuffer[$dirk]['OUTER-Y'] += $yadj;
6712 $this->objectbuffer[$dirk]['BORDER-Y'] += $yadj;
6713 $this->objectbuffer[$dirk]['INNER-Y'] += $yadj;
6714 }
6715
6716 // DIRECTIONALITY RTL
6717 if ((($blockdir == 'rtl') && ($contains_rtl )) || ($all_rtl )) { $this->restoreFont($font[$arraysize-1 - $k]); }
6718 else { $this->restoreFont( $font[ $k ] ); }
6719
6720 $this->SetSpacing(($this->fixedlSpacing*_MPDFK)+$jcharspacing,($this->fixedlSpacing+$this->minwSpacing)*_MPDFK+$jws);
6721 // Now unset these values so they don't influence GetStringwidth below or in fn. Cell
6722 $this->fixedlSpacing = false;
6723 $this->minwSpacing = 0;
6724
6725 // mPDF 5.6.26
6726 $save_vis = $this->visibility;
6727 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->textparam['visibility'] != $this->visibility) {
6728 $this->SetVisibility($this->textparam['visibility']);
6729 }
6730 // *********** SPAN BACKGROUND COLOR ***************** //
6731 if ($this->spanbgcolor) {
6732 $cor = $this->spanbgcolorarray;
6733 $this->SetFColor($cor);
6734 $save_fill = $fill; $spanfill = 1; $fill = 1;
6735 }
6736 if (!empty($this->spanborddet)) {
6737 if (strpos($contentB[$k],'L')!==false) $this->x += $this->spanborddet['L']['w'];
6738 if (strpos($contentB[$k],'L')===false) $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0;
6739 if (strpos($contentB[$k],'R')===false) $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0;
6740 }
6741
6742 // WORD SPACING
6743 $stringWidth = $this->GetStringWidth($chunk );
6744 $stringWidth += ( $this->charspacing * mb_strlen($chunk,$this->mb_enc ) / _MPDFK );
6745 $stringWidth += ( $this->ws * mb_substr_count($chunk,' ',$this->mb_enc ) / _MPDFK );
6746 if (isset($this->objectbuffer[$dirk])) { $stringWidth = $this->objectbuffer[$dirk]['OUTER-WIDTH']; }
6747
6748 if ($stringWidth==0) { $stringWidth = 0.000001; }
6749 if ($k == $arraysize-1) {
6750 $stringWidth -= ( $this->charspacing / _MPDFK );
6751 // mPDF 5.6.40
6752 if ($this->checkCJK && $CJKoverflow && $align=='J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) {
6753 // force-end overhang
6754 $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
6755 $this->Cell( $this->GetStringWidth($hanger), $lineHeight, $hanger, '', 1, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, $af, $bf, true );
6756 }
6757 else {
6758 $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)
6759 }
6760
6761 }
6762 else $this->Cell( $stringWidth, $lineHeight, $chunk, '', 0, '', $fill, $this->HREF, 0, 0,0,'M', $fill, $af, $bf, true );//first or middle part
6763
6764 if (!empty($this->spanborddet)) {
6765 if (strpos($contentB[$k],'R')!==false && $k != $arraysize-1) $this->x += $this->spanborddet['R']['w'];
6766 }
6767 // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
6768 if (isset($spanfill) && $spanfill) {
6769 $fill = $save_fill; $spanfill = 0;
6770 if ($fill) { $this->SetFColor($bcor); }
6771 }
6772 // mPDF 5.6.26
6773 if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->visibility != $save_vis) {
6774 $this->SetVisibility($save_vis);
6775 }
6776
6777 }
6778 if (!$is_table) {
6779 $this->maxPosR = max($this->maxPosR , ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin']));
6780 $this->maxPosL = min($this->maxPosL , ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin']));
6781 }
6782
6783 // move on to the next line, reset variables, tack on saved content and current char
6784
6785 $this->printobjectbuffer($is_table, $blockdir);
6786 $this->objectbuffer = array();
6787
6788 /*-- LISTS --*/
6789 // LIST BULLETS/NUMBERS
6790 if ($is_list && is_array($this->bulletarray) && ($lineCount == 1) ) {
6791
6792 $this->ResetSpacing();
6793
6794 $bull = $this->bulletarray;
6795 if (isset($bull['level']) && isset($bull['occur']) && isset($this->InlineProperties['LIST'][$bull['level']][$bull['occur']])) {
6796 $this->restoreInlineProperties($this->InlineProperties['LIST'][$bull['level']][$bull['occur']]);
6797 }
6798 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']]); }
6799 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
6800 $this->bullet = true;
6801 $this->SetFont('czapfdingbats','',$this->FontSizePt/2.5);
6802 }
6803 else { $this->SetFont($this->FontFamily,$this->FontStyle,$this->FontSizePt,true,true); } // force output
6804 //Output bullet
6805 $this->x = $currentx;
6806 if (isset($bull['x'])) { $this->x += $bull['x']; }
6807 $this->y -= $lineHeight;
6808 if (isset($bull['col']) && $bull['col']) { $this->SetTColor($bull['col']); } // mPDF 5.6.67
6809 if (isset($bull['txt'])) { $this->Cell($bull['w'], $lineHeight,$bull['txt'],'','',$bull['align'],0,'',0,-$this->cMarginL, -$this->cMarginR ); }
6810 if (isset($bull['font']) && $bull['font'] == 'czapfdingbats') {
6811 $this->bullet = false;
6812 }
6813 $this->x = $currentx; // Reset
6814 $this->y += $lineHeight;
6815
6816 if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
6817
6818 $this->bulletarray = array(); // prevents repeat of bullet/number if <li>....<br />.....</li>
6819 }
6820 /*-- END LISTS --*/
6821
6822
6823 /*-- CSS-IMAGE-FLOAT --*/
6824 // Update values if set to skipline
6825 if ($this->floatmargins) { $this->_advanceFloatMargins(); }
6826 /*-- END CSS-IMAGE-FLOAT --*/
6827
6828 // Reset lineheight
6829 $lineHeight = $this->divheight;
6830 $valign = 'M';
6831
6832 $font = array();
6833 $content = array();
6834 $contentB = array();
6835 $contentWidth = 0;
6836 if (!empty($savedObj)) {
6837 $this->objectbuffer[] = $savedObj;
6838 $font[] = $savedFont;
6839 $content[] = '';
6840 $contentB[] = '';
6841 $contentWidth += $savedObj['OUTER-WIDTH'] * _MPDFK;
6842 }
6843 // mPDF 5.6.20
6844 if (count($savedPreContent) > 0) {
6845 for($ix=count($savedPreContent)-1;$ix>=0;$ix--) {
6846 $font[] = $savedPreFont[$ix];
6847 $content[] = $savedPreContent[$ix];
6848 $contentB[] = $savedPreContentB[$ix];
6849 $this->restoreFont( $savedPreFont[$ix] );
6850 $lbw = $rbw = 0; // Border widths
6851 if (!empty($this->spanborddet)) {
6852 $lbw = $this->spanborddet['L']['w'];
6853 $rbw = $this->spanborddet['R']['w'];
6854 }
6855 if ($ix>0) {
6856 $contentWidth += $this->GetStringWidth( $savedPreContent[$ix] ) * _MPDFK;
6857 if (strpos($savedPreContentB[$ix],'L')!==false) $contentWidth += $lbw;
6858 if (strpos($savedPreContentB[$ix],'R')!==false) $contentWidth += $rbw;
6859 }
6860 }
6861 $savedPreContent = array();
6862 $savedPreContentB = array();
6863 $savedPreFont = array();
6864 $content[ (count($content)-1) ] .= $c;
6865 }
6866 else {
6867 $font[] = $savedFont;
6868 $content[] = $savedContent . $c;
6869 $contentB[] = $savedContentB ;
6870 }
6871
6872 $currContent =& $content[ (count($content)-1) ];
6873
6874 // CJK - strip CJK space at end of line
6875 // &#x3000; = \xe3\x80\x80 = CJK space
6876 if ($this->checkCJK && $currContent == "\xe3\x80\x80") { $currContent = '' ; } // *CJK-FONTS*
6877
6878 $this->restoreFont( $savedFont );
6879 $lbw = $rbw = 0; // Border widths
6880 if (!empty($this->spanborddet)) {
6881 $lbw = $this->spanborddet['L']['w'];
6882 $rbw = $this->spanborddet['R']['w'];
6883 }
6884 $contentWidth += $this->GetStringWidth( $currContent ) * _MPDFK;
6885 if (strpos($savedContentB,'L')!==false) $contentWidth += $lbw;
6886 $cutoffWidth = $contentWidth;
6887 $CJKoverflow = false;
6888 $hanger = ''; // mPDF 5.6.40
6889 }
6890 // another character will fit, so add it on
6891 else {
6892 $contentWidth += $cw;
6893 $currContent .= $c;
6894 }
6895 }
6896 unset($content);
6897 unset($contentB);
6898 }
6899 //----------------------END OF FLOWING BLOCK------------------------------------//
6900
6901
6902 /*-- CSS-IMAGE-FLOAT --*/
6903 // Update values if set to skipline
6904 function _advanceFloatMargins() {
6905 // Update floatmargins - L
6906 if (isset($this->floatmargins['L']) && $this->floatmargins['L']['skipline'] && $this->floatmargins['L']['y0'] != $this->y) {
6907 $yadj = $this->y - $this->floatmargins['L']['y0'];
6908 $this->floatmargins['L']['y0'] = $this->y;
6909 $this->floatmargins['L']['y1'] += $yadj;
6910
6911 // Update objattr in floatbuffer
6912 if ($this->floatbuffer[$this->floatmargins['L']['id']]['border_left']['w']) {
6913 $this->floatbuffer[$this->floatmargins['L']['id']]['BORDER-Y'] += $yadj;
6914 }
6915 $this->floatbuffer[$this->floatmargins['L']['id']]['INNER-Y'] += $yadj;
6916 $this->floatbuffer[$this->floatmargins['L']['id']]['OUTER-Y'] += $yadj;
6917
6918 // Unset values
6919 $this->floatbuffer[$this->floatmargins['L']['id']]['skipline'] = false;
6920 $this->floatmargins['L']['skipline'] = false;
6921 $this->floatmargins['L']['id'] = '';
6922 }
6923 // Update floatmargins - R
6924 if (isset($this->floatmargins['R']) && $this->floatmargins['R']['skipline'] && $this->floatmargins['R']['y0'] != $this->y) {
6925 $yadj = $this->y - $this->floatmargins['R']['y0'];
6926 $this->floatmargins['R']['y0'] = $this->y;
6927 $this->floatmargins['R']['y1'] += $yadj;
6928
6929 // Update objattr in floatbuffer
6930 if ($this->floatbuffer[$this->floatmargins['R']['id']]['border_left']['w']) {
6931 $this->floatbuffer[$this->floatmargins['R']['id']]['BORDER-Y'] += $yadj;
6932 }
6933 $this->floatbuffer[$this->floatmargins['R']['id']]['INNER-Y'] += $yadj;
6934 $this->floatbuffer[$this->floatmargins['R']['id']]['OUTER-Y'] += $yadj;
6935
6936 // Unset values
6937 $this->floatbuffer[$this->floatmargins['R']['id']]['skipline'] = false;
6938 $this->floatmargins['R']['skipline'] = false;
6939 $this->floatmargins['R']['id'] = '';
6940 }
6941 }
6942 /*-- END CSS-IMAGE-FLOAT --*/
6943
6944
6945
6946 ////////////////////////////////////////////////////////////////////////////////
6947 // ADDED forcewrap - to call from inline OBJECT functions to breakwords if necessary in cell
6948 ////////////////////////////////////////////////////////////////////////////////
6949 function WordWrap(&$text, $maxwidth, $forcewrap = 0) {
6950 $biggestword=0;
6951 $toonarrow=false;
6952
6953 $text = trim($text);
6954
6955 if ($text==='') return 0;
6956 $space = $this->GetCharWidth(' ',false);
6957 $lines = explode("\n", $text);
6958 $text = '';
6959 $count = 0;
6960 foreach ($lines as $line) {
6961 $words = explode(' ', $line);
6962 $width = 0;
6963 foreach ($words as $word) {
6964 $word = trim($word);
6965 $wordwidth = $this->GetStringWidth($word);
6966 //Warn user that maxwidth is insufficient
6967 if ($wordwidth > $maxwidth + 0.0001) {
6968 if ($wordwidth > $biggestword) { $biggestword = $wordwidth; }
6969 $toonarrow=true;
6970 // ADDED
6971 if ($forcewrap) {
6972 while($wordwidth > $maxwidth) {
6973 $chw = 0; // check width
6974 for ( $i = 0; $i < mb_strlen($word, $this->mb_enc ); $i++ ) {
6975 $chw = $this->GetStringWidth(mb_substr($word,0,$i+1,$this->mb_enc ));
6976 if ($chw > $maxwidth ) {
6977 if ($text) {
6978 $text = rtrim($text)."\n".mb_substr($word,0,$i,$this->mb_enc );
6979 $count++;
6980 }
6981 else {
6982 $text = mb_substr($word,0,$i,$this->mb_enc );
6983 }
6984 $word = mb_substr($word,$i,mb_strlen($word, $this->mb_enc )-$i,$this->mb_enc );
6985 $wordwidth = $this->GetStringWidth($word);
6986 $width = $maxwidth;
6987 break;
6988 }
6989 }
6990 }
6991 }
6992 }
6993
6994 if ($width + $wordwidth < $maxwidth - 0.0001) {
6995 $width += $wordwidth + $space;
6996 $text .= $word.' ';
6997 }
6998 else {
6999 $width = $wordwidth + $space;
7000 $text = rtrim($text)."\n".$word.' ';
7001 $count++;
7002 }
7003 }
7004 $text .= "\n";
7005 $count++;
7006 }
7007 $text = rtrim($text);
7008
7009 //Return -(wordsize) if word is bigger than maxwidth
7010
7011 // ADDED
7012 if ($forcewrap) { return $count; }
7013 if (($toonarrow) && ($this->table_error_report)) {
7014 $this->Error("Word is too long to fit in table - ".$this->table_error_report_param);
7015 }
7016 if ($toonarrow) return -$biggestword;
7017 else return $count;
7018 }
7019
7020 /*-- END HTML-CSS --*/
7021
7022 function _SetTextRendering($mode) {
7023 if (!(($mode == 0) || ($mode == 1) || ($mode == 2)))
7024 $this->Error("Text rendering mode should be 0, 1 or 2 (value : $mode)");
7025 $tr = ($mode.' Tr');
7026 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); }
7027 $this->pageoutput[$this->page]['TextRendering'] = $tr;
7028
7029 }
7030
7031 function SetTextOutline($params=array()) { // mPDF 5.6.07
7032 if (isset($params['outline-s']) && $params['outline-s'])
7033 {
7034 $this->SetLineWidth($params['outline-WIDTH']);
7035 $this->SetDColor($params['outline-COLOR']);
7036 $tr = ('2 Tr');
7037 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); }
7038 $this->pageoutput[$this->page]['TextRendering'] = $tr;
7039 }
7040 else //Now resets all values
7041 {
7042 $this->SetLineWidth(0.2);
7043 $this->SetDColor($this->ConvertColor(0));
7044 $this->_SetTextRendering(0);
7045 $tr = ('0 Tr');
7046 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); }
7047 $this->pageoutput[$this->page]['TextRendering'] = $tr;
7048 }
7049 }
7050
7051 function Image($file,$x,$y,$w=0,$h=0,$type='',$link='',$paint=true, $constrain=true, $watermark=false, $shownoimg=true, $allowvector=true) {
7052 $orig_srcpath = $file;
7053 $this->GetFullPath($file);
7054
7055 $info=$this->_getImage($file, true, $allowvector, $orig_srcpath );
7056 if(!$info && $paint) {
7057 $info = $this->_getImage($this->noImageFile);
7058 if ($info) {
7059 $file = $this->noImageFile;
7060 $w = ($info['w'] * (25.4/$this->dpi)); // 14 x 16px
7061 $h = ($info['h'] * (25.4/$this->dpi)); // 14 x 16px
7062 }
7063 }
7064 if(!$info) return false;
7065 //Automatic width and height calculation if needed
7066 if($w==0 and $h==0) {
7067 /*-- IMAGES-WMF --*/
7068 if ($info['type']=='wmf') {
7069 // WMF units are twips (1/20pt)
7070 // divide by 20 to get points
7071 // divide by k to get user units
7072 $w = abs($info['w'])/(20*_MPDFK);
7073 $h = abs($info['h']) / (20*_MPDFK);
7074 }
7075 else
7076 /*-- END IMAGES-WMF --*/
7077 if ($info['type']=='svg') {
7078 // returned SVG units are pts
7079 // divide by k to get user units (mm)
7080 $w = abs($info['w'])/_MPDFK;
7081 $h = abs($info['h']) /_MPDFK;
7082 }
7083 else {
7084 //Put image at default image dpi
7085 $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
7086 $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
7087 }
7088 }
7089 if($w==0) $w=abs($h*$info['w']/$info['h']);
7090 if($h==0) $h=abs($w*$info['h']/$info['w']);
7091
7092 /*-- WATERMARK --*/
7093 if ($watermark) {
7094 $maxw = $this->w;
7095 $maxh = $this->h;
7096 // Size = D PF or array
7097 if (is_array($this->watermark_size)) {
7098 $w = $this->watermark_size[0];
7099 $h = $this->watermark_size[1];
7100 }
7101 else if (!is_string($this->watermark_size)) {
7102 $maxw -= $this->watermark_size*2;
7103 $maxh -= $this->watermark_size*2;
7104 $w = $maxw;
7105 $h=abs($w*$info['h']/$info['w']);
7106 if ($h > $maxh ) {
7107 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
7108 }
7109 }
7110 else if ($this->watermark_size == 'F') {
7111 if ($this->ColActive) { $maxw = $this->w - ($this->DeflMargin + $this->DefrMargin); }
7112 else { $maxw = $this->pgwidth; }
7113 $maxh = $this->h - ($this->tMargin + $this->bMargin);
7114 $w = $maxw;
7115 $h=abs($w*$info['h']/$info['w']);
7116 if ($h > $maxh ) {
7117 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
7118 }
7119 }
7120 else if ($this->watermark_size == 'P') { // Default P
7121 $w = $maxw;
7122 $h=abs($w*$info['h']/$info['w']);
7123 if ($h > $maxh ) {
7124 $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
7125 }
7126 }
7127 // Automatically resize to maximum dimensions of page if too large
7128 if ($w > $maxw) {
7129 $w = $maxw;
7130 $h=abs($w*$info['h']/$info['w']);
7131 }
7132 if ($h > $maxh ) {
7133 $h = $maxh ;
7134 $w=abs($h*$info['w']/$info['h']);
7135 }
7136 // Position
7137 if (is_array($this->watermark_pos)) {
7138 $x = $this->watermark_pos[0];
7139 $y = $this->watermark_pos[1];
7140 }
7141 else if ($this->watermark_pos == 'F') { // centred on printable area
7142 if ($this->ColActive) { // *COLUMNS*
7143 if (($this->mirrorMargins) && (($this->page)%2==0)) { $xadj = $this->DeflMargin-$this->DefrMargin; } // *COLUMNS*
7144 else { $xadj = 0; } // *COLUMNS*
7145 $x = ($this->DeflMargin - $xadj + ($this->w - ($this->DeflMargin + $this->DefrMargin))/2) - ($w/2); // *COLUMNS*
7146 } // *COLUMNS*
7147 else { // *COLUMNS*
7148 $x = ($this->lMargin + ($this->pgwidth)/2) - ($w/2);
7149 } // *COLUMNS*
7150 $y = ($this->tMargin + ($this->h - ($this->tMargin + $this->bMargin))/2) - ($h/2);
7151 }
7152 else { // default P - centred on whole page
7153 $x = ($this->w/2) - ($w/2);
7154 $y = ($this->h/2) - ($h/2);
7155 }
7156 /*-- IMAGES-WMF --*/
7157 if ($info['type']=='wmf') {
7158 $sx = $w*_MPDFK / $info['w'];
7159 $sy = -$h*_MPDFK / $info['h'];
7160 $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']);
7161 }
7162 else
7163 /*-- END IMAGES-WMF --*/
7164 if ($info['type']=='svg') {
7165 $sx = $w*_MPDFK / $info['w'];
7166 $sy = -$h*_MPDFK / $info['h'];
7167 $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']);
7168 }
7169 else {
7170 $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']);
7171 }
7172
7173 if ($this->watermarkImgBehind) {
7174 $outstring = $this->watermarkImgAlpha . "\n" . $outstring . "\n" . $this->SetAlpha(1, 'Normal', true) . "\n";
7175 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', "\n".$outstring."\n".'\\1', $this->pages[$this->page]);
7176 }
7177 else { $this->_out($outstring); }
7178
7179 return 0;
7180 } // end of IF watermark
7181 /*-- END WATERMARK --*/
7182
7183 if ($constrain) {
7184 // Automatically resize to maximum dimensions of page if too large
7185 if (isset($this->blk[$this->blklvl]['inner_width']) && $this->blk[$this->blklvl]['inner_width']) { $maxw = $this->blk[$this->blklvl]['inner_width']; }
7186 else { $maxw = $this->pgwidth; }
7187 if ($w > $maxw) {
7188 $w = $maxw;
7189 $h=abs($w*$info['h']/$info['w']);
7190 }
7191 if ($h > $this->h - ($this->tMargin + $this->bMargin + 1)) { // see below - +10 to avoid drawing too close to border of page
7192 $h = $this->h - ($this->tMargin + $this->bMargin + 1) ;
7193 if ($this->fullImageHeight) { $h = $this->fullImageHeight; }
7194 $w=abs($h*$info['w']/$info['h']);
7195 }
7196
7197
7198 //Avoid drawing out of the paper(exceeding width limits).
7199 //if ( ($x + $w) > $this->fw ) {
7200 if ( ($x + $w) > $this->w ) {
7201 $x = $this->lMargin;
7202 $y += 5;
7203 }
7204
7205 $changedpage = false;
7206 $oldcolumn = $this->CurrCol;
7207 //Avoid drawing out of the page.
7208 if($y+$h>$this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
7209 $this->AddPage($this->CurOrientation);
7210 // Added to correct for OddEven Margins
7211 $x=$x +$this->MarginCorrection;
7212 $y = $this->tMargin; // mPDF 5.7.3
7213 $changedpage = true;
7214 }
7215 /*-- COLUMNS --*/
7216 // COLS
7217 // COLUMN CHANGE
7218 if ($this->CurrCol != $oldcolumn) {
7219 $y = $this->y0;
7220 $x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
7221 $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
7222 }
7223 /*-- END COLUMNS --*/
7224 } // end of IF constrain
7225
7226 /*-- IMAGES-WMF --*/
7227 if ($info['type']=='wmf') {
7228 $sx = $w*_MPDFK / $info['w'];
7229 $sy = -$h*_MPDFK / $info['h'];
7230 $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']);
7231 }
7232 else
7233 /*-- END IMAGES-WMF --*/
7234 if ($info['type']=='svg') {
7235 $sx = $w*_MPDFK / $info['w'];
7236 $sy = -$h*_MPDFK / $info['h'];
7237 $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']);
7238 }
7239 else {
7240 $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']);
7241 }
7242
7243 if($paint) {
7244 $this->_out($outstring);
7245 if($link) $this->Link($x,$y,$w,$h,$link);
7246
7247 // Avoid writing text on top of the image. // THIS WAS OUTSIDE THE if ($paint) bit!!!!!!!!!!!!!!!!
7248 $this->y = $y + $h;
7249 }
7250
7251 //Return width-height array
7252 $sizesarray['WIDTH'] = $w;
7253 $sizesarray['HEIGHT'] = $h;
7254 $sizesarray['X'] = $x; //Position before painting image
7255 $sizesarray['Y'] = $y; //Position before painting image
7256 $sizesarray['OUTPUT'] = $outstring;
7257
7258 $sizesarray['IMAGE_ID'] = $info['i'];
7259 $sizesarray['itype'] = $info['type'];
7260 $sizesarray['set-dpi'] = $info['set-dpi'];
7261 return $sizesarray;
7262 }
7263
7264
7265
7266 //=============================================================
7267 //=============================================================
7268 //=============================================================
7269 //=============================================================
7270 //=============================================================
7271 /*-- HTML-CSS --*/
7272
7273 function _getObjAttr($t) {
7274 $c = explode("\xbb\xa4\xac",$t,2);
7275 $c = explode(",",$c[1],2);
7276 foreach($c as $v) {
7277 $v = explode("=",$v,2);
7278 $sp[$v[0]] = $v[1];
7279 }
7280 return (unserialize($sp['objattr']));
7281 }
7282
7283
7284 function inlineObject($type,$x,$y,$objattr,$Lmargin,$widthUsed,$maxWidth,$lineHeight,$paint=false,$is_table=false)
7285 {
7286 if ($is_table) { $k = $this->shrin_k; } else { $k = 1; }
7287
7288 // NB $x is only used when paint=true
7289 // Lmargin not used
7290 $w = 0;
7291 if (isset($objattr['width'])) { $w = $objattr['width']/$k; }
7292 $h = 0;
7293 if (isset($objattr['height'])) { $h = abs($objattr['height']/$k); }
7294 $widthLeft = $maxWidth - $widthUsed;
7295 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 10) ;
7296 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
7297 // For Images
7298 if (isset($objattr['border_left'])) {
7299 $extraWidth = ($objattr['border_left']['w'] + $objattr['border_right']['w'] + $objattr['margin_left']+ $objattr['margin_right'])/$k;
7300 $extraHeight = ($objattr['border_top']['w'] + $objattr['border_bottom']['w'] + $objattr['margin_top']+ $objattr['margin_bottom'])/$k;
7301
7302 if ($type == 'image' || $type == 'barcode' || $type == 'textcircle') {
7303 $extraWidth += ($objattr['padding_left'] + $objattr['padding_right'])/$k;
7304 $extraHeight += ($objattr['padding_top'] + $objattr['padding_bottom'])/$k;
7305 }
7306 }
7307
7308 if (!isset($objattr['vertical-align'])) { $objattr['vertical-align'] = 'M'; }
7309
7310 if ($type == 'image' || (isset($objattr['subtype']) && $objattr['subtype'] == 'IMAGE')) {
7311 if (isset($objattr['itype']) && ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg')) {
7312 $file = $objattr['file'];
7313 $info=$this->formobjects[$file];
7314 }
7315 else if (isset($objattr['file'])) {
7316 $file = $objattr['file'];
7317 $info=$this->images[$file];
7318 }
7319 }
7320 if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
7321 $w = 0.00001;
7322 $h = 0.00001;
7323 }
7324
7325 // TEST whether need to skipline
7326 if (!$paint) {
7327 if ($type == 'hr') { // always force new line
7328 if (($y + $h + $lineHeight > $this->PageBreakTrigger) && !$this->InFooter && !$is_table) { return array(-2, $w ,$h ); } // New page + new line
7329 else { return array(1, $w ,$h ); } // new line
7330 }
7331 else {
7332 if ($widthUsed > 0 && $w > $widthLeft && (!$is_table || $type != 'image')) { // New line needed
7333 if (($y + $h + $lineHeight > $this->PageBreakTrigger) && !$this->InFooter) { return array(-2,$w ,$h ); } // New page + new line
7334 return array(1,$w ,$h ); // new line
7335 }
7336 else if ($widthUsed > 0 && $w > $widthLeft && $is_table) { // New line needed in TABLE
7337 return array(1,$w ,$h ); // new line
7338 }
7339 // Will fit on line but NEW PAGE REQUIRED
7340 else if (($y + $h > $this->PageBreakTrigger) && !$this->InFooter && !$is_table) { return array(-1,$w ,$h ); }
7341 else { return array(0,$w ,$h ); }
7342 }
7343 }
7344
7345 if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
7346 $w = 0.00001;
7347 $h = 0.00001;
7348 $objattr['BORDER-WIDTH'] = 0;
7349 $objattr['BORDER-HEIGHT'] = 0;
7350 $objattr['BORDER-X'] = $x;
7351 $objattr['BORDER-Y'] = $y;
7352 $objattr['INNER-WIDTH'] = 0;
7353 $objattr['INNER-HEIGHT'] = 0;
7354 $objattr['INNER-X'] = $x;
7355 $objattr['INNER-Y'] = $y;
7356 }
7357
7358 if ($type == 'image') {
7359 // Automatically resize to width remaining
7360 if ($w > ($widthLeft + 0.0001) && !$is_table ) { // mPDF 5.7.4 0.0001 to allow for rounding errors when w==maxWidth
7361 $w = $widthLeft ;
7362 $h=abs($w*$info['h']/$info['w']);
7363 }
7364 $img_w = $w - $extraWidth ;
7365 $img_h = $h - $extraHeight ;
7366
7367 $objattr['BORDER-WIDTH'] = $img_w + $objattr['padding_left']/$k + $objattr['padding_right']/$k + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
7368 $objattr['BORDER-HEIGHT'] = $img_h + $objattr['padding_top']/$k + $objattr['padding_bottom']/$k + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
7369 $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
7370 $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
7371 $objattr['INNER-WIDTH'] = $img_w;
7372 $objattr['INNER-HEIGHT'] = $img_h;
7373 $objattr['INNER-X'] = $x + $objattr['padding_left']/$k + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
7374 $objattr['INNER-Y'] = $y + $objattr['padding_top']/$k + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
7375 $objattr['ID'] = $info['i'];
7376 }
7377
7378 if ($type == 'input' && $objattr['subtype'] == 'IMAGE') {
7379 $img_w = $w - $extraWidth ;
7380 $img_h = $h - $extraHeight ;
7381 $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
7382 $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
7383 $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
7384 $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
7385 $objattr['INNER-WIDTH'] = $img_w;
7386 $objattr['INNER-HEIGHT'] = $img_h;
7387 $objattr['INNER-X'] = $x + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
7388 $objattr['INNER-Y'] = $y + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
7389 $objattr['ID'] = $info['i'];
7390 }
7391
7392 if ($type == 'barcode' || $type == 'textcircle') {
7393 $b_w = $w - $extraWidth ;
7394 $b_h = $h - $extraHeight ;
7395 $objattr['BORDER-WIDTH'] = $b_w + $objattr['padding_left']/$k + $objattr['padding_right']/$k + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
7396 $objattr['BORDER-HEIGHT'] = $b_h + $objattr['padding_top']/$k + $objattr['padding_bottom']/$k + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
7397 $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
7398 $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
7399 $objattr['INNER-X'] = $x + $objattr['padding_left']/$k + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
7400 $objattr['INNER-Y'] = $y + $objattr['padding_top']/$k + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
7401 $objattr['INNER-WIDTH'] = $b_w;
7402 $objattr['INNER-HEIGHT'] = $b_h;
7403 }
7404
7405
7406 if ($type == 'textarea') {
7407 // Automatically resize to width remaining
7408 if ($w > $widthLeft && !$is_table) {
7409 $w = $widthLeft ;
7410 }
7411 if (($y + $h > $this->PageBreakTrigger) && !$this->InFooter) {
7412 $h=$this->h - $y - $this->bMargin;
7413 }
7414 }
7415
7416 if ($type == 'hr') {
7417 if ($is_table) {
7418 $objattr['INNER-WIDTH'] = $maxWidth * $objattr['W-PERCENT']/100;
7419 $objattr['width'] = $objattr['INNER-WIDTH'];
7420 $w = $maxWidth;
7421 }
7422 else {
7423 if ($w>$maxWidth) { $w = $maxWidth; }
7424 $objattr['INNER-WIDTH'] = $w;
7425 $w = $maxWidth;
7426 }
7427 }
7428
7429
7430
7431 if (($type == 'select') || ($type == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD'))) {
7432 // Automatically resize to width remaining
7433 if ($w > $widthLeft && !$is_table) {
7434 $w = $widthLeft;
7435 }
7436 }
7437
7438 if ($type == 'textarea' || $type == 'select' || $type == 'input') {
7439 if (isset($objattr['fontsize'])) $objattr['fontsize'] /= $k;
7440 if (isset($objattr['linewidth'])) $objattr['linewidth'] /= $k;
7441 }
7442
7443 if (!isset($objattr['BORDER-Y'])) { $objattr['BORDER-Y'] = 0; }
7444 if (!isset($objattr['BORDER-X'])) { $objattr['BORDER-X'] = 0; }
7445 if (!isset($objattr['INNER-Y'])) { $objattr['INNER-Y'] = 0; }
7446 if (!isset($objattr['INNER-X'])) { $objattr['INNER-X'] = 0; }
7447
7448 //Return width-height array
7449 $objattr['OUTER-WIDTH'] = $w;
7450 $objattr['OUTER-HEIGHT'] = $h;
7451 $objattr['OUTER-X'] = $x;
7452 $objattr['OUTER-Y'] = $y;
7453 return $objattr;
7454 }
7455
7456 /*-- END HTML-CSS --*/
7457
7458 //=============================================================
7459 //=============================================================
7460 //=============================================================
7461 //=============================================================
7462 //=============================================================
7463
7464 function SetLineJoin($mode=0)
7465 {
7466 $s=sprintf('%d j',$mode);
7467 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); }
7468 $this->pageoutput[$this->page]['LineJoin'] = $s;
7469
7470 }
7471 function SetLineCap($mode=2) {
7472 $s=sprintf('%d J',$mode);
7473 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); }
7474 $this->pageoutput[$this->page]['LineCap'] = $s;
7475
7476 }
7477
7478 function SetDash($black=false,$white=false)
7479 {
7480 if($black and $white) $s=sprintf('[%.3F %.3F] 0 d',$black*_MPDFK,$white*_MPDFK);
7481 else $s='[] 0 d';
7482 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); }
7483 $this->pageoutput[$this->page]['Dash'] = $s;
7484
7485 }
7486
7487 function SetDisplayPreferences($preferences) {
7488 // String containing any or none of /HideMenubar/HideToolbar/HideWindowUI/DisplayDocTitle/CenterWindow/FitWindow
7489 $this->DisplayPreferences .= $preferences;
7490 }
7491
7492
7493 function Ln($h='',$collapsible=0)
7494 {
7495 // Added collapsible to allow collapsible top-margin on new page
7496 //Line feed; default value is last cell height
7497 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
7498 if ($collapsible && ($this->y==$this->tMargin) && (!$this->ColActive)) { $h = 0; }
7499 if(is_string($h)) $this->y+=$this->lasth;
7500 else $this->y+=$h;
7501 }
7502
7503 /*-- HTML-CSS --*/
7504 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
7505 function DivLn($h,$level=-3,$move_y=true,$collapsible=false,$state=0) {
7506 // this->x is returned as it was
7507 // adds lines (y) where DIV bgcolors are filled in
7508 // allows .00001 as nominal height used for bookmarks/annotations etc.
7509 if ($collapsible && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->tMargin)) && (!$this->ColActive)) { return; }
7510 if ($collapsible && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->y0)) && ($this->ColActive) && $this->CurrCol == 0) { return; } // *COLUMNS*
7511
7512 // Still use this method if columns or page-break-inside: avoid, as it allows repositioning later
7513 // otherwise, now uses PaintDivBB()
7514 if (!$this->ColActive && !$this->keep_block_together && !$this->kwt) {
7515 if ($move_y && !$this->ColActive) { $this->y += $h; }
7516 return;
7517 }
7518
7519 if ($level == -3) { $level = $this->blklvl; }
7520 $firstblockfill = $this->GetFirstBlockFill();
7521 if ($firstblockfill && $this->blklvl > 0 && $this->blklvl >= $firstblockfill) {
7522 $last_x = 0;
7523 $last_w = 0;
7524 $last_fc = $this->FillColor;
7525 $bak_x = $this->x;
7526 $bak_h = $this->divheight;
7527 $this->divheight = 0; // Temporarily turn off divheight - as Cell() uses it to check for PageBreak
7528 for ($blvl=$firstblockfill;$blvl<=$level;$blvl++) {
7529 $this->SetBlockFill($blvl);
7530 $this->x = $this->lMargin + $this->blk[$blvl]['outer_left_margin'];
7531 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
7532 $x = $this->x;
7533 $this->Cell( ($this->blk[$blvl]['width']), $h, '', '', 0, '', 1);
7534 if (!$this->keep_block_together && !$this->writingHTMLheader && !$this->writingHTMLfooter) {
7535 $this->x = $x;
7536 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
7537 if ($blvl == $this->blklvl) { $this->PaintDivLnBorder($state,$blvl,$h); }
7538 else { $this->PaintDivLnBorder(0,$blvl,$h); }
7539 }
7540 }
7541 $last_x = $this->lMargin + $this->blk[$blvl]['outer_left_margin'];
7542 $last_w = $this->blk[$blvl]['width'];
7543 $last_fc = $this->FillColor;
7544 }
7545 // Reset current block fill
7546 if (isset($this->blk[$this->blklvl]['bgcolorarray'])) {
7547 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
7548 $this->SetFColor($bcor);
7549 }
7550 $this->x = $bak_x;
7551 $this->divheight = $bak_h;
7552 }
7553 if ($move_y) { $this->y += $h; }
7554 }
7555 /*-- END HTML-CSS --*/
7556
7557
7558 function SetX($x)
7559 {
7560 //Set x position
7561 if($x >= 0) $this->x=$x;
7562 else $this->x = $this->w + $x;
7563 }
7564
7565 function SetY($y)
7566 {
7567 //Set y position and reset x
7568 $this->x=$this->lMargin;
7569 if($y>=0)
7570 $this->y=$y;
7571 else
7572 $this->y=$this->h+$y;
7573 }
7574
7575 function SetXY($x,$y)
7576 {
7577 //Set x and y positions
7578 $this->SetY($y);
7579 $this->SetX($x);
7580 }
7581
7582
7583 function Output($name='',$dest='')
7584 {
7585 //Output PDF to some destination
7586 if ($this->showStats) {
7587 echo '<div>Generated in '.sprintf('%.2F',(microtime(true) - $this->time0)).' seconds</div>';
7588 }
7589 //Finish document if necessary
7590 if ($this->progressBar) { $this->UpdateProgressBar(1,'100','Finished'); } // *PROGRESS-BAR*
7591 if($this->state < 3) $this->Close();
7592 if ($this->progressBar) { $this->UpdateProgressBar(2,'100','Finished'); } // *PROGRESS-BAR*
7593 // fn. error_get_last is only in PHP>=5.2
7594 if ($this->debug && function_exists('error_get_last') && error_get_last()) {
7595 $e = error_get_last();
7596 if (($e['type'] < 2048 && $e['type'] != 8) || (intval($e['type']) & intval(ini_get("error_reporting")))) {
7597 echo "<p>Error message detected - PDF file generation aborted.</p>";
7598 echo $e['message'].'<br />';
7599 echo 'File: '.$e['file'].'<br />';
7600 echo 'Line: '.$e['line'].'<br />';
7601 exit;
7602 }
7603 }
7604
7605
7606 if (($this->PDFA || $this->PDFX) && $this->encrypted) { $this->Error("PDFA1-b or PDFX/1-a does not permit encryption of documents."); }
7607 if (count($this->PDFAXwarnings) && (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto))) {
7608 if ($this->PDFA) {
7609 echo '<div>WARNING - This file could not be generated as it stands as a PDFA1-b compliant file.</div>';
7610 echo '<div>These issues can be automatically fixed by mPDF using <i>$mpdf-&gt;PDFAauto=true;</i></div>';
7611 echo '<div>Action that mPDF will take to automatically force PDFA1-b compliance are shown in brackets.</div>';
7612 }
7613 else {
7614 echo '<div>WARNING - This file could not be generated as it stands as a PDFX/1-a compliant file.</div>';
7615 echo '<div>These issues can be automatically fixed by mPDF using <i>$mpdf-&gt;PDFXauto=true;</i></div>';
7616 echo '<div>Action that mPDF will take to automatically force PDFX/1-a compliance are shown in brackets.</div>';
7617 }
7618 echo '<div>Warning(s) generated:</div><ul>';
7619 $this->PDFAXwarnings = array_unique($this->PDFAXwarnings);
7620 foreach($this->PDFAXwarnings AS $w) {
7621 echo '<li>'.$w.'</li>';
7622 }
7623 echo '</ul>';
7624 exit;
7625 }
7626
7627 if ($this->showStats) {
7628 echo '<div>Compiled in '.sprintf('%.2F',(microtime(true) - $this->time0)).' seconds (total)</div>';
7629 echo '<div>Peak Memory usage '.number_format((memory_get_peak_usage(true)/(1024*1024)),2).' MB</div>';
7630 echo '<div>PDF file size '.number_format((strlen($this->buffer)/1024)).' kB</div>';
7631 echo '<div>Number of fonts '.count($this->fonts).'</div>';
7632 exit;
7633 }
7634
7635
7636 if(is_bool($dest)) $dest=$dest ? 'D' : 'F';
7637 $dest=strtoupper($dest);
7638 if($dest=='') {
7639 if($name=='') {
7640 $name='mpdf.pdf';
7641 $dest='I';
7642 }
7643 else { $dest='F'; }
7644 }
7645
7646 /*-- PROGRESS-BAR --*/
7647 if ($this->progressBar && ($dest=='D' || $dest=='I')) {
7648 if($name=='') { $name='mpdf.pdf'; }
7649 $tempfile = '_tempPDF'.uniqid(rand(1,100000),true);
7650 //Save to local file
7651 $f=fopen(_MPDF_TEMP_PATH.$tempfile.'.pdf','wb');
7652 if(!$f) $this->Error('Unable to create temporary output file: '.$tempfile.'.pdf');
7653 fwrite($f,$this->buffer,strlen($this->buffer));
7654 fclose($f);
7655 $this->UpdateProgressBar(3,'','Finished');
7656
7657 echo '<script type="text/javascript">
7658
7659 var form = document.createElement("form");
7660 form.setAttribute("method", "post");
7661 form.setAttribute("action", "'._MPDF_URI.'includes/out.php");
7662
7663 var hiddenField = document.createElement("input");
7664 hiddenField.setAttribute("type", "hidden");
7665 hiddenField.setAttribute("name", "filename");
7666 hiddenField.setAttribute("value", "'.$tempfile.'");
7667 form.appendChild(hiddenField);
7668
7669 var hiddenField = document.createElement("input");
7670 hiddenField.setAttribute("type", "hidden");
7671 hiddenField.setAttribute("name", "dest");
7672 hiddenField.setAttribute("value", "'.$dest.'");
7673 form.appendChild(hiddenField);
7674
7675 var hiddenField = document.createElement("input");
7676 hiddenField.setAttribute("type", "hidden");
7677 hiddenField.setAttribute("name", "opname");
7678 hiddenField.setAttribute("value", "'.$name.'");
7679 form.appendChild(hiddenField);
7680
7681 var hiddenField = document.createElement("input");
7682 hiddenField.setAttribute("type", "hidden");
7683 hiddenField.setAttribute("name", "path");
7684 hiddenField.setAttribute("value", "'.urlencode(_MPDF_TEMP_PATH).'");
7685 form.appendChild(hiddenField);
7686
7687 document.body.appendChild(form);
7688 form.submit();
7689
7690 </script>
7691 </div>
7692 </body>
7693 </html>';
7694 exit;
7695 }
7696 else {
7697 if ($this->progressBar) { $this->UpdateProgressBar(3,'','Finished'); }
7698 /*-- END PROGRESS-BAR --*/
7699
7700 switch($dest) {
7701 case 'I':
7702 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; }
7703 //Send to standard output
7704 if(PHP_SAPI!='cli') {
7705 //We send to a browser
7706 header('Content-Type: application/pdf');
7707 if(headers_sent())
7708 $this->Error('Some data has already been output to browser, can\'t send PDF file');
7709 if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
7710 // don't use length if server using compression
7711 header('Content-Length: '.strlen($this->buffer));
7712 }
7713 header('Content-disposition: inline; filename="'.$name.'"');
7714 header('Cache-Control: public, must-revalidate, max-age=0');
7715 header('Pragma: public');
7716 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
7717 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
7718 }
7719 echo $this->buffer;
7720 break;
7721 case 'D':
7722 //Download file
7723 header('Content-Description: File Transfer');
7724 if (headers_sent())
7725 $this->Error('Some data has already been output to browser, can\'t send PDF file');
7726 header('Content-Transfer-Encoding: binary');
7727 header('Cache-Control: public, must-revalidate, max-age=0');
7728 header('Pragma: public');
7729 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
7730 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
7731 header('Content-Type: application/force-download');
7732 header('Content-Type: application/octet-stream', false);
7733 header('Content-Type: application/download', false);
7734 header('Content-Type: application/pdf', false);
7735 if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
7736 // don't use length if server using compression
7737 header('Content-Length: '.strlen($this->buffer));
7738 }
7739 header('Content-disposition: attachment; filename="'.$name.'"');
7740 echo $this->buffer;
7741 break;
7742 case 'F':
7743 //Save to local file
7744 $f=fopen($name,'wb');
7745 if(!$f) $this->Error('Unable to create output file: '.$name);
7746 fwrite($f,$this->buffer,strlen($this->buffer));
7747 fclose($f);
7748 break;
7749 case 'S':
7750 //Return as a string
7751 return $this->buffer;
7752 default:
7753 $this->Error('Incorrect output destination: '.$dest);
7754 }
7755
7756 } // *PROGRESS-BAR*
7757 //======================================================================================================
7758 // DELETE OLD TMP FILES - Housekeeping
7759 // Delete any files in tmp/ directory that are >1 hrs old
7760 $interval = 3600;
7761 if ($handle = @opendir(preg_replace('/\/$/','',_MPDF_TEMP_PATH))) { // mPDF 5.7.3
7762 while (false !== ($file = readdir($handle))) {
7763 if (($file != "..") && ($file != ".") && !is_dir($file) && ((filemtime(_MPDF_TEMP_PATH.$file)+$interval) < time()) && (substr($file, 0, 1) !== '.') && ($file !='dummy.txt')) { // mPDF 5.7.3
7764 unlink(_MPDF_TEMP_PATH.$file);
7765 }
7766 }
7767 closedir($handle);
7768 }
7769 //==============================================================================================================
7770
7771 return '';
7772 }
7773
7774
7775 // *****************************************************************************
7776 // *
7777 // Protected methods *
7778 // *
7779 // *****************************************************************************
7780 function _dochecks()
7781 {
7782 //Check for locale-related bug
7783 if(1.1==1)
7784 $this->Error('Don\'t alter the locale before including mPDF');
7785 //Check for decimal separator
7786 if(sprintf('%.1f',1.0)!='1.0')
7787 setlocale(LC_NUMERIC,'C');
7788 // mPDF 5.4.11
7789 $mqr=ini_get("magic_quotes_runtime");
7790 if ($mqr) { $this->Error('mPDF requires magic_quotes_runtime to be turned off e.g. by using ini_set("magic_quotes_runtime", 0);'); }
7791 }
7792
7793 function _begindoc()
7794 {
7795 //Start document
7796 $this->state=1;
7797 $this->_out('%PDF-'.$this->pdf_version);
7798 $this->_out('%'.chr(226).chr(227).chr(207).chr(211)); // 4 chars > 128 to show binary file
7799 }
7800
7801
7802 /*-- HTMLHEADERS-FOOTERS --*/
7803 function _puthtmlheaders() {
7804 $this->state=2;
7805 $nb=$this->page;
7806 for($n=1;$n<=$nb;$n++) {
7807 if ($this->mirrorMargins && $n%2==0) { $OE = 'E'; } // EVEN
7808 else { $OE = 'O'; }
7809 $this->page = $n;
7810 if (isset($this->saveHTMLHeader[$n][$OE])) {
7811 $html = $this->saveHTMLHeader[$n][$OE]['html'];
7812 $this->lMargin = $this->saveHTMLHeader[$n][$OE]['ml'];
7813 $this->rMargin = $this->saveHTMLHeader[$n][$OE]['mr'];
7814 $this->tMargin = $this->saveHTMLHeader[$n][$OE]['mh'];
7815 $this->bMargin = $this->saveHTMLHeader[$n][$OE]['mf'];
7816 $this->margin_header = $this->saveHTMLHeader[$n][$OE]['mh'];
7817 $this->margin_footer = $this->saveHTMLHeader[$n][$OE]['mf'];
7818 $this->w = $this->saveHTMLHeader[$n][$OE]['pw'];
7819 $this->h = $this->saveHTMLHeader[$n][$OE]['ph'];
7820 $rotate = (isset($this->saveHTMLHeader[$n][$OE]['rotate']) ? $this->saveHTMLHeader[$n][$OE]['rotate'] : null);
7821 $this->Reset();
7822 $this->pageoutput[$n] = array();
7823 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
7824 $this->x = $this->lMargin;
7825 $this->y = $this->margin_header;
7826 // mPDF 5.6.47
7827 $pn = $this->docPageNum($n);
7828 if ($pn)
7829 $pnstr = $this->pagenumPrefix.$pn.$this->pagenumSuffix;
7830 else { $pnstr = ''; }
7831 $html = str_replace('{PAGENO}',$pnstr,$html);
7832 $pnt = $this->docPageNumTotal($n);
7833 if ($pnt)
7834 $pntstr = $this->nbpgPrefix.$pnt.$this->nbpgSuffix;
7835 else { $pntstr = ''; }
7836 $html = str_replace($this->aliasNbPgGp,$pntstr,$html ); // {nbpg}
7837 $html = str_replace($this->aliasNbPg,$nb,$html ); // {nb}
7838 $html = preg_replace_callback('/\{DATE\s+(.*?)\}/', array($this, 'date_callback') ,$html ); // mPDF 5.7
7839
7840 $this->HTMLheaderPageLinks = array();
7841 $this->HTMLheaderPageAnnots = array();
7842 $this->HTMLheaderPageForms = array();
7843 $this->pageBackgrounds = array();
7844
7845 $this->writingHTMLheader = true;
7846 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
7847 $this->writingHTMLheader = false;
7848 $this->Reset();
7849 $this->pageoutput[$n] = array();
7850
7851 $s = $this->PrintPageBackgrounds();
7852 $this->headerbuffer = $s . $this->headerbuffer;
7853 $os = '';
7854 if ($rotate) {
7855 $os .= sprintf('q 0 -1 1 0 0 %.3F cm ',($this->w*_MPDFK));
7856 }
7857 $os .= $this->headerbuffer ;
7858 if ($rotate) {
7859 $os .= ' Q' . "\n";
7860 }
7861
7862 // Writes over the page background but behind any other output on page
7863 $os = preg_replace('/\\\\/','\\\\\\\\',$os);
7864 $this->pages[$n] = preg_replace('/(___HEADER___MARKER'.$this->uniqstr.')/', "\n".$os."\n".'\\1', $this->pages[$n]);
7865
7866 $lks = $this->HTMLheaderPageLinks;
7867 foreach($lks AS $lk) {
7868 if ($rotate) {
7869 $lw = $lk[2];
7870 $lh = $lk[3];
7871 $lk[2] = $lh;
7872 $lk[3] = $lw; // swap width and height
7873 $ax = $lk[0]/_MPDFK;
7874 $ay = $lk[1]/_MPDFK;
7875 $bx = $ay-($lh/_MPDFK);
7876 $by = $this->w-$ax;
7877 $lk[0] = $bx*_MPDFK;
7878 $lk[1] = ($this->h-$by)*_MPDFK - $lw;
7879 }
7880 $this->PageLinks[$n][]=$lk;
7881 }
7882 /*-- FORMS --*/
7883 foreach($this->HTMLheaderPageForms AS $f) {
7884 $this->form->forms[$f['n']] = $f;
7885 }
7886 /*-- END FORMS --*/
7887
7888
7889 }
7890 if (isset($this->saveHTMLFooter[$n][$OE])) {
7891 $html = $this->saveHTMLFooter[$this->page][$OE]['html'];
7892 $this->lMargin = $this->saveHTMLFooter[$n][$OE]['ml'];
7893 $this->rMargin = $this->saveHTMLFooter[$n][$OE]['mr'];
7894 $this->tMargin = $this->saveHTMLFooter[$n][$OE]['mh'];
7895 $this->bMargin = $this->saveHTMLFooter[$n][$OE]['mf'];
7896 $this->margin_header = $this->saveHTMLFooter[$n][$OE]['mh'];
7897 $this->margin_footer = $this->saveHTMLFooter[$n][$OE]['mf'];
7898 $this->w = $this->saveHTMLFooter[$n][$OE]['pw'];
7899 $this->h = $this->saveHTMLFooter[$n][$OE]['ph'];
7900 $rotate = (isset($this->saveHTMLFooter[$n][$OE]['rotate']) ? $this->saveHTMLFooter[$n][$OE]['rotate'] : null);
7901 $this->Reset();
7902 $this->pageoutput[$n] = array();
7903 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
7904 $this->x = $this->lMargin;
7905 $top_y = $this->y = $this->h - $this->margin_footer;
7906
7907 // if bottom-margin==0, corrects to avoid division by zero
7908 if ($this->y == $this->h) { $top_y = $this->y = ($this->h - 0.1); }
7909 // mPDF 5.6.47
7910 $pn = $this->docPageNum($n);
7911 if ($pn)
7912 $pnstr = $this->pagenumPrefix.$pn.$this->pagenumSuffix;
7913 else { $pnstr = ''; }
7914 $html = str_replace('{PAGENO}',$pnstr,$html);
7915 $pnt = $this->docPageNumTotal($n);
7916 if ($pnt)
7917 $pntstr = $this->nbpgPrefix.$pnt.$this->nbpgSuffix;
7918 else { $pntstr = ''; }
7919 $html = str_replace($this->aliasNbPgGp,$pntstr,$html ); // {nbpg}
7920 $html = str_replace($this->aliasNbPg,$nb,$html ); // {nb}
7921 $html = preg_replace_callback('/\{DATE\s+(.*?)\}/', array($this, 'date_callback') ,$html ); // mPDF 5.7
7922
7923
7924 $this->HTMLheaderPageLinks = array();
7925 $this->HTMLheaderPageAnnots = array();
7926 $this->HTMLheaderPageForms = array();
7927 $this->pageBackgrounds = array();
7928
7929 $this->writingHTMLfooter = true;
7930 $this->InFooter = true;
7931 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
7932 $this->InFooter = false;
7933 $this->Reset();
7934 $this->pageoutput[$n] = array();
7935
7936 $fheight = $this->y - $top_y;
7937 $adj = -$fheight;
7938
7939 $s = $this->PrintPageBackgrounds(-$adj);
7940 $this->headerbuffer = $s . $this->headerbuffer;
7941 $this->writingHTMLfooter = false; // mPDF 5.7.3 (moved after PrintPageBackgrounds so can adjust position of images in footer)
7942
7943 $os = '';
7944 $os .= $this->StartTransform(true)."\n";
7945 if ($rotate) {
7946 $os .= sprintf('q 0 -1 1 0 0 %.3F cm ',($this->w*_MPDFK));
7947 }
7948 $os .= $this->transformTranslate(0, $adj, true)."\n";
7949 $os .= $this->headerbuffer ;
7950 if ($rotate) {
7951 $os .= ' Q' . "\n";
7952 }
7953 $os .= $this->StopTransform(true)."\n";
7954 // Writes over the page background but behind any other output on page
7955 $os = preg_replace('/\\\\/','\\\\\\\\',$os);
7956 $this->pages[$n] = preg_replace('/(___HEADER___MARKER'.$this->uniqstr.')/', "\n".$os."\n".'\\1', $this->pages[$n]);
7957
7958 $lks = $this->HTMLheaderPageLinks;
7959 foreach($lks AS $lk) {
7960 $lk[1] -= $adj*_MPDFK;
7961 if ($rotate) {
7962 $lw = $lk[2];
7963 $lh = $lk[3];
7964 $lk[2] = $lh;
7965 $lk[3] = $lw; // swap width and height
7966
7967 $ax = $lk[0]/_MPDFK;
7968 $ay = $lk[1]/_MPDFK;
7969 $bx = $ay-($lh/_MPDFK);
7970 $by = $this->w-$ax;
7971 $lk[0] = $bx*_MPDFK;
7972 $lk[1] = ($this->h-$by)*_MPDFK - $lw;
7973 }
7974 $this->PageLinks[$n][]=$lk;
7975 }
7976 /*-- FORMS --*/
7977 foreach($this->HTMLheaderPageForms AS $f) {
7978 $f['y'] += $adj;
7979 $this->form->forms[$f['n']] = $f;
7980 }
7981 /*-- END FORMS --*/
7982 }
7983 }
7984 $this->page=$nb;
7985 $this->state=1;
7986 }
7987 /*-- END HTMLHEADERS-FOOTERS --*/
7988
7989
7990 function _putpages()
7991 {
7992 $nb=$this->page;
7993 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
7994
7995 if($this->DefOrientation=='P') {
7996 $defwPt=$this->fwPt;
7997 $defhPt=$this->fhPt;
7998 }
7999 else {
8000 $defwPt=$this->fhPt;
8001 $defhPt=$this->fwPt;
8002 }
8003 $annotid=(3+2*$nb);
8004
8005 // Active Forms
8006 $totaladdnum = 0;
8007 for($n=1;$n<=$nb;$n++) {
8008 if (isset($this->PageLinks[$n])) { $totaladdnum += count($this->PageLinks[$n]); }
8009 /*-- ANNOTATIONS --*/
8010 if (isset($this->PageAnnots[$n])) {
8011 foreach ($this->PageAnnots[$n] as $k => $pl) {
8012 if (!empty($pl['opt']['popup']) || !empty($pl['opt']['file'])) { $totaladdnum += 2 ; }
8013 else { $totaladdnum++; }
8014 }
8015 }
8016 /*-- END ANNOTATIONS --*/
8017
8018 /*-- FORMS --*/
8019 if ( count($this->form->forms) > 0 ) {
8020 $this->form->countPageForms($n, $totaladdnum);
8021 }
8022 /*-- END FORMS --*/
8023 }
8024 /*-- FORMS --*/
8025 // Make a note in the radio button group of the obj_id it will have
8026 $ctr = 0;
8027 if (count($this->form->form_radio_groups)) {
8028 foreach($this->form->form_radio_groups AS $name=>$frg) {
8029 $this->form->form_radio_groups[$name]['obj_id'] = $annotid + $totaladdnum + $ctr;
8030 $ctr++;
8031 }
8032 }
8033 /*-- END FORMS --*/
8034
8035 // Select unused fonts (usually default font)
8036 $unused = array();
8037 foreach($this->fonts as $fk=>$font) {
8038 if (!$font['used'] && ($font['type']=='TTF')) {
8039 $unused[] = $fk;
8040 }
8041 }
8042
8043
8044 for($n=1;$n<=$nb;$n++)
8045 {
8046 $thispage = $this->pages[$n];
8047 // unset($this->pages[$n]); // mPDF 5.6.47
8048 if(isset($this->OrientationChanges[$n])) {
8049 $hPt=$this->pageDim[$n]['w']*_MPDFK;
8050 $wPt=$this->pageDim[$n]['h']*_MPDFK;
8051 $owidthPt_LR = $this->pageDim[$n]['outer_width_TB']*_MPDFK;
8052 $owidthPt_TB = $this->pageDim[$n]['outer_width_LR']*_MPDFK;
8053 }
8054 else {
8055 $wPt=$this->pageDim[$n]['w']*_MPDFK;
8056 $hPt=$this->pageDim[$n]['h']*_MPDFK;
8057 $owidthPt_LR = $this->pageDim[$n]['outer_width_LR']*_MPDFK;
8058 $owidthPt_TB = $this->pageDim[$n]['outer_width_TB']*_MPDFK;
8059 }
8060 // Remove references to unused fonts (usually default font)
8061 foreach($unused as $fk) {
8062 if ($this->fonts[$fk]['sip'] || $this->fonts[$fk]['smp']) {
8063 foreach($this->fonts[$fk]['subsetfontids'] AS $k => $fid) {
8064 $thispage = preg_replace('/\s\/F'.$fid.' \d[\d.]* Tf\s/is',' ',$thispage);
8065 }
8066 }
8067 else {
8068 $thispage = preg_replace('/\s\/F'.$this->fonts[$fk]['i'].' \d[\d.]* Tf\s/is',' ',$thispage);
8069 }
8070 }
8071 //Replace number of pages
8072 if(!empty($this->aliasNbPg)) {
8073 if (!$this->onlyCoreFonts) { $s1 = $this->UTF8ToUTF16BE($this->aliasNbPg, false); }
8074 $s2 = $this->aliasNbPg;
8075 if (!$this->onlyCoreFonts) { $r1 = $this->UTF8ToUTF16BE($nb, false); }
8076 $r2 = $nb;
8077 if (preg_match_all('/{mpdfheadernbpg (C|R) ff=(\S*) fs=(\S*) fz=(.*?)}/',$thispage,$m)) {
8078 for($hi=0;$hi<count($m[0]);$hi++) {
8079 $pos = $m[1][$hi];
8080 $hff = $m[2][$hi];
8081 $hfst = $m[3][$hi];
8082 $hfsz = $m[4][$hi];
8083 $this->SetFont($hff,$hfst,$hfsz, false);
8084 $x1 = $this->GetStringWidth($this->aliasNbPg);
8085 $x2 = $this->GetStringWidth($nb);
8086 $xadj = $x1 - $x2;
8087 if ($pos=='C') { $xadj /= 2; }
8088 $rep = sprintf(' q 1 0 0 1 %.3F 0 cm ', $xadj*_MPDFK);
8089 $thispage = str_replace($m[0][$hi], $rep, $thispage);
8090 }
8091 }
8092 if (!$this->onlyCoreFonts) { $thispage=str_replace($s1,$r1,$thispage); }
8093 $thispage=str_replace($s2,$r2,$thispage);
8094
8095 // And now for any SMP/SIP fonts subset using <HH> format
8096 $r = '';
8097 $nstr = "$nb";
8098 for($i=0;$i<strlen($nstr);$i++) {
8099 $r .= sprintf("%02s", strtoupper(dechex(intval($nstr[$i])+48)));
8100 }
8101 $thispage=str_replace($this->aliasNbPgHex,$r,$thispage);
8102
8103 }
8104 //Replace number of pages in group
8105 if(!empty($this->aliasNbPgGp)) {
8106 if (!$this->onlyCoreFonts) { $s1 = $this->UTF8ToUTF16BE($this->aliasNbPgGp, false); }
8107 $s2 = $this->aliasNbPgGp;
8108 $nbt = $this->docPageNumTotal($n);
8109 if (!$this->onlyCoreFonts) { $r1 = $this->UTF8ToUTF16BE($nbt, false); }
8110 $r2 = $nbt;
8111 if (preg_match_all('/{mpdfheadernbpggp (C|R) ff=(\S*) fs=(\S*) fz=(.*?)}/',$thispage,$m)) {
8112 for($hi=0;$hi<count($m[0]);$hi++) {
8113 $pos = $m[1][$hi];
8114 $hff = $m[2][$hi];
8115 $hfst = $m[3][$hi];
8116 $hfsz = $m[4][$hi];
8117 $this->SetFont($hff,$hfst,$hfsz, false);
8118 $x1 = $this->GetStringWidth($this->aliasNbPgGp);
8119 $x2 = $this->GetStringWidth($nbt);
8120 $xadj = $x1 - $x2;
8121 if ($pos=='C') { $xadj /= 2; }
8122 $rep = sprintf(' q 1 0 0 1 %.3F 0 cm ', $xadj*_MPDFK);
8123 $thispage = str_replace($m[0][$hi], $rep, $thispage);
8124 }
8125 }
8126 if (!$this->onlyCoreFonts) { $thispage=str_replace($s1,$r1,$thispage); }
8127 $thispage=str_replace($s2,$r2,$thispage);
8128
8129 // And now for any SMP/SIP fonts subset using <HH> format
8130 $r = '';
8131 $nstr = "$nbt";
8132 for($i=0;$i<strlen($nstr);$i++) {
8133 $r .= sprintf("%02s", strtoupper(dechex(intval($nstr[$i])+48)));
8134 }
8135 $thispage=str_replace($this->aliasNbPgGpHex,$r,$thispage);
8136
8137 }
8138 $thispage = preg_replace('/(\s*___BACKGROUND___PATTERNS'.$this->uniqstr.'\s*)/', " ", $thispage);
8139 $thispage = preg_replace('/(\s*___HEADER___MARKER'.$this->uniqstr.'\s*)/', " ", $thispage);
8140 $thispage = preg_replace('/(\s*___PAGE___START'.$this->uniqstr.'\s*)/', " ", $thispage);
8141 $thispage = preg_replace('/(\s*___TABLE___BACKGROUNDS'.$this->uniqstr.'\s*)/', " ", $thispage);
8142 // mPDF 5.7.3 TRANSFORMS
8143 while (preg_match('/(\% BTR(.*?)\% ETR)/is', $thispage, $m)) {
8144 $thispage = preg_replace('/(\% BTR.*?\% ETR)/is', '', $thispage, 1)."\n".$m[2];
8145 }
8146
8147 //Page
8148 $this->_newobj();
8149 $this->_out('<</Type /Page');
8150 $this->_out('/Parent 1 0 R');
8151 if(isset($this->OrientationChanges[$n])) {
8152 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$hPt,$wPt));
8153 //If BleedBox is defined, it must be larger than the TrimBox, but smaller than the MediaBox
8154 $bleedMargin = $this->pageDim[$n]['bleedMargin']*_MPDFK;
8155 if ($bleedMargin && ($owidthPt_TB || $owidthPt_LR)) {
8156 $x0 = $owidthPt_TB-$bleedMargin;
8157 $y0 = $owidthPt_LR-$bleedMargin;
8158 $x1 = $hPt-$owidthPt_TB+$bleedMargin;
8159 $y1 = $wPt-$owidthPt_LR+$bleedMargin;
8160 $this->_out(sprintf('/BleedBox [%.3F %.3F %.3F %.3F]', $x0, $y0, $x1, $y1));
8161 }
8162 $this->_out(sprintf('/TrimBox [%.3F %.3F %.3F %.3F]', $owidthPt_TB, $owidthPt_LR, ($hPt-$owidthPt_TB), ($wPt-$owidthPt_LR)));
8163 if (isset($this->OrientationChanges[$n]) && $this->displayDefaultOrientation) {
8164 if ($this->DefOrientation=='P') { $this->_out('/Rotate 270'); }
8165 else { $this->_out('/Rotate 90'); }
8166 }
8167 }
8168 //else if($wPt != $defwPt || $hPt != $defhPt) {
8169 else {
8170 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$wPt,$hPt));
8171 $bleedMargin = $this->pageDim[$n]['bleedMargin']*_MPDFK;
8172 if ($bleedMargin && ($owidthPt_TB || $owidthPt_LR)) {
8173 $x0 = $owidthPt_LR-$bleedMargin;
8174 $y0 = $owidthPt_TB-$bleedMargin;
8175 $x1 = $wPt-$owidthPt_LR+$bleedMargin;
8176 $y1 = $hPt-$owidthPt_TB+$bleedMargin;
8177 $this->_out(sprintf('/BleedBox [%.3F %.3F %.3F %.3F]', $x0, $y0, $x1, $y1));
8178 }
8179 $this->_out(sprintf('/TrimBox [%.3F %.3F %.3F %.3F]', $owidthPt_LR, $owidthPt_TB, ($wPt-$owidthPt_LR), ($hPt-$owidthPt_TB)));
8180 }
8181 $this->_out('/Resources 2 0 R');
8182
8183 // Important to keep in RGB colorSpace when using transparency
8184 if (!$this->PDFA && !$this->PDFX) {
8185 if ($this->restrictColorSpace == 3)
8186 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceCMYK >> ');
8187 else if ($this->restrictColorSpace == 1)
8188 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceGray >> ');
8189 else
8190 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceRGB >> ');
8191 }
8192
8193 $annotsnum = 0;
8194 $embeddedfiles = array(); // mPDF 5.7.2 /EmbeddedFiles
8195
8196 if (isset($this->PageLinks[$n])) { $annotsnum += count($this->PageLinks[$n]); }
8197 /*-- ANNOTATIONS --*/
8198 if (isset($this->PageAnnots[$n])) {
8199 foreach ($this->PageAnnots[$n] as $k => $pl) {
8200 if (!empty($pl['opt']['file'])) { $embeddedfiles[$annotsnum+1] = true ; } // mPDF 5.7.2 /EmbeddedFiles
8201 if (!empty($pl['opt']['popup']) || !empty($pl['opt']['file'])) { $annotsnum += 2 ; }
8202 else { $annotsnum++; }
8203 $this->PageAnnots[$n][$k]['pageobj'] = $this->n;
8204 }
8205 }
8206 /*-- END ANNOTATIONS --*/
8207
8208 /*-- FORMS --*/
8209 // Active Forms
8210 $formsnum = 0;
8211 if ( count($this->form->forms) > 0 ) {
8212 foreach( $this->form->forms as $val ) {
8213 if ( $val['page'] == $n )
8214 $formsnum++;
8215 }
8216 }
8217 /*-- END FORMS --*/
8218 if ($annotsnum || $formsnum) {
8219 $s = '/Annots [ ';
8220 for($i=0;$i<$annotsnum;$i++) {
8221 if (!isset($embeddedfiles[$i])) { $s .= ($annotid + $i) . ' 0 R '; } // mPDF 5.7.2 /EmbeddedFiles
8222 }
8223 $annotid += $annotsnum;
8224 /*-- FORMS --*/
8225 if ( count($this->form->forms) > 0 ) {
8226 $this->form->addFormIds($n, $s, $annotid);
8227 }
8228 /*-- END FORMS --*/
8229 $s .= '] ';
8230 $this->_out($s);
8231 }
8232
8233 $this->_out('/Contents '.($this->n+1).' 0 R>>');
8234 $this->_out('endobj');
8235
8236 //Page content
8237 $this->_newobj();
8238 $p=($this->compress) ? gzcompress($thispage) : $thispage;
8239 $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
8240 $this->_putstream($p);
8241 $this->_out('endobj');
8242 }
8243 $this->_putannots(); // mPDF 5.7.2
8244
8245 //Pages root
8246 $this->offsets[1]=strlen($this->buffer);
8247 $this->_out('1 0 obj');
8248 $this->_out('<</Type /Pages');
8249 $kids='/Kids [';
8250 for($i=0;$i<$nb;$i++)
8251 $kids.=(3+2*$i).' 0 R ';
8252 $this->_out($kids.']');
8253 $this->_out('/Count '.$nb);
8254 $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$defwPt,$defhPt));
8255 $this->_out('>>');
8256 $this->_out('endobj');
8257 }
8258
8259
8260 function _putannots() { // mPDF 5.7.2
8261 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
8262 $nb=$this->page;
8263 for($n=1;$n<=$nb;$n++)
8264 {
8265 $annotobjs = array();
8266 if(isset($this->PageLinks[$n]) || isset($this->PageAnnots[$n]) || count($this->form->forms) > 0 ) {
8267 $wPt=$this->pageDim[$n]['w']*_MPDFK;
8268 $hPt=$this->pageDim[$n]['h']*_MPDFK;
8269
8270 //Links
8271 if(isset($this->PageLinks[$n])) {
8272 foreach($this->PageLinks[$n] as $key => $pl) {
8273 $this->_newobj();
8274 $annot='';
8275 $rect=sprintf('%.3F %.3F %.3F %.3F',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
8276 $annot .= '<</Type /Annot /Subtype /Link /Rect ['.$rect.']';
8277 $annot .= ' /Contents '.$this->_UTF16BEtextstring($pl[4]);
8278 $annot .= ' /NM '.$this->_textstring(sprintf('%04u-%04u', $n, $key));
8279 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
8280 $annot .= ' /Border [0 0 0]';
8281 // Use this (instead of /Border) to specify border around link
8282 // $annot .= ' /BS <</W 1'; // Width on points; 0 = no line
8283 // $annot .= ' /S /D'; // style - [S]olid, [D]ashed, [B]eveled, [I]nset, [U]nderline
8284 // $annot .= ' /D [3 2]'; // Dash array - if dashed
8285 // $annot .= ' >>';
8286 // $annot .= ' /C [1 0 0]'; // Color RGB
8287
8288 if ($this->PDFA || $this->PDFX) { $annot .= ' /F 28'; }
8289 if (strpos($pl[4],'@')===0) {
8290 $p=substr($pl[4],1);
8291 // $h=isset($this->OrientationChanges[$p]) ? $wPt : $hPt;
8292 $htarg=$this->pageDim[$p]['h']*_MPDFK;
8293 $annot.=sprintf(' /Dest [%d 0 R /XYZ 0 %.3F null]>>',1+2*$p,$htarg);
8294 }
8295 else if(is_string($pl[4])) {
8296 $annot .= ' /A <</S /URI /URI '.$this->_textstring($pl[4]).'>> >>';
8297 }
8298 else {
8299 $l=$this->links[$pl[4]];
8300 // may not be set if #link points to non-existent target
8301 if (isset($this->pageDim[$l[0]]['h'])) { $htarg=$this->pageDim[$l[0]]['h']*_MPDFK; }
8302 else { $htarg=$this->h*_MPDFK; } // doesn't really matter
8303 $annot.=sprintf(' /Dest [%d 0 R /XYZ 0 %.3F null]>>',1+2*$l[0],$htarg-$l[1]*_MPDFK);
8304 }
8305 $this->_out($annot);
8306 $this->_out('endobj');
8307 }
8308 }
8309
8310
8311 /*-- ANNOTATIONS --*/
8312 if(isset($this->PageAnnots[$n])) {
8313 foreach ($this->PageAnnots[$n] as $key => $pl) {
8314 if ($pl['opt']['file']) { $FileAttachment=true; }
8315 else { $FileAttachment=false; }
8316 $this->_newobj();
8317 $annot='';
8318 $pl['opt'] = array_change_key_case($pl['opt'], CASE_LOWER);
8319 $x = $pl['x'];
8320 if ($this->annotMargin <> 0 || $x==0 || $x<0) { // Odd page
8321 $x = ($wPt/_MPDFK) - $this->annotMargin;
8322 }
8323 $w = $h = 0;
8324 $a = $x * _MPDFK;
8325 $b = $hPt - ($pl['y'] * _MPDFK);
8326 $annot .= '<</Type /Annot ';
8327 if ($FileAttachment) {
8328 $annot .= '/Subtype /FileAttachment';
8329 // Need to set a size for FileAttachment icons
8330 if ($pl['opt']['icon']=='Paperclip') { $w=8.235; $h=20; } // 7,17
8331 else if ($pl['opt']['icon']=='Tag') { $w=20; $h=16; }
8332 else if ($pl['opt']['icon']=='Graph') { $w=20; $h=20; }
8333 else { $w=14; $h=20; } // PushPin
8334 $f = $pl['opt']['file'];
8335 $f = preg_replace('/^.*\//', '', $f);
8336 $f = preg_replace('/[^a-zA-Z0-9._]/', '', $f);
8337 $annot .= '/FS <</Type /Filespec /F ('.$f.')';
8338 $annot .= '/EF <</F '.($this->n+1).' 0 R>>';
8339 $annot .= '>>';
8340 }
8341 else {
8342 $annot .= '/Subtype /Text';
8343 }
8344 $rect = sprintf('%.3F %.3F %.3F %.3F', $a, $b-$h, $a+$w, $b);
8345 $annot .= '/Rect ['.$rect.']';
8346
8347 // contents = description of file in free text
8348 $annot .= ' /Contents '.$this->_UTF16BEtextstring($pl['txt']);
8349 $annot .= ' /NM '.$this->_textstring(sprintf('%04u-%04u', $n, (2000 + $key)));
8350 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
8351 $annot .= ' /CreationDate '.$this->_textstring('D:'.date('YmdHis'));
8352 $annot .= ' /Border [0 0 0]';
8353 if ($this->PDFA || $this->PDFX) {
8354 $annot .= ' /F 28';
8355 $annot .= ' /CA 1';
8356 }
8357 else if ($pl['opt']['ca']>0) { $annot .= ' /CA '.$pl['opt']['ca']; }
8358
8359 $annotcolor = ' /C [';
8360 if (isset($pl['opt']['c']) AND $pl['opt']['c']) {
8361 $col = $pl['opt']['c'];
8362 if ($col{0}==3 || $col{0}==5) { $annotcolor .= sprintf("%.3F %.3F %.3F", ord($col{1})/255,ord($col{2})/255,ord($col{3})/255); }
8363 else if ($col{0}==1) { $annotcolor .= sprintf("%.3F", ord($col{1})/255); }
8364 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); }
8365 else { $annotcolor .= '1 1 0'; }
8366 }
8367 else { $annotcolor .= '1 1 0'; }
8368 $annotcolor .= ']';
8369 $annot .= $annotcolor;
8370 // Usually Author
8371 // Use as Title for fileattachment
8372 if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) {
8373 $annot .= ' /T '.$this->_UTF16BEtextstring($pl['opt']['t']);
8374 }
8375 if ($FileAttachment) {
8376 $iconsapp = array('Paperclip', 'Graph', 'PushPin', 'Tag');
8377 }
8378 else { $iconsapp = array('Comment', 'Help', 'Insert', 'Key', 'NewParagraph', 'Note', 'Paragraph'); }
8379 if (isset($pl['opt']['icon']) AND in_array($pl['opt']['icon'], $iconsapp)) {
8380 $annot .= ' /Name /'.$pl['opt']['icon'];
8381 }
8382 else if ($FileAttachment) { $annot .= ' /Name /PushPin'; }
8383 else { $annot .= ' /Name /Note'; }
8384 if (!$FileAttachment) {
8385 // /Subj is PDF 1.5 spec.
8386 if (isset($pl['opt']['subj']) && !$this->PDFA && !$this->PDFX) {
8387 $annot .= ' /Subj '.$this->_UTF16BEtextstring($pl['opt']['subj']);
8388 }
8389 if (!empty($pl['opt']['popup'])) {
8390 $annot .= ' /Open true';
8391 $annot .= ' /Popup '.($this->n+1).' 0 R';
8392 }
8393 else { $annot .= ' /Open false'; }
8394 }
8395 $annot .= ' /P '.$pl['pageobj'].' 0 R';
8396 $annot .= '>>';
8397 $this->_out($annot);
8398 $this->_out('endobj');
8399
8400 if ($FileAttachment) {
8401 $file = @file_get_contents($pl['opt']['file']) or die('mPDF Error: Cannot access file attachment - '.$pl['opt']['file']);
8402 $filestream = gzcompress($file);
8403 $this->_newobj();
8404 $this->_out('<</Type /EmbeddedFile');
8405 $this->_out('/Length '.strlen($filestream));
8406 $this->_out('/Filter /FlateDecode');
8407 $this->_out('>>');
8408 $this->_putstream($filestream);
8409 $this->_out('endobj');
8410 }
8411 else if (!empty($pl['opt']['popup'])) {
8412 $this->_newobj();
8413 $annot='';
8414 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][0])) { $x = $pl['opt']['popup'][0] * _MPDFK; }
8415 else { $x = $pl['x'] * _MPDFK; }
8416 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][1])) { $y = $hPt - ($pl['opt']['popup'][1] * _MPDFK); }
8417 else { $y = $hPt - ($pl['y'] * _MPDFK); }
8418 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][2])) { $w = $pl['opt']['popup'][2] * _MPDFK; }
8419 else { $w = 180; }
8420 if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][3])) { $h = $pl['opt']['popup'][3] * _MPDFK; }
8421 else { $h = 120; }
8422 $rect = sprintf('%.3F %.3F %.3F %.3F', $x, $y-$h, $x+$w, $y);
8423 $annot .= '<</Type /Annot /Subtype /Popup /Rect ['.$rect.']';
8424 $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
8425 if ($this->PDFA || $this->PDFX) { $annot .= ' /F 28'; }
8426 $annot .= ' /Parent '.($this->n-1).' 0 R';
8427 $annot .= '>>';
8428 $this->_out($annot);
8429 $this->_out('endobj');
8430 }
8431 }
8432 }
8433 /*-- END ANNOTATIONS --*/
8434
8435 /*-- FORMS --*/
8436 // Active Forms
8437 if ( count($this->form->forms) > 0 ) {
8438 $this->form->_putFormItems($n, $hPt);
8439 }
8440 /*-- END FORMS --*/
8441 }
8442 }
8443 /*-- FORMS --*/
8444 // Active Forms - Radio Button Group entries
8445 // Output Radio Button Group form entries (radio_on_obj_id already determined)
8446 if (count($this->form->form_radio_groups)) {
8447 $this->form->_putRadioItems($n);
8448 }
8449 /*-- END FORMS --*/
8450 }
8451
8452
8453 /*-- ANNOTATIONS --*/
8454 function Annotation($text, $x=0, $y=0, $icon='Note', $author='', $subject='', $opacity=0, $colarray=false, $popup='', $file='') {
8455 if (is_array($colarray) && count($colarray)==3) { $colarray = $this->ConvertColor('rgb('.$colarray[0].','.$colarray[1].','.$colarray[2].')'); }
8456 if ($colarray === false) { $colarray = $this->ConvertColor('yellow'); }
8457 if ($x==0) { $x = $this->x; }
8458 if ($y==0) { $y = $this->y; }
8459 $page = $this->page;
8460 if ($page < 1) { // Document has not been started - assume it's for first page
8461 $page = 1;
8462 if ($x==0) { $x = $this->lMargin; }
8463 if ($y==0) { $y = $this->tMargin; }
8464 }
8465
8466 if ($this->PDFA || $this->PDFX) {
8467 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)"; }
8468 $x = ($this->w) - $this->rMargin*0.66;
8469 }
8470 if (!$this->annotMargin) { $y -= $this->FontSize / 2; }
8471
8472 if (!$opacity && $this->annotMargin) { $opacity = 1; }
8473 else if (!$opacity) { $opacity = $this->annotOpacity; }
8474
8475 $an = array('txt' => $text, 'x' => $x, 'y' => $y, 'opt' => array('Icon'=>$icon, 'T'=>$author, 'Subj'=>$subject, 'C'=>$colarray, 'CA'=>$opacity, 'popup'=>$popup, 'file'=>$file));
8476
8477 if ($this->keep_block_together) { // Save to array - don't write yet
8478 $this->ktAnnots[$this->page][]= $an;
8479 return;
8480 }
8481 else if ($this->table_rotate) {
8482 $this->tbrot_Annots[$this->page][]= $an;
8483 return;
8484 }
8485 else if ($this->kwt) {
8486 $this->kwt_Annots[$this->page][]= $an;
8487 return;
8488 }
8489 // mPDF 5.0
8490 if ($this->writingHTMLheader || $this->writingHTMLfooter) {
8491 $this->HTMLheaderPageAnnots[]= $an;
8492 return;
8493 }
8494 //Put an Annotation on the page
8495 $this->PageAnnots[$page][] = $an;
8496 /*-- COLUMNS --*/
8497 // Save cross-reference to Column buffer
8498 $ref = count($this->PageAnnots[$this->page])-1;
8499 $this->columnAnnots[$this->CurrCol][INTVAL($this->x)][INTVAL($this->y)] = $ref;
8500 /*-- END COLUMNS --*/
8501 }
8502 /*-- END ANNOTATIONS --*/
8503
8504
8505 function _putfonts() {
8506 $nf=$this->n;
8507 foreach($this->FontFiles as $fontkey=>$info) {
8508 // TrueType embedded
8509 if (isset($info['type']) && $info['type']=='TTF' && !$info['sip'] && !$info['smp']) {
8510 $used = true;
8511 $asSubset = false;
8512 foreach($this->fonts AS $k=>$f) {
8513 if ($f['fontkey'] == $fontkey && $f['type']=='TTF') {
8514 $used = $f['used'];
8515 if ($used) {
8516 $nChars = (ord($f['cw'][0]) << 8) + ord($f['cw'][1]);
8517 $usage = intval(count($f['subset'])*100 / $nChars);
8518 $fsize = $info['length1'];
8519 // Always subset the very large TTF files
8520 if ($fsize > ($this->maxTTFFilesize *1024)) { $asSubset = true; }
8521 else if ($usage < $this->percentSubset) { $asSubset = true; }
8522 }
8523 if ($f['unAGlyphs']) $aaSubset = true; // mPDF 5.4.05
8524 if ($this->PDFA || $this->PDFX) $asSubset = false;
8525 $this->fonts[$k]['asSubset'] = $asSubset;
8526 break;
8527 }
8528 }
8529 if ($used && !$asSubset) {
8530 //Font file embedding
8531 $this->_newobj();
8532 $this->FontFiles[$fontkey]['n']=$this->n;
8533 $font='';
8534 $originalsize = $info['length1'];
8535 if ($this->repackageTTF || $this->fonts[$fontkey]['TTCfontID']>0) {
8536 // First see if there is a cached compressed file
8537 if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z')) {
8538 $f=fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z','rb');
8539 if(!$f) { $this->Error('Font file .ps.z not found'); }
8540 while(!feof($f)) { $font .= fread($f, 2048); }
8541 fclose($f);
8542 include(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.php'); // sets $originalsize (of repackaged font)
8543 }
8544 else {
8545 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
8546 $ttf = new TTFontFile();
8547 $font = $ttf->repackageTTF($this->FontFiles[$fontkey]['ttffile'], $this->fonts[$fontkey]['TTCfontID'], $this->debugfonts, $this->fonts[$fontkey]['unAGlyphs']); // mPDF 5.4.05
8548
8549 $originalsize = strlen($font);
8550 $font = gzcompress($font);
8551 unset($ttf);
8552 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8553 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z',"wb");
8554 fwrite($fh,$font,strlen($font));
8555 fclose($fh);
8556 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.php',"wb");
8557 $len = "<?php \n";
8558 $len.='$originalsize='.$originalsize.";\n";
8559 $len.="?>";
8560 fwrite($fh,$len,strlen($len));
8561 fclose($fh);
8562 }
8563 }
8564 }
8565 else {
8566 // First see if there is a cached compressed file
8567 if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.z')) {
8568 $f=fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.z','rb');
8569 if(!$f) { $this->Error('Font file not found'); }
8570 while(!feof($f)) { $font .= fread($f, 2048); }
8571 fclose($f);
8572 }
8573 else {
8574 $f=fopen($this->FontFiles[$fontkey]['ttffile'],'rb');
8575 if(!$f) { $this->Error('Font file not found'); }
8576 while(!feof($f)) { $font .= fread($f, 2048); }
8577 fclose($f);
8578 $font = gzcompress($font);
8579 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8580 $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.z',"wb");
8581 fwrite($fh,$font,strlen($font));
8582 fclose($fh);
8583 }
8584 }
8585 }
8586
8587 $this->_out('<</Length '.strlen($font));
8588 $this->_out('/Filter /FlateDecode');
8589 $this->_out('/Length1 '.$originalsize);
8590 $this->_out('>>');
8591 $this->_putstream($font);
8592 $this->_out('endobj');
8593 }
8594 }
8595 }
8596
8597 $nfonts = count($this->fonts);
8598 $fctr = 1;
8599 foreach($this->fonts as $k=>$font) {
8600 //Font objects
8601 $type=$font['type'];
8602 $name=$font['name'];
8603 if ((!isset($font['used']) || !$font['used']) && $type=='TTF') { continue; }
8604 if ($this->progressBar) { $this->UpdateProgressBar(2,intval($fctr*100/$nfonts),'Writing Fonts'); $fctr++; } // *PROGRESS-BAR*
8605 if (isset($font['asSubset'])) { $asSubset = $font['asSubset']; }
8606 else { $asSubset = ''; }
8607 /*-- CJK-FONTS --*/
8608 if($type=='Type0') { // = Adobe CJK Fonts
8609 $this->fonts[$k]['n']=$this->n+1;
8610 $this->_newobj();
8611 $this->_out('<</Type /Font');
8612 $this->_putType0($font);
8613 }
8614 else
8615 /*-- END CJK-FONTS --*/
8616 if($type=='core') {
8617 //Standard font
8618 $this->fonts[$k]['n']=$this->n+1;
8619 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.)'); }
8620 $this->_newobj();
8621 $this->_out('<</Type /Font');
8622 $this->_out('/BaseFont /'.$name);
8623 $this->_out('/Subtype /Type1');
8624 if($name!='Symbol' && $name!='ZapfDingbats') {
8625 $this->_out('/Encoding /WinAnsiEncoding');
8626 }
8627 $this->_out('>>');
8628 $this->_out('endobj');
8629 }
8630 // TrueType embedded SUBSETS for SIP (CJK extB containing Supplementary Ideographic Plane 2)
8631 // Or Unicode Plane 1 - Supplementary Multilingual Plane
8632 else if ($type=='TTF' && ($font['sip'] || $font['smp'])) {
8633 if (!$font['used']) { continue; }
8634 $ssfaid="AA";
8635 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
8636 $ttf = new TTFontFile();
8637 for($sfid=0;$sfid<count($font['subsetfontids']);$sfid++) {
8638 $this->fonts[$k]['n'][$sfid]=$this->n+1; // NB an array for subset
8639 $subsetname = 'MPDF'.$ssfaid.'+'.$font['name'];
8640 $ssfaid++;
8641 $subset = $font['subsets'][$sfid];
8642 unset($subset[0]);
8643 $ttfontstream = $ttf->makeSubsetSIP($font['ttffile'], $subset, $font['TTCfontID'], $this->debugfonts);
8644 $ttfontsize = strlen($ttfontstream);
8645 $fontstream = gzcompress($ttfontstream);
8646 $widthstring = '';
8647 $toUnistring = '';
8648 foreach($font['subsets'][$sfid] AS $cp=>$u) {
8649 $w = $this->_getCharWidth($font['cw'], $u);
8650 if ($w !== false) {
8651 $widthstring .= $w.' ';
8652 }
8653 else {
8654 $widthstring .= round($ttf->defaultWidth).' ';
8655 }
8656 if ($u > 65535) {
8657 $utf8 = chr(($u>>18)+240).chr((($u>>12)&63)+128).chr((($u>>6)&63)+128) .chr(($u&63)+128);
8658 $utf16 = mb_convert_encoding($utf8, 'UTF-16BE', 'UTF-8');
8659 $l1 = ord($utf16[0]);
8660 $h1 = ord($utf16[1]);
8661 $l2 = ord($utf16[2]);
8662 $h2 = ord($utf16[3]);
8663 $toUnistring .= sprintf("<%02s> <%02s%02s%02s%02s>\n", strtoupper(dechex($cp)), strtoupper(dechex($l1)), strtoupper(dechex($h1)), strtoupper(dechex($l2)), strtoupper(dechex($h2)));
8664 }
8665 else {
8666 $toUnistring .= sprintf("<%02s> <%04s>\n", strtoupper(dechex($cp)), strtoupper(dechex($u)));
8667 }
8668 }
8669
8670 //Additional Type1 or TrueType font
8671 $this->_newobj();
8672 $this->_out('<</Type /Font');
8673 $this->_out('/BaseFont /'.$subsetname);
8674 $this->_out('/Subtype /TrueType');
8675 $this->_out('/FirstChar 0 /LastChar '.(count($font['subsets'][$sfid])-1));
8676 $this->_out('/Widths '.($this->n+1).' 0 R');
8677 $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
8678 $this->_out('/ToUnicode '.($this->n + 3).' 0 R');
8679 $this->_out('>>');
8680 $this->_out('endobj');
8681
8682 //Widths
8683 $this->_newobj();
8684 $this->_out('['.$widthstring.']');
8685 $this->_out('endobj');
8686
8687 //Descriptor
8688 $this->_newobj();
8689 $s='<</Type /FontDescriptor /FontName /'.$subsetname."\n";
8690 foreach($font['desc'] as $kd=>$v) {
8691 if ($kd == 'Flags') { $v = $v | 4; $v = $v & ~32; } // SYMBOLIC font flag
8692 $s.=' /'.$kd.' '.$v."\n";
8693 }
8694 $s.='/FontFile2 '.($this->n + 2).' 0 R';
8695 $this->_out($s.'>>');
8696 $this->_out('endobj');
8697
8698 // ToUnicode
8699 $this->_newobj();
8700 $toUni = "/CIDInit /ProcSet findresource begin\n";
8701 $toUni .= "12 dict begin\n";
8702 $toUni .= "begincmap\n";
8703 $toUni .= "/CIDSystemInfo\n";
8704 $toUni .= "<</Registry (Adobe)\n";
8705 $toUni .= "/Ordering (UCS)\n";
8706 $toUni .= "/Supplement 0\n";
8707 $toUni .= ">> def\n";
8708 $toUni .= "/CMapName /Adobe-Identity-UCS def\n";
8709 $toUni .= "/CMapType 2 def\n";
8710 $toUni .= "1 begincodespacerange\n";
8711 $toUni .= "<00> <FF>\n";
8712 $toUni .= "endcodespacerange\n";
8713 $toUni .= count($font['subsets'][$sfid])." beginbfchar\n";
8714 $toUni .= $toUnistring;
8715 $toUni .= "endbfchar\n";
8716 $toUni .= "endcmap\n";
8717 $toUni .= "CMapName currentdict /CMap defineresource pop\n";
8718 $toUni .= "end\n";
8719 $toUni .= "end\n";
8720
8721 $this->_out('<</Length '.(strlen($toUni)).'>>');
8722 $this->_putstream($toUni);
8723 $this->_out('endobj');
8724
8725 //Font file
8726 $this->_newobj();
8727 $this->_out('<</Length '.strlen($fontstream));
8728 $this->_out('/Filter /FlateDecode');
8729 $this->_out('/Length1 '.$ttfontsize);
8730 $this->_out('>>');
8731 $this->_putstream($fontstream);
8732 $this->_out('endobj');
8733 } // foreach subset
8734 unset($ttf);
8735 }
8736 // TrueType embedded SUBSETS or FULL
8737 else if ($type=='TTF') {
8738 $this->fonts[$k]['n']=$this->n+1;
8739 if ($asSubset ) {
8740 $ssfaid="A";
8741 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
8742 $ttf = new TTFontFile();
8743 $fontname = 'MPDFA'.$ssfaid.'+'.$font['name'];
8744 $subset = $font['subset'];
8745 unset($subset[0]);
8746 $ttfontstream = $ttf->makeSubset($font['ttffile'], $subset, $font['TTCfontID'], $this->debugfonts, $font['unAGlyphs']); // mPDF 5.4.05
8747 $ttfontsize = strlen($ttfontstream);
8748 $fontstream = gzcompress($ttfontstream);
8749 $codeToGlyph = $ttf->codeToGlyph;
8750 unset($codeToGlyph[0]);
8751 }
8752 else { $fontname = $font['name']; }
8753 // Type0 Font
8754 // A composite font - a font composed of other fonts, organized hierarchically
8755 $this->_newobj();
8756 $this->_out('<</Type /Font');
8757 $this->_out('/Subtype /Type0');
8758 $this->_out('/BaseFont /'.$fontname.'');
8759 $this->_out('/Encoding /Identity-H');
8760 $this->_out('/DescendantFonts ['.($this->n + 1).' 0 R]');
8761 $this->_out('/ToUnicode '.($this->n + 2).' 0 R');
8762 $this->_out('>>');
8763 $this->_out('endobj');
8764
8765 // CIDFontType2
8766 // A CIDFont whose glyph descriptions are based on TrueType font technology
8767 $this->_newobj();
8768 $this->_out('<</Type /Font');
8769 $this->_out('/Subtype /CIDFontType2');
8770 $this->_out('/BaseFont /'.$fontname.'');
8771 $this->_out('/CIDSystemInfo '.($this->n + 2).' 0 R');
8772 $this->_out('/FontDescriptor '.($this->n + 3).' 0 R');
8773 if (isset($font['desc']['MissingWidth'])){
8774 $this->_out('/DW '.$font['desc']['MissingWidth'].'');
8775 }
8776
8777 if (!$asSubset && file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw')) {
8778 $w = '';
8779 $w=file_get_contents(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw');
8780 $this->_out($w);
8781 }
8782 else {
8783 $this->_putTTfontwidths($font, $asSubset, $ttf->maxUni);
8784 }
8785
8786 $this->_out('/CIDToGIDMap '.($this->n + 4).' 0 R');
8787 $this->_out('>>');
8788 $this->_out('endobj');
8789
8790 // ToUnicode
8791 $this->_newobj();
8792 $toUni = "/CIDInit /ProcSet findresource begin\n";
8793 $toUni .= "12 dict begin\n";
8794 $toUni .= "begincmap\n";
8795 $toUni .= "/CIDSystemInfo\n";
8796 $toUni .= "<</Registry (Adobe)\n";
8797 $toUni .= "/Ordering (UCS)\n";
8798 $toUni .= "/Supplement 0\n";
8799 $toUni .= ">> def\n";
8800 $toUni .= "/CMapName /Adobe-Identity-UCS def\n";
8801 $toUni .= "/CMapType 2 def\n";
8802 $toUni .= "1 begincodespacerange\n";
8803 $toUni .= "<0000> <FFFF>\n";
8804 $toUni .= "endcodespacerange\n";
8805 $toUni .= "1 beginbfrange\n";
8806 $toUni .= "<0000> <FFFF> <0000>\n";
8807 $toUni .= "endbfrange\n";
8808 $toUni .= "endcmap\n";
8809 $toUni .= "CMapName currentdict /CMap defineresource pop\n";
8810 $toUni .= "end\n";
8811 $toUni .= "end\n";
8812 $this->_out('<</Length '.(strlen($toUni)).'>>');
8813 $this->_putstream($toUni);
8814 $this->_out('endobj');
8815
8816
8817 // CIDSystemInfo dictionary
8818 $this->_newobj();
8819 $this->_out('<</Registry (Adobe)');
8820 $this->_out('/Ordering (UCS)');
8821 $this->_out('/Supplement 0');
8822 $this->_out('>>');
8823 $this->_out('endobj');
8824
8825 // Font descriptor
8826 $this->_newobj();
8827 $this->_out('<</Type /FontDescriptor');
8828 $this->_out('/FontName /'.$fontname);
8829 foreach($font['desc'] as $kd=>$v) {
8830 if ($asSubset && $kd == 'Flags') { $v = $v | 4; $v = $v & ~32; } // SYMBOLIC font flag
8831 $this->_out(' /'.$kd.' '.$v);
8832 }
8833 if ($font['panose']) {
8834 $this->_out(' /Style << /Panose <'.$font['panose'].'> >>');
8835 }
8836 if ($asSubset ) {
8837 $this->_out('/FontFile2 '.($this->n + 2).' 0 R');
8838 }
8839 else if ($font['fontkey']) {
8840 // obj ID of a stream containing a TrueType font program
8841 $this->_out('/FontFile2 '.$this->FontFiles[$font['fontkey']]['n'].' 0 R');
8842 }
8843 $this->_out('>>');
8844 $this->_out('endobj');
8845
8846 // Embed CIDToGIDMap
8847 // A specification of the mapping from CIDs to glyph indices
8848 if ($asSubset ) {
8849 $cidtogidmap = '';
8850 $cidtogidmap = str_pad('', 256*256*2, "\x00");
8851 foreach($codeToGlyph as $cc=>$glyph) {
8852 $cidtogidmap[$cc*2] = chr($glyph >> 8);
8853 $cidtogidmap[$cc*2 + 1] = chr($glyph & 0xFF);
8854 }
8855 $cidtogidmap = gzcompress($cidtogidmap);
8856 }
8857 else {
8858 // First see if there is a cached CIDToGIDMapfile
8859 $cidtogidmap = '';
8860 if (file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm')) {
8861 $f=fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm','rb');
8862 while(!feof($f)) { $cidtogidmap .= fread($f, 2048); }
8863 fclose($f);
8864 }
8865 else {
8866 if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
8867 $ttf = new TTFontFile();
8868 $charToGlyph = $ttf->getCTG($font['ttffile'], $font['TTCfontID'], $this->debugfonts, $font['unAGlyphs']); // mPDF 5.4.05
8869 $cidtogidmap = str_pad('', 256*256*2, "\x00");
8870 foreach($charToGlyph as $cc=>$glyph) {
8871 $cidtogidmap[$cc*2] = chr($glyph >> 8);
8872 $cidtogidmap[$cc*2 + 1] = chr($glyph & 0xFF);
8873 }
8874 unset($ttf);
8875 $cidtogidmap = gzcompress($cidtogidmap);
8876 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8877 $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm',"wb");
8878 fwrite($fh,$cidtogidmap,strlen($cidtogidmap));
8879 fclose($fh);
8880 }
8881 }
8882 }
8883 $this->_newobj();
8884 $this->_out('<</Length '.strlen($cidtogidmap).'');
8885 $this->_out('/Filter /FlateDecode');
8886 $this->_out('>>');
8887 $this->_putstream($cidtogidmap);
8888 $this->_out('endobj');
8889
8890 //Font file
8891 if ($asSubset ) {
8892 $this->_newobj();
8893 $this->_out('<</Length '.strlen($fontstream));
8894 $this->_out('/Filter /FlateDecode');
8895 $this->_out('/Length1 '.$ttfontsize);
8896 $this->_out('>>');
8897 $this->_putstream($fontstream);
8898 $this->_out('endobj');
8899 unset($ttf);
8900 }
8901 }
8902 else { $this->Error('Unsupported font type: '.$type.' ('.$name.')'); }
8903 }
8904 }
8905
8906
8907
8908 function _putTTfontwidths(&$font, $asSubset, $maxUni) {
8909 if ($asSubset && file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php')) {
8910 include(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php') ;
8911 $startcid = 128;
8912 }
8913 else {
8914 $rangeid = 0;
8915 $range = array();
8916 $prevcid = -2;
8917 $prevwidth = -1;
8918 $interval = false;
8919 $startcid = 1;
8920 }
8921 if ($asSubset) { $cwlen = $maxUni + 1; }
8922 else { $cwlen = (strlen($font['cw'])/2); }
8923
8924 // for each character
8925 for ($cid=$startcid; $cid<$cwlen; $cid++) {
8926 if ($cid==128 && $asSubset && (!file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php'))) {
8927 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8928 $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php',"wb");
8929 $cw127='<?php'."\n";
8930 $cw127.='$rangeid='.$rangeid.";\n";
8931 $cw127.='$prevcid='.$prevcid.";\n";
8932 $cw127.='$prevwidth='.$prevwidth.";\n";
8933 if ($interval) { $cw127.='$interval=true'.";\n"; }
8934 else { $cw127.='$interval=false'.";\n"; }
8935 $cw127.='$range='.var_export($range,true).";\n";
8936 $cw127.="?>";
8937 fwrite($fh,$cw127,strlen($cw127));
8938 fclose($fh);
8939 }
8940 }
8941 if ($font['cw'][$cid*2] == "\00" && $font['cw'][$cid*2+1] == "\00") { continue; }
8942 $width = (ord($font['cw'][$cid*2]) << 8) + ord($font['cw'][$cid*2+1]);
8943 if ($width == 65535) { $width = 0; }
8944 if ($asSubset && $cid > 255 && (!isset($font['subset'][$cid]) || !$font['subset'][$cid])) {
8945 continue;
8946 }
8947 if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) {
8948 if ($cid == ($prevcid + 1)) {
8949 // consecutive CID
8950 if ($width == $prevwidth) {
8951 if ($width == $range[$rangeid][0]) {
8952 $range[$rangeid][] = $width;
8953 } else {
8954 array_pop($range[$rangeid]);
8955 // new range
8956 $rangeid = $prevcid;
8957 $range[$rangeid] = array();
8958 $range[$rangeid][] = $prevwidth;
8959 $range[$rangeid][] = $width;
8960 }
8961 $interval = true;
8962 $range[$rangeid]['interval'] = true;
8963 } else {
8964 if ($interval) {
8965 // new range
8966 $rangeid = $cid;
8967 $range[$rangeid] = array();
8968 $range[$rangeid][] = $width;
8969 } else {
8970 $range[$rangeid][] = $width;
8971 }
8972 $interval = false;
8973 }
8974 } else {
8975 // new range
8976 $rangeid = $cid;
8977 $range[$rangeid] = array();
8978 $range[$rangeid][] = $width;
8979 $interval = false;
8980 }
8981 $prevcid = $cid;
8982 $prevwidth = $width;
8983 }
8984 }
8985 $w = $this->_putfontranges($range);
8986 $this->_out($w);
8987 if (!$asSubset) {
8988 if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
8989 $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw',"wb");
8990 fwrite($fh,$w,strlen($w));
8991 fclose($fh);
8992 }
8993 }
8994 }
8995
8996 function _putfontranges(&$range) {
8997 // optimize ranges
8998 $prevk = -1;
8999 $nextk = -1;
9000 $prevint = false;
9001 foreach ($range as $k => $ws) {
9002 $cws = count($ws);
9003 if (($k == $nextk) AND (!$prevint) AND ((!isset($ws['interval'])) OR ($cws < 4))) {
9004 if (isset($range[$k]['interval'])) {
9005 unset($range[$k]['interval']);
9006 }
9007 $range[$prevk] = array_merge($range[$prevk], $range[$k]);
9008 unset($range[$k]);
9009 } else {
9010 $prevk = $k;
9011 }
9012 $nextk = $k + $cws;
9013 if (isset($ws['interval'])) {
9014 if ($cws > 3) {
9015 $prevint = true;
9016 } else {
9017 $prevint = false;
9018 }
9019 unset($range[$k]['interval']);
9020 --$nextk;
9021 } else {
9022 $prevint = false;
9023 }
9024 }
9025 // output data
9026 $w = '';
9027 foreach ($range as $k => $ws) {
9028 if (count(array_count_values($ws)) == 1) {
9029 // interval mode is more compact
9030 $w .= ' '.$k.' '.($k + count($ws) - 1).' '.$ws[0];
9031 } else {
9032 // range mode
9033 $w .= ' '.$k.' [ '.implode(' ', $ws).' ]' . "\n";
9034 }
9035 }
9036 return '/W ['.$w.' ]';
9037 }
9038
9039
9040 function _putfontwidths(&$font, $cidoffset=0) {
9041 ksort($font['cw']);
9042 unset($font['cw'][65535]);
9043 $rangeid = 0;
9044 $range = array();
9045 $prevcid = -2;
9046 $prevwidth = -1;
9047 $interval = false;
9048 // for each character
9049 foreach ($font['cw'] as $cid => $width) {
9050 $cid -= $cidoffset;
9051 if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) {
9052 if ($cid == ($prevcid + 1)) {
9053 // consecutive CID
9054 if ($width == $prevwidth) {
9055 if ($width == $range[$rangeid][0]) {
9056 $range[$rangeid][] = $width;
9057 } else {
9058 array_pop($range[$rangeid]);
9059 // new range
9060 $rangeid = $prevcid;
9061 $range[$rangeid] = array();
9062 $range[$rangeid][] = $prevwidth;
9063 $range[$rangeid][] = $width;
9064 }
9065 $interval = true;
9066 $range[$rangeid]['interval'] = true;
9067 } else {
9068 if ($interval) {
9069 // new range
9070 $rangeid = $cid;
9071 $range[$rangeid] = array();
9072 $range[$rangeid][] = $width;
9073 } else {
9074 $range[$rangeid][] = $width;
9075 }
9076 $interval = false;
9077 }
9078 } else {
9079 // new range
9080 $rangeid = $cid;
9081 $range[$rangeid] = array();
9082 $range[$rangeid][] = $width;
9083 $interval = false;
9084 }
9085 $prevcid = $cid;
9086 $prevwidth = $width;
9087 }
9088 }
9089 $this->_out($this->_putfontranges($range));
9090 }
9091
9092
9093 /*-- CJK-FONTS --*/
9094
9095 // from class PDF_Chinese CJK EXTENSIONS
9096 function _putType0(&$font)
9097 {
9098 //Type0
9099 $this->_out('/Subtype /Type0');
9100 $this->_out('/BaseFont /'.$font['name'].'-'.$font['CMap']);
9101 $this->_out('/Encoding /'.$font['CMap']);
9102 $this->_out('/DescendantFonts ['.($this->n+1).' 0 R]');
9103 $this->_out('>>');
9104 $this->_out('endobj');
9105 //CIDFont
9106 $this->_newobj();
9107 $this->_out('<</Type /Font');
9108 $this->_out('/Subtype /CIDFontType0');
9109 $this->_out('/BaseFont /'.$font['name']);
9110
9111 $cidinfo = '/Registry '.$this->_textstring('Adobe');
9112 $cidinfo .= ' /Ordering '.$this->_textstring($font['registry']['ordering']);
9113 $cidinfo .= ' /Supplement '.$font['registry']['supplement'];
9114 $this->_out('/CIDSystemInfo <<'.$cidinfo.'>>');
9115
9116 $this->_out('/FontDescriptor '.($this->n+1).' 0 R');
9117 if (isset($font['MissingWidth'])){
9118 $this->_out('/DW '.$font['MissingWidth'].'');
9119 }
9120 $this->_putfontwidths($font, 31);
9121 $this->_out('>>');
9122 $this->_out('endobj');
9123
9124 //Font descriptor
9125 $this->_newobj();
9126 $s = '<</Type /FontDescriptor /FontName /'.$font['name'];
9127 foreach ($font['desc'] as $k => $v) {
9128 if ($k != 'Style') {
9129 $s .= ' /'.$k.' '.$v.'';
9130 }
9131 }
9132 $this->_out($s.'>>');
9133 $this->_out('endobj');
9134 }
9135 /*-- END CJK-FONTS --*/
9136
9137
9138
9139 function _putimages()
9140 {
9141 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
9142 reset($this->images);
9143 while(list($file,$info)=each($this->images)) {
9144 $this->_newobj();
9145 $this->images[$file]['n']=$this->n;
9146 $this->_out('<</Type /XObject');
9147 $this->_out('/Subtype /Image');
9148 $this->_out('/Width '.$info['w']);
9149 $this->_out('/Height '.$info['h']);
9150 if (isset($info['masked'])) {
9151 $this->_out('/SMask '.($this->n - 1).' 0 R');
9152 }
9153 if($info['cs']=='Indexed') {
9154 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.")."); }
9155 $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
9156 }
9157 else {
9158 $this->_out('/ColorSpace /'.$info['cs']);
9159 if($info['cs']=='DeviceCMYK') {
9160 if ($this->PDFA && $this->restrictColorSpace!=3) { $this->Error("PDFA1-b does not permit Images using mixed colour space (".$file.")."); }
9161 if($info['type']=='jpg') { $this->_out('/Decode [1 0 1 0 1 0 1 0]'); }
9162 }
9163 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.")."); }
9164 }
9165 $this->_out('/BitsPerComponent '.$info['bpc']);
9166 if (isset($info['f']) && $info['f']) { $this->_out('/Filter /'.$info['f']); }
9167 if(isset($info['parms'])) { $this->_out($info['parms']); }
9168 if(isset($info['trns']) and is_array($info['trns'])) {
9169 $trns='';
9170 for($i=0;$i<count($info['trns']);$i++)
9171 $trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
9172 $this->_out('/Mask ['.$trns.']');
9173 }
9174 $this->_out('/Length '.strlen($info['data']).'>>');
9175 $this->_putstream($info['data']);
9176
9177 unset($this->images[$file]['data']);
9178 $this->_out('endobj');
9179 //Palette
9180 if($info['cs']=='Indexed') {
9181 $this->_newobj();
9182 $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
9183 $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
9184 $this->_putstream($pal);
9185 $this->_out('endobj');
9186 }
9187 }
9188 }
9189
9190 function _putinfo()
9191 {
9192 $this->_out('/Producer '.$this->_UTF16BEtextstring('mPDF '.mPDF_VERSION));
9193 if(!empty($this->title))
9194 $this->_out('/Title '.$this->_UTF16BEtextstring($this->title));
9195 if(!empty($this->subject))
9196 $this->_out('/Subject '.$this->_UTF16BEtextstring($this->subject));
9197 if(!empty($this->author))
9198 $this->_out('/Author '.$this->_UTF16BEtextstring($this->author));
9199 if(!empty($this->keywords))
9200 $this->_out('/Keywords '.$this->_UTF16BEtextstring($this->keywords));
9201 if(!empty($this->creator))
9202 $this->_out('/Creator '.$this->_UTF16BEtextstring($this->creator));
9203
9204 $z = date('O'); // +0200
9205 $offset = substr($z,0,3)."'".substr($z,3,2)."'";
9206 $this->_out('/CreationDate '.$this->_textstring(date('YmdHis').$offset));
9207 $this->_out('/ModDate '.$this->_textstring(date('YmdHis').$offset));
9208 if ($this->PDFX) {
9209 $this->_out('/Trapped/False');
9210 $this->_out('/GTS_PDFXVersion(PDF/X-1a:2003)');
9211 }
9212 }
9213
9214 function _putmetadata() {
9215 $this->_newobj();
9216 $this->MetadataRoot = $this->n;
9217 $Producer = 'mPDF '.mPDF_VERSION;
9218 $z = date('O'); // +0200
9219 $offset = substr($z,0,3).':'.substr($z,3,2);
9220 $CreationDate = date('Y-m-d\TH:i:s').$offset; // 2006-03-10T10:47:26-05:00 2006-06-19T09:05:17Z
9221 $uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff),
9222 mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
9223 mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) );
9224
9225
9226 $m = '<?xpacket begin="'.chr(239).chr(187).chr(191).'" id="W5M0MpCehiHzreSzNTczkc9d"?>'."\n"; // begin = FEFF BOM
9227 $m .= ' <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="3.1-701">'."\n";
9228 $m .= ' <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">'."\n";
9229 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:pdf="http://ns.adobe.com/pdf/1.3/">'."\n";
9230 $m .= ' <pdf:Producer>'.$Producer.'</pdf:Producer>'."\n";
9231 if(!empty($this->keywords)) { $m .= ' <pdf:Keywords>'.$this->keywords.'</pdf:Keywords>'."\n"; }
9232 $m .= ' </rdf:Description>'."\n";
9233
9234 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:xmp="http://ns.adobe.com/xap/1.0/">'."\n";
9235 $m .= ' <xmp:CreateDate>'.$CreationDate.'</xmp:CreateDate>'."\n";
9236 $m .= ' <xmp:ModifyDate>'.$CreationDate.'</xmp:ModifyDate>'."\n";
9237 $m .= ' <xmp:MetadataDate>'.$CreationDate.'</xmp:MetadataDate>'."\n";
9238 if(!empty($this->creator)) { $m .= ' <xmp:CreatorTool>'.$this->creator.'</xmp:CreatorTool>'."\n"; }
9239 $m .= ' </rdf:Description>'."\n";
9240
9241 // DC elements
9242 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:dc="http://purl.org/dc/elements/1.1/">'."\n";
9243 $m .= ' <dc:format>application/pdf</dc:format>'."\n";
9244 if(!empty($this->title)) {
9245 $m .= ' <dc:title>
9246 <rdf:Alt>
9247 <rdf:li xml:lang="x-default">'.$this->title.'</rdf:li>
9248 </rdf:Alt>
9249 </dc:title>'."\n";
9250 }
9251 if(!empty($this->keywords)) {
9252 $m .= ' <dc:subject>
9253 <rdf:Bag>
9254 <rdf:li>'.$this->keywords.'</rdf:li>
9255 </rdf:Bag>
9256 </dc:subject>'."\n";
9257 }
9258 if(!empty($this->subject)) {
9259 $m .= ' <dc:description>
9260 <rdf:Alt>
9261 <rdf:li xml:lang="x-default">'.$this->subject.'</rdf:li>
9262 </rdf:Alt>
9263 </dc:description>'."\n";
9264 }
9265 if(!empty($this->author)) {
9266 $m .= ' <dc:creator>
9267 <rdf:Seq>
9268 <rdf:li>'.$this->author.'</rdf:li>
9269 </rdf:Seq>
9270 </dc:creator>'."\n";
9271 }
9272 $m .= ' </rdf:Description>'."\n";
9273
9274
9275 // This bit is specific to PDFX-1a
9276 if ($this->PDFX) {
9277 $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";
9278 }
9279
9280 // This bit is specific to PDFA-1b
9281 else if ($this->PDFA) {
9282 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/" >'."\n";
9283 $m .= ' <pdfaid:part>1</pdfaid:part>'."\n";
9284 $m .= ' <pdfaid:conformance>B</pdfaid:conformance>'."\n";
9285 $m .= ' <pdfaid:amd>2005</pdfaid:amd>'."\n";
9286 $m .= ' </rdf:Description>'."\n";
9287 }
9288
9289 $m .= ' <rdf:Description rdf:about="uuid:'.$uuid.'" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">'."\n";
9290 $m .= ' <xmpMM:DocumentID>uuid:'.$uuid.'</xmpMM:DocumentID>'."\n";
9291 $m .= ' </rdf:Description>'."\n";
9292 $m .= ' </rdf:RDF>'."\n";
9293 $m .= ' </x:xmpmeta>'."\n";
9294 $m .= str_repeat(str_repeat(' ',100)."\n",20); // 2-4kB whitespace padding required
9295 $m .= '<?xpacket end="w"?>'; // "r" read only
9296 $this->_out('<</Type/Metadata/Subtype/XML/Length '.strlen($m).'>>');
9297 $this->_putstream($m);
9298 $this->_out('endobj');
9299 }
9300
9301 function _putoutputintent() {
9302 $this->_newobj();
9303 $this->OutputIntentRoot = $this->n;
9304 $this->_out('<</Type /OutputIntent');
9305
9306 if ($this->PDFA) {
9307 $this->_out('/S /GTS_PDFA1');
9308 if ($this->ICCProfile) {
9309 $this->_out('/Info ('.preg_replace('/_/',' ',$this->ICCProfile).')');
9310 $this->_out('/OutputConditionIdentifier (Custom)');
9311 $this->_out('/OutputCondition ()');
9312 }
9313 else {
9314 $this->_out('/Info (sRGB IEC61966-2.1)');
9315 $this->_out('/OutputConditionIdentifier (sRGB IEC61966-2.1)');
9316 $this->_out('/OutputCondition ()');
9317 }
9318 $this->_out('/DestOutputProfile '.($this->n+1).' 0 R');
9319 }
9320 else if ($this->PDFX) { // always a CMYK profile
9321 $this->_out('/S /GTS_PDFX');
9322 if ($this->ICCProfile) {
9323 $this->_out('/Info ('.preg_replace('/_/',' ',$this->ICCProfile).')');
9324 $this->_out('/OutputConditionIdentifier (Custom)');
9325 $this->_out('/OutputCondition ()');
9326 $this->_out('/DestOutputProfile '.($this->n+1).' 0 R');
9327 }
9328 else {
9329 $this->_out('/Info (CGATS TR 001)');
9330 $this->_out('/OutputConditionIdentifier (CGATS TR 001)');
9331 $this->_out('/OutputCondition (CGATS TR 001 (SWOP))');
9332 $this->_out('/RegistryName (http://www.color.org)');
9333 }
9334 }
9335 $this->_out('>>');
9336 $this->_out('endobj');
9337
9338 if ($this->PDFX && !$this->ICCProfile) { return; } // no ICCProfile embedded
9339
9340 $this->_newobj();
9341 if ($this->ICCProfile)
9342 $s = file_get_contents(_MPDF_PATH.'iccprofiles/'.$this->ICCProfile.'.icc');
9343 else
9344 $s = file_get_contents(_MPDF_PATH.'iccprofiles/sRGB_IEC61966-2-1.icc');
9345 if ($this->compress) { $s = gzcompress($s); }
9346 $this->_out('<<');
9347 if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace == 3)) { $this->_out('/N 4'); }
9348 else { $this->_out('/N 3'); }
9349 if ($this->compress)
9350 $this->_out('/Filter /FlateDecode ');
9351 $this->_out('/Length '.strlen($s).'>>');
9352 $this->_putstream($s);
9353 $this->_out('endobj');
9354 }
9355
9356
9357 function _putcatalog() {
9358 $this->_out('/Type /Catalog');
9359 $this->_out('/Pages 1 0 R');
9360 if($this->ZoomMode=='fullpage') $this->_out('/OpenAction [3 0 R /Fit]');
9361 elseif($this->ZoomMode=='fullwidth') $this->_out('/OpenAction [3 0 R /FitH null]');
9362 elseif($this->ZoomMode=='real') $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
9363 elseif(!is_string($this->ZoomMode)) $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']');
9364 else $this->_out('/OpenAction [3 0 R /XYZ null null null]');
9365 if($this->LayoutMode=='single') $this->_out('/PageLayout /SinglePage');
9366 elseif($this->LayoutMode=='continuous') $this->_out('/PageLayout /OneColumn');
9367 elseif($this->LayoutMode=='twoleft') $this->_out('/PageLayout /TwoColumnLeft');
9368 elseif($this->LayoutMode=='tworight') $this->_out('/PageLayout /TwoColumnRight');
9369 elseif($this->LayoutMode=='two') {
9370 if ($this->mirrorMargins) { $this->_out('/PageLayout /TwoColumnRight'); }
9371 else { $this->_out('/PageLayout /TwoColumnLeft'); }
9372 }
9373
9374 /*-- BOOKMARKS --*/
9375 if(count($this->BMoutlines)>0) {
9376 $this->_out('/Outlines '.$this->OutlineRoot.' 0 R');
9377 $this->_out('/PageMode /UseOutlines');
9378 }
9379 /*-- END BOOKMARKS --*/
9380 if(is_int(strpos($this->DisplayPreferences,'FullScreen'))) $this->_out('/PageMode /FullScreen');
9381
9382 // Metadata
9383 if ($this->PDFA || $this->PDFX) {
9384 $this->_out('/Metadata '.$this->MetadataRoot.' 0 R');
9385 }
9386 // OutputIntents
9387 if ($this->PDFA || $this->PDFX || $this->ICCProfile) {
9388 $this->_out('/OutputIntents ['.$this->OutputIntentRoot.' 0 R]');
9389 }
9390
9391 /*-- FORMS --*/
9392 if (count($this->form->forms)>0) {
9393 $this->form->_putFormsCatalog();
9394 }
9395 /*-- END FORMS --*/
9396 if ( isset($this->js) ) {
9397 $this->_out('/Names << /JavaScript '.($this->n_js).' 0 R >> ');
9398 }
9399
9400 if($this->DisplayPreferences || $this->directionality == 'rtl' || $this->mirrorMargins) {
9401 $this->_out('/ViewerPreferences<<');
9402 if(is_int(strpos($this->DisplayPreferences,'HideMenubar'))) $this->_out('/HideMenubar true');
9403 if(is_int(strpos($this->DisplayPreferences,'HideToolbar'))) $this->_out('/HideToolbar true');
9404 if(is_int(strpos($this->DisplayPreferences,'HideWindowUI'))) $this->_out('/HideWindowUI true');
9405 if(is_int(strpos($this->DisplayPreferences,'DisplayDocTitle'))) $this->_out('/DisplayDocTitle true');
9406 if(is_int(strpos($this->DisplayPreferences,'CenterWindow'))) $this->_out('/CenterWindow true');
9407 if(is_int(strpos($this->DisplayPreferences,'FitWindow'))) $this->_out('/FitWindow true');
9408 // /PrintScaling is PDF 1.6 spec.
9409 if(is_int(strpos($this->DisplayPreferences,'NoPrintScaling')) && !$this->PDFA && !$this->PDFX)
9410 $this->_out('/PrintScaling /None');
9411 if($this->directionality == 'rtl') $this->_out('/Direction /R2L');
9412 // /Duplex is PDF 1.7 spec.
9413 if($this->mirrorMargins && !$this->PDFA && !$this->PDFX) {
9414 // if ($this->DefOrientation=='P') $this->_out('/Duplex /DuplexFlipShortEdge');
9415 $this->_out('/Duplex /DuplexFlipLongEdge'); // PDF v1.7+
9416 }
9417 $this->_out('>>');
9418 }
9419 // mPDF 5.6.01
9420 if($this->open_layer_pane && ($this->hasOC || count($this->layers)))
9421 $this->_out('/PageMode /UseOC');
9422
9423 // mPDF 5.6.01
9424 if ($this->hasOC || count($this->layers)) {
9425 $p = $v = $h = $l = $loff = $lall = $as = ''; // mPDF 5.6.28
9426 if ($this->hasOC) {
9427 if (($this->hasOC & 1) == 1) $p=$this->n_ocg_print.' 0 R';
9428 if (($this->hasOC & 2) == 2) $v=$this->n_ocg_view.' 0 R';
9429 if (($this->hasOC & 4) == 4) $h=$this->n_ocg_hidden.' 0 R';
9430 $as="<</Event /Print /OCGs [$p $v $h] /Category [/Print]>> <</Event /View /OCGs [$p $v $h] /Category [/View]>>";
9431 }
9432
9433 if(count($this->layers)) {
9434 foreach($this->layers as $k=>$layer) { // mPDF 5.6.28
9435 if (strtolower($this->layerDetails[$k]['state'])=='hidden') { $loff .= $layer['n'].' 0 R '; }
9436 else { $l .= $layer['n'].' 0 R '; }
9437 $lall .= $layer['n'].' 0 R ';
9438 }
9439 }
9440 $this->_out("/OCProperties <</OCGs [$p $v $h $lall] /D <</ON [$p $l] /OFF [$v $h $loff] "); // mPDF 5.6.28
9441 $this->_out("/Order [$v $p $h $lall] "); // mPDF 5.6.28
9442 if ($as) $this->_out("/AS [$as] ");
9443 $this->_out(">>>>");
9444
9445 }
9446
9447 }
9448
9449 // Inactive function left for backwards compatability
9450 function SetUserRights($enable=true, $annots="", $form="", $signature="") {
9451 // Does nothing
9452 }
9453
9454 function _enddoc() {
9455 if ($this->progressBar) { $this->UpdateProgressBar(2,'10','Writing Headers & Footers'); } // *PROGRESS-BAR*
9456 $this->_puthtmlheaders(); // *HTMLHEADERS-FOOTERS*
9457 if ($this->progressBar) { $this->UpdateProgressBar(2,'20','Writing Pages'); } // *PROGRESS-BAR*
9458 // Remove references to unused fonts (usually default font)
9459 foreach($this->fonts as $fk=>$font) {
9460 if (!$font['used'] && ($font['type']=='TTF')) {
9461 if ($font['sip'] || $font['smp']) {
9462 foreach($font['subsetfontids'] AS $k => $fid) {
9463 foreach($this->pages AS $pn=>$page) {
9464 $this->pages[$pn] = preg_replace('/\s\/F'.$fid.' \d[\d.]* Tf\s/is',' ',$this->pages[$pn]);
9465 }
9466 }
9467 }
9468 else {
9469 foreach($this->pages AS $pn=>$page) {
9470 $this->pages[$pn] = preg_replace('/\s\/F'.$font['i'].' \d[\d.]* Tf\s/is',' ',$this->pages[$pn]);
9471 }
9472 }
9473 }
9474 }
9475
9476 // mPDF 5.6.01 - LAYERS
9477 if (count($this->layers)) {
9478 foreach($this->pages AS $pn=>$page) {
9479 preg_match_all('/\/OCZ-index \/ZI(\d+) BDC(.*?)(EMCZ)-index/is',$this->pages[$pn],$m1);
9480 preg_match_all('/\/OCBZ-index \/ZI(\d+) BDC(.*?)(EMCBZ)-index/is',$this->pages[$pn],$m2);
9481 preg_match_all('/\/OCGZ-index \/ZI(\d+) BDC(.*?)(EMCGZ)-index/is',$this->pages[$pn],$m3);
9482 $m = array();
9483 for ($i=0;$i<4;$i++) {
9484 $m[$i] = array_merge($m1[$i],$m2[$i],$m3[$i]);
9485 }
9486 if (count($m[0])) {
9487 $sortarr = array();
9488 for($i=0;$i<count($m[0]);$i++) {
9489 $key = $m[1][$i]*2;
9490 if ($m[3][$i]=='EMCZ') $key +=2; // background first then gradient then normal
9491 else if ($m[3][$i]=='EMCGZ') $key +=1;
9492 $sortarr[$i] = $key;
9493 }
9494 asort($sortarr);
9495 foreach($sortarr AS $i=>$k) {
9496 $this->pages[$pn] = str_replace($m[0][$i],'',$this->pages[$pn] );
9497 $this->pages[$pn] .= "\n".$m[0][$i]."\n";
9498 }
9499 $this->pages[$pn] = preg_replace('/\/OC[BG]{0,1}Z-index \/ZI(\d+) BDC/is','/OC /ZI\\1 BDC ',$this->pages[$pn]);
9500 $this->pages[$pn] = preg_replace('/EMC[BG]{0,1}Z-index/is','EMC',$this->pages[$pn]);
9501 }
9502 }
9503 }
9504
9505 $this->_putpages();
9506 if ($this->progressBar) { $this->UpdateProgressBar(2,'30','Writing document resources'); } // *PROGRESS-BAR*
9507
9508 $this->_putresources();
9509 //Info
9510 $this->_newobj();
9511 $this->InfoRoot = $this->n;
9512 $this->_out('<<');
9513 if ($this->progressBar) { $this->UpdateProgressBar(2,'80','Writing document info'); } // *PROGRESS-BAR*
9514 $this->_putinfo();
9515 $this->_out('>>');
9516 $this->_out('endobj');
9517
9518 // METADATA
9519 if ($this->PDFA || $this->PDFX) { $this->_putmetadata(); }
9520 // OUTPUTINTENT
9521 if ($this->PDFA || $this->PDFX || $this->ICCProfile) { $this->_putoutputintent(); }
9522
9523 //Catalog
9524 $this->_newobj();
9525 $this->_out('<<');
9526 if ($this->progressBar) { $this->UpdateProgressBar(2,'90','Writing document catalog'); } // *PROGRESS-BAR*
9527 $this->_putcatalog();
9528 $this->_out('>>');
9529 $this->_out('endobj');
9530 //Cross-ref
9531 $o=strlen($this->buffer);
9532 $this->_out('xref');
9533 $this->_out('0 '.($this->n+1));
9534 $this->_out('0000000000 65535 f ');
9535 for($i=1; $i <= $this->n ; $i++)
9536 $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
9537 //Trailer
9538 $this->_out('trailer');
9539 $this->_out('<<');
9540 $this->_puttrailer();
9541 $this->_out('>>');
9542 $this->_out('startxref');
9543 $this->_out($o);
9544
9545 $this->buffer .= '%%EOF';
9546 $this->state=3;
9547 /*-- IMPORTS --*/
9548
9549 if ($this->enableImports && count($this->parsers) > 0) {
9550 foreach ($this->parsers as $k => $_){
9551 $this->parsers[$k]->closeFile();
9552 $this->parsers[$k] = null;
9553 unset($this->parsers[$k]);
9554 }
9555 }
9556 /*-- END IMPORTS --*/
9557 }
9558
9559 function _beginpage($orientation,$mgl='',$mgr='',$mgt='',$mgb='',$mgh='',$mgf='',$ohname='',$ehname='',$ofname='',$efname='',$ohvalue=0,$ehvalue=0,$ofvalue=0,$efvalue=0,$pagesel='',$newformat='') {
9560 if (!($pagesel && $this->page==1 && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->tMargin)))) {
9561 $this->page++;
9562 $this->pages[$this->page]='';
9563 }
9564 $this->state=2;
9565 $resetHTMLHeadersrequired = false;
9566
9567 if ($newformat) { $this->_setPageSize($newformat, $orientation); }
9568 /*-- CSS-PAGE --*/
9569 // Paged media (page-box)
9570
9571 if ($pagesel || (isset($this->page_box['using']) && $this->page_box['using'])) {
9572 if ($pagesel || $this->page==1) { $first = true; }
9573 else { $first = false; }
9574 if ($this->mirrorMargins && ($this->page % 2==0)) { $oddEven = 'E'; }
9575 else { $oddEven = 'O'; }
9576 if ($pagesel) { $psel = $pagesel; }
9577 else if ($this->page_box['current']) { $psel = $this->page_box['current']; }
9578 else { $psel = ''; }
9579 list($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS($psel, $first, $oddEven);
9580 if ($this->mirrorMargins && ($this->page % 2==0)) {
9581 if ($hname) { $ehvalue = 1; $ehname = $hname; } else { $ehvalue = -1; }
9582 if ($fname) { $efvalue = 1; $efname = $fname; } else { $efvalue = -1; }
9583 }
9584 else {
9585 if ($hname) { $ohvalue = 1; $ohname = $hname; } else { $ohvalue = -1; }
9586 if ($fname) { $ofvalue = 1; $ofname = $fname; } else { $ofvalue = -1; }
9587 }
9588 if ($resetpagenum || $pagenumstyle || $suppress) {
9589 $this->PageNumSubstitutions[] = array('from'=>($this->page), 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=>$suppress);
9590 }
9591 // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
9592 $this->show_marks = $marks;
9593
9594 // Background color
9595 if (isset($bg['BACKGROUND-COLOR'])) {
9596 $cor = $this->ConvertColor($bg['BACKGROUND-COLOR']);
9597 if ($cor) {
9598 $this->bodyBackgroundColor = $cor;
9599 }
9600 }
9601 else { $this->bodyBackgroundColor = false; }
9602
9603 /*-- BACKGROUNDS --*/
9604 if (isset($bg['BACKGROUND-GRADIENT'])) {
9605 $this->bodyBackgroundGradient = $bg['BACKGROUND-GRADIENT'];
9606 }
9607 else { $this->bodyBackgroundGradient = false; }
9608
9609 // Tiling Patterns
9610 if (isset($bg['BACKGROUND-IMAGE']) && $bg['BACKGROUND-IMAGE']) {
9611 $ret = $this->SetBackground($bg, $this->pgwidth);
9612 if ($ret) { $this->bodyBackgroundImage = $ret; }
9613 }
9614 else { $this->bodyBackgroundImage = false; }
9615 /*-- END BACKGROUNDS --*/
9616
9617 $this->page_box['current'] = $psel;
9618 $this->page_box['using'] = true;
9619 }
9620 /*-- END CSS-PAGE --*/
9621
9622 //Page orientation
9623 if(!$orientation)
9624 $orientation=$this->DefOrientation;
9625 else {
9626 $orientation=strtoupper(substr($orientation,0,1));
9627 if($orientation!=$this->DefOrientation)
9628 $this->OrientationChanges[$this->page]=true;
9629 }
9630 if($orientation!=$this->CurOrientation || $newformat) {
9631
9632 //Change orientation
9633 if($orientation=='P') {
9634 $this->wPt=$this->fwPt;
9635 $this->hPt=$this->fhPt;
9636 $this->w=$this->fw;
9637 $this->h=$this->fh;
9638 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P') {
9639 $this->tMargin = $this->orig_tMargin;
9640 $this->bMargin = $this->orig_bMargin;
9641 $this->DeflMargin = $this->orig_lMargin;
9642 $this->DefrMargin = $this->orig_rMargin;
9643 $this->margin_header = $this->orig_hMargin;
9644 $this->margin_footer = $this->orig_fMargin;
9645 }
9646 else { $resetHTMLHeadersrequired = true; } // *HTMLHEADERS-FOOTERS*
9647 }
9648 else {
9649 $this->wPt=$this->fhPt;
9650 $this->hPt=$this->fwPt;
9651 $this->w=$this->fh;
9652 $this->h=$this->fw;
9653 if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P') {
9654 $this->tMargin = $this->orig_lMargin;
9655 $this->bMargin = $this->orig_rMargin;
9656 $this->DeflMargin = $this->orig_bMargin;
9657 $this->DefrMargin = $this->orig_tMargin;
9658 $this->margin_header = $this->orig_hMargin;
9659 $this->margin_footer = $this->orig_fMargin;
9660 }
9661 else { $resetHTMLHeadersrequired = true; } // *HTMLHEADERS-FOOTERS*
9662
9663 }
9664 $this->CurOrientation=$orientation;
9665 $this->ResetMargins();
9666 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
9667 $this->PageBreakTrigger=$this->h-$this->bMargin;
9668 }
9669
9670 $this->pageDim[$this->page]['w']=$this->w ;
9671 $this->pageDim[$this->page]['h']=$this->h ;
9672
9673 $this->pageDim[$this->page]['outer_width_LR'] = isset($this->page_box['outer_width_LR']) ? $this->page_box['outer_width_LR'] : 0;
9674 $this->pageDim[$this->page]['outer_width_TB'] = isset($this->page_box['outer_width_TB']) ? $this->page_box['outer_width_TB'] : 0;
9675 if (!isset($this->page_box['outer_width_LR']) && !isset($this->page_box['outer_width_TB'])) {
9676 $this->pageDim[$this->page]['bleedMargin'] = 0;
9677 }
9678 else if ($this->bleedMargin <= $this->page_box['outer_width_LR'] && $this->bleedMargin <= $this->page_box['outer_width_TB']) {
9679 $this->pageDim[$this->page]['bleedMargin'] = $this->bleedMargin;
9680 }
9681 else {
9682 $this->pageDim[$this->page]['bleedMargin'] = min($this->page_box['outer_width_LR'], $this->page_box['outer_width_TB'])-0.01;
9683 }
9684
9685 // If Page Margins are re-defined
9686 // strlen()>0 is used to pick up (integer) 0, (string) '0', or set value
9687 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)) {
9688 if (strlen($mgl)>0) $this->DeflMargin = $mgl;
9689 if (strlen($mgr)>0) $this->DefrMargin = $mgr;
9690 if (strlen($mgt)>0) $this->tMargin = $mgt;
9691 if (strlen($mgb)>0) $this->bMargin = $mgb;
9692 if (strlen($mgh)>0) $this->margin_header=$mgh;
9693 if (strlen($mgf)>0) $this->margin_footer=$mgf;
9694 $this->ResetMargins();
9695 $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
9696 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
9697 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9698 }
9699
9700 $this->ResetMargins();
9701 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
9702 $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
9703
9704 // Reset column top margin
9705 $this->y0 = $this->tMargin;
9706
9707 $this->x=$this->lMargin;
9708 $this->y=$this->tMargin;
9709 $this->FontFamily='';
9710
9711 // HEADERS AND FOOTERS
9712 if ($ohvalue<0 || strtoupper($ohvalue)=='OFF') {
9713 $this->HTMLHeader = '';
9714 $this->headerDetails['odd'] = array();
9715 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9716 }
9717 else if ($ohname && $ohvalue>0) {
9718 /*-- HTMLHEADERS-FOOTERS --*/
9719 if (preg_match('/^html_(.*)$/i',$ohname,$n)) {
9720 if (isset($this->pageHTMLheaders[$n[1]])) { $this->HTMLHeader = $this->pageHTMLheaders[$n[1]]; }
9721 else { $this->HTMLHeader = ''; }
9722 $this->headerDetails['odd'] = array();
9723 $resetHTMLHeadersrequired = true;
9724 }
9725 else {
9726 /*-- END HTMLHEADERS-FOOTERS --*/
9727 if (isset($this->pageheaders[$ohname])) { $this->headerDetails['odd'] = $this->pageheaders[$ohname]; }
9728 else if ($ohname!='_default') { $this->headerDetails['odd'] = array(); }
9729 $this->HTMLHeader = '';
9730 /*-- HTMLHEADERS-FOOTERS --*/
9731 $resetHTMLHeadersrequired = false;
9732 }
9733 /*-- END HTMLHEADERS-FOOTERS --*/
9734 }
9735
9736 if ($ehvalue<0 || strtoupper($ehvalue)=='OFF') {
9737 $this->HTMLHeaderE = '';
9738 $this->headerDetails['even'] = array();
9739 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9740 }
9741 else if ($ehname && $ehvalue>0) {
9742 /*-- HTMLHEADERS-FOOTERS --*/
9743 if (preg_match('/^html_(.*)$/i',$ehname,$n)) {
9744 if (isset($this->pageHTMLheaders[$n[1]])) { $this->HTMLHeaderE = $this->pageHTMLheaders[$n[1]]; }
9745 else { $this->HTMLHeaderE = ''; }
9746 $this->headerDetails['even'] = array();
9747 $resetHTMLHeadersrequired = true;
9748 }
9749 else {
9750 /*-- END HTMLHEADERS-FOOTERS --*/
9751 if (isset($this->pageheaders[$ehname])) { $this->headerDetails['even'] = $this->pageheaders[$ehname]; }
9752 else if ($ehname!='_default') { $this->headerDetails['even'] = array(); }
9753 $this->HTMLHeaderE = '';
9754 /*-- HTMLHEADERS-FOOTERS --*/
9755 $resetHTMLHeadersrequired = false;
9756 }
9757 /*-- END HTMLHEADERS-FOOTERS --*/
9758 }
9759
9760 if ($ofvalue<0 || strtoupper($ofvalue)=='OFF') {
9761 $this->HTMLFooter = '';
9762 $this->footerDetails['odd'] = array();
9763 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9764 }
9765 else if ($ofname && $ofvalue>0) {
9766 /*-- HTMLHEADERS-FOOTERS --*/
9767 if (preg_match('/^html_(.*)$/i',$ofname,$n)) {
9768 if (isset($this->pageHTMLfooters[$n[1]])) { $this->HTMLFooter = $this->pageHTMLfooters[$n[1]]; }
9769 else { $this->HTMLFooter = ''; }
9770 $this->footerDetails['odd'] = array();
9771 $resetHTMLHeadersrequired = true;
9772 }
9773 else {
9774 /*-- END HTMLHEADERS-FOOTERS --*/
9775 if (isset($this->pagefooters[$ofname])) { $this->footerDetails['odd'] = $this->pagefooters[$ofname]; }
9776 else if ($ofname!='_default') { $this->footerDetails['odd'] = array(); }
9777 $this->HTMLFooter = '';
9778 /*-- HTMLHEADERS-FOOTERS --*/
9779 $resetHTMLHeadersrequired = true;
9780 }
9781 /*-- END HTMLHEADERS-FOOTERS --*/
9782 }
9783
9784 if ($efvalue<0 || strtoupper($efvalue)=='OFF') {
9785 $this->HTMLFooterE = '';
9786 $this->footerDetails['even'] = array();
9787 $resetHTMLHeadersrequired = true; // *HTMLHEADERS-FOOTERS*
9788 }
9789 else if ($efname && $efvalue>0) {
9790 /*-- HTMLHEADERS-FOOTERS --*/
9791 if (preg_match('/^html_(.*)$/i',$efname,$n)) {
9792 if (isset($this->pageHTMLfooters[$n[1]])) { $this->HTMLFooterE = $this->pageHTMLfooters[$n[1]]; }
9793 else { $this->HTMLFooterE = ''; }
9794 $this->footerDetails['even'] = array();
9795 $resetHTMLHeadersrequired = true;
9796 }
9797 else {
9798 /*-- END HTMLHEADERS-FOOTERS --*/
9799 if (isset($this->pagefooters[$efname])) { $this->footerDetails['even'] = $this->pagefooters[$efname]; }
9800 else if ($efname!='_default') { $this->footerDetails['even'] = array(); }
9801 $this->HTMLFooterE = '';
9802 /*-- HTMLHEADERS-FOOTERS --*/
9803 $resetHTMLHeadersrequired = true;
9804 }
9805 /*-- END HTMLHEADERS-FOOTERS --*/
9806 }
9807 /*-- HTMLHEADERS-FOOTERS --*/
9808 if ($resetHTMLHeadersrequired) {
9809 $this->SetHTMLHeader($this->HTMLHeader );
9810 $this->SetHTMLHeader($this->HTMLHeaderE ,'E');
9811 $this->SetHTMLFooter($this->HTMLFooter );
9812 $this->SetHTMLFooter($this->HTMLFooterE ,'E');
9813 }
9814 /*-- END HTMLHEADERS-FOOTERS --*/
9815
9816
9817 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
9818 $this->_setAutoHeaderHeight($this->headerDetails['even'], $this->HTMLHeaderE);
9819 $this->_setAutoFooterHeight($this->footerDetails['even'], $this->HTMLFooterE);
9820 }
9821 else { // ODD or DEFAULT
9822 $this->_setAutoHeaderHeight($this->headerDetails['odd'], $this->HTMLHeader);
9823 $this->_setAutoFooterHeight($this->footerDetails['odd'], $this->HTMLFooter);
9824 }
9825 // Reset column top margin
9826 $this->y0 = $this->tMargin;
9827
9828 $this->x=$this->lMargin;
9829 $this->y=$this->tMargin;
9830 }
9831
9832
9833
9834 function _setAutoHeaderHeight(&$det, &$htmlh) {
9835 if ($this->setAutoTopMargin=='pad') {
9836 if (isset($htmlh['h']) && $htmlh['h']) { $h = $htmlh['h']; } // 5.7.3
9837 else if ($det) { $h = $this->_getHFHeight($det,'H'); }
9838 else { $h = 0; }
9839 $this->tMargin = $this->margin_header + $h + $this->orig_tMargin;
9840 }
9841 else if ($this->setAutoTopMargin=='stretch') {
9842 if (isset($htmlh['h']) && $htmlh['h']) { $h = $htmlh['h']; } // 5.7.3
9843 else if ($det) { $h = $this->_getHFHeight($det,'H'); }
9844 else { $h = 0; }
9845 $this->tMargin = max($this->orig_tMargin, $this->margin_header + $h + $this->autoMarginPadding);
9846 }
9847 }
9848
9849
9850 function _setAutoFooterHeight(&$det, &$htmlf) {
9851 if ($this->setAutoBottomMargin=='pad') {
9852 if (isset($htmlf['h']) && $htmlf['h']) { $h = $htmlf['h']; } // 5.7.3
9853 else if ($det) { $h = $this->_getHFHeight($det,'F'); }
9854 else { $h = 0; }
9855 $this->bMargin = $this->margin_footer + $h + $this->orig_bMargin;
9856 $this->PageBreakTrigger=$this->h-$this->bMargin ;
9857 }
9858 else if ($this->setAutoBottomMargin=='stretch') {
9859 if (isset($htmlf['h']) && $htmlf['h']) { $h = $htmlf['h']; } // 5.7.3
9860 else if ($det) { $h = $this->_getHFHeight($det,'F'); }
9861 else { $h = 0; }
9862 $this->bMargin = max($this->orig_bMargin, $this->margin_footer + $h + $this->autoMarginPadding);
9863 $this->PageBreakTrigger=$this->h-$this->bMargin ;
9864 }
9865 }
9866
9867 function _getHFHeight(&$det,$end) {
9868 $h = 0;
9869 if(count($det)) {
9870 foreach(array('L','C','R') AS $pos) {
9871 if (isset($det[$pos]['content']) && $det[$pos]['content']) {
9872 if (isset($det[$pos]['font-size']) && $det[$pos]['font-size']) { $hfsz = $det[$pos]['font-size']; }
9873 else { $hfsz = $this->default_font_size; }
9874 $h = max($h,$hfsz/_MPDFK);
9875 }
9876 }
9877 if ($det['line'] && $end=='H') { $h += $h/_MPDFK*$this->header_line_spacing; }
9878 else if ($det['line'] && $end=='F') { $h += $h/_MPDFK*$this->footer_line_spacing; }
9879 }
9880 return $h;
9881 }
9882
9883
9884 function _endpage() {
9885 /*-- CSS-IMAGE-FLOAT --*/
9886 $this->printfloatbuffer();
9887 /*-- END CSS-IMAGE-FLOAT --*/
9888
9889 if($this->visibility!='visible')
9890 $this->SetVisibility('visible');
9891 $this->EndLayer(); // mPDF 5.6.01
9892 //End of page contents
9893 $this->state=1;
9894 }
9895
9896 function _newobj($obj_id=false,$onlynewobj=false) {
9897 if (!$obj_id) {
9898 $obj_id = ++$this->n;
9899 }
9900 //Begin a new object
9901 if (!$onlynewobj) {
9902 $this->offsets[$obj_id] = strlen($this->buffer);
9903 $this->_out($obj_id.' 0 obj');
9904 $this->_current_obj_id = $obj_id; // for later use with encryption
9905 }
9906 }
9907
9908 function _dounderline($x,$y,$txt) {
9909 // Now print line exactly where $y secifies - called from Text() and Cell() - adjust position there
9910 // WORD SPACING
9911 $w =($this->GetStringWidth($txt)*_MPDFK) + ($this->charspacing * mb_strlen( $txt, $this->mb_enc ))
9912 + ( $this->ws * mb_substr_count( $txt, ' ', $this->mb_enc ));
9913 //Draw a line
9914 return sprintf('%.3F %.3F m %.3F %.3F l S',$x*_MPDFK,($this->h-$y)*_MPDFK,($x*_MPDFK)+$w,($this->h-$y)*_MPDFK);
9915 }
9916
9917
9918 function _imageError($file, $firsttime, $msg) {
9919 // Save re-trying image URL's which have already failed
9920 $this->failedimages[$file] = true;
9921 if ($firsttime && ($this->showImageErrors || $this->debug)) {
9922 $this->Error("IMAGE Error (".$file."): ".$msg);
9923 }
9924 return false;
9925 }
9926
9927
9928 function _getImage(&$file, $firsttime=true, $allowvector=true, $orig_srcpath=false) {
9929 // firsttime i.e. whether to add to this->images - use false when calling iteratively
9930 // Image Data passed directly as var:varname
9931 if (preg_match('/var:\s*(.*)/',$file, $v)) {
9932 $data = $this->$v[1];
9933 $file = md5($data);
9934 }
9935 if (preg_match('/data:image\/(gif|jpeg|png);base64,(.*)/',$file, $v)) {
9936 $type = $v[1];
9937 $data = base64_decode($v[2]);
9938 $file = md5($data);
9939 }
9940
9941 // mPDF 5.7.4 URLs
9942 if ($firsttime && $file && substr($file,0,5)!='data:') { $file = str_replace(" ","%20",$file ); }
9943 if ($firsttime && $orig_srcpath) {
9944 // If orig_srcpath is a relative file path (and not a URL), then it needs to be URL decoded
9945 if (substr($orig_srcpath,0,5)!='data:') { $orig_srcpath = str_replace(" ","%20",$orig_srcpath); }
9946 if (!preg_match('/^(http|ftp)/',$orig_srcpath)) { $orig_srcpath = urldecode_parts($orig_srcpath ); }
9947 }
9948
9949
9950 $ppUx = 0;
9951 if ($orig_srcpath && isset($this->images[$orig_srcpath])) { $file=$orig_srcpath; return $this->images[$orig_srcpath]; }
9952 if (isset($this->images[$file])) { return $this->images[$file]; }
9953 else if ($orig_srcpath && isset($this->formobjects[$orig_srcpath])) { $file=$orig_srcpath; return $this->formobjects[$file]; }
9954 else if (isset($this->formobjects[$file])) { return $this->formobjects[$file]; }
9955 // Save re-trying image URL's which have already failed
9956 else if ($firsttime && isset($this->failedimages[$file])) { return $this->_imageError($file, $firsttime, ''); }
9957 if (empty($data)) {
9958 $type = '';
9959 $data = '';
9960
9961 if ($orig_srcpath && $this->basepathIsLocal && $check = @fopen($orig_srcpath,"rb")) {
9962 fclose($check);
9963 $file=$orig_srcpath;
9964 $data = file_get_contents($file);
9965 $type = $this->_imageTypeFromString($data);
9966 }
9967 if (!$data && $check = @fopen($file,"rb")) {
9968 fclose($check);
9969 $data = file_get_contents($file);
9970 $type = $this->_imageTypeFromString($data);
9971 }
9972 if ((!$data || !$type) && !ini_get('allow_url_fopen') ) { // only worth trying if remote file and !ini_get('allow_url_fopen')
9973 $this->file_get_contents_by_socket($file, $data); // needs full url?? even on local (never needed for local)
9974 if ($data) { $type = $this->_imageTypeFromString($data); }
9975 }
9976 if ((!$data || !$type) && function_exists("curl_init")) { // mPDF 5.7.4
9977 $this->file_get_contents_by_curl($file, $data); // needs full url?? even on local (never needed for local)
9978 if ($data) { $type = $this->_imageTypeFromString($data); }
9979 }
9980
9981 }
9982 if (!$data) { return $this->_imageError($file, $firsttime, 'Could not find image file'); }
9983 if (empty($type)) { $type = $this->_imageTypeFromString($data); }
9984 if (($type == 'wmf' || $type == 'svg') && !$allowvector) { return $this->_imageError($file, $firsttime, 'WMF or SVG image file not supported in this context'); }
9985
9986 // SVG
9987 if ($type == 'svg') {
9988 if (!class_exists('SVG', false)) { include(_MPDF_PATH .'classes/svg.php'); }
9989 $svg = new SVG($this);
9990 $family=$this->FontFamily;
9991 $style=$this->FontStyle;
9992 $size=$this->FontSizePt;
9993 $info = $svg->ImageSVG($data);
9994 //Restore font
9995 if($family) $this->SetFont($family,$style,$size,false);
9996 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing SVG file'); }
9997 $info['type']='svg';
9998 $info['i']=count($this->formobjects)+1;
9999 $this->formobjects[$file]=$info;
10000 return $info;
10001 }
10002
10003 // JPEG
10004 if ($type == 'jpeg' || $type == 'jpg') {
10005 $hdr = $this->_jpgHeaderFromString($data);
10006 if (!$hdr) { return $this->_imageError($file, $firsttime, 'Error parsing JPG header'); }
10007 $a = $this->_jpgDataFromHeader($hdr);
10008 $j = strpos($data,'JFIF');
10009 if ($j) {
10010 //Read resolution
10011 $unitSp=ord(substr($data,($j+7),1));
10012 if ($unitSp > 0) {
10013 $ppUx=$this->_twobytes2int(substr($data,($j+8),2)); // horizontal pixels per meter, usually set to zero
10014 if ($unitSp == 2) { // = dots per cm (if == 1 set as dpi)
10015 $ppUx=round($ppUx/10 *25.4);
10016 }
10017 }
10018 }
10019 if ($a[2] == 'DeviceCMYK' && (($this->PDFA && $this->restrictColorSpace!=3) || $this->restrictColorSpace==2)) {
10020 // convert to RGB image
10021 if (!function_exists("gd_info")) { $this->Error("JPG image may not use CMYK color space (".$file.")."); }
10022 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.)"; }
10023 $im = @imagecreatefromstring($data);
10024 if ($im) {
10025 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.md5($file).RAND(1,10000).'.png';
10026 imageinterlace($im, false);
10027 $check = @imagepng($im, $tempfile);
10028 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse JPG(CMYK) image'); }
10029 $info = $this->_getImage($tempfile, false);
10030 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse JPG(CMYK) image'); }
10031 imagedestroy($im);
10032 unlink($tempfile);
10033 $info['type']='jpg';
10034 if ($firsttime) {
10035 $info['i']=count($this->images)+1;
10036 $this->images[$file]=$info;
10037 }
10038 return $info;
10039 }
10040 else { return $this->_imageError($file, $firsttime, 'Error creating GD image file from JPG(CMYK) image'); }
10041 }
10042 else if ($a[2] == 'DeviceRGB' && ($this->PDFX || $this->restrictColorSpace==3)) {
10043 // Convert to CMYK image stream - nominally returned as type='png'
10044 $info = $this->_convImage($data, $a[2], 'DeviceCMYK', $a[0], $a[1], $ppUx, false);
10045 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.)"; }
10046 }
10047 else if (($a[2] == 'DeviceRGB' || $a[2] == 'DeviceCMYK') && $this->restrictColorSpace==1) {
10048 // Convert to Grayscale image stream - nominally returned as type='png'
10049 $info = $this->_convImage($data, $a[2], 'DeviceGray', $a[0], $a[1], $ppUx, false);
10050 }
10051 else {
10052 $info = array('w'=>$a[0],'h'=>$a[1],'cs'=>$a[2],'bpc'=>$a[3],'f'=>'DCTDecode','data'=>$data, 'type'=>'jpg');
10053 if ($ppUx) { $info['set-dpi'] = $ppUx; }
10054 }
10055 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing or converting JPG image'); }
10056
10057 if ($firsttime) {
10058 $info['i']=count($this->images)+1;
10059 $this->images[$file]=$info;
10060 }
10061 return $info;
10062 }
10063
10064 // PNG
10065 else if ($type == 'png') {
10066 //Check signature
10067 if(substr($data,0,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
10068 return $this->_imageError($file, $firsttime, 'Error parsing PNG identifier');
10069 }
10070 //Read header chunk
10071 if(substr($data,12,4)!='IHDR') {
10072 return $this->_imageError($file, $firsttime, 'Incorrect PNG file (no IHDR block found)');
10073 }
10074
10075 $w=$this->_fourbytes2int(substr($data,16,4));
10076 $h=$this->_fourbytes2int(substr($data,20,4));
10077 $bpc=ord(substr($data,24,1));
10078 $errpng = false;
10079 $pngalpha = false;
10080 if($bpc>8) { $errpng = 'not 8-bit depth'; }
10081 $ct=ord(substr($data,25,1));
10082 if($ct==0) { $colspace='DeviceGray'; }
10083 elseif($ct==2) { $colspace='DeviceRGB'; }
10084 elseif($ct==3) { $colspace='Indexed'; }
10085 elseif($ct==4) { $colspace='DeviceGray'; $errpng = 'alpha channel'; $pngalpha = true; }
10086 else { $colspace='DeviceRGB'; $errpng = 'alpha channel'; $pngalpha = true; }
10087 if(ord(substr($data,26,1))!=0) { $errpng = 'compression method'; }
10088 if(ord(substr($data,27,1))!=0) { $errpng = 'filter method'; }
10089 if(ord(substr($data,28,1))!=0) { $errpng = 'interlaced file'; }
10090 $j = strpos($data,'pHYs');
10091 if ($j) {
10092 //Read resolution
10093 $unitSp=ord(substr($data,($j+12),1));
10094 if ($unitSp == 1) {
10095 $ppUx=$this->_fourbytes2int(substr($data,($j+4),4)); // horizontal pixels per meter, usually set to zero
10096 $ppUx=round($ppUx/1000 *25.4);
10097 }
10098 }
10099 if (($colspace == 'DeviceRGB' || $colspace == 'Indexed') && ($this->PDFX || $this->restrictColorSpace==3)) {
10100 // Convert to CMYK image stream - nominally returned as type='png'
10101 $info = $this->_convImage($data, $colspace, 'DeviceCMYK', $w, $h, $ppUx, $pngalpha);
10102 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.)"; }
10103 }
10104 else if (($colspace == 'DeviceRGB' || $colspace == 'Indexed') && $this->restrictColorSpace==1) {
10105 // Convert to Grayscale image stream - nominally returned as type='png'
10106 $info = $this->_convImage($data, $colspace, 'DeviceGray', $w, $h, $ppUx, $pngalpha);
10107 }
10108 else if (($this->PDFA || $this->PDFX) && $pngalpha) {
10109 // Remove alpha channel
10110 if ($this->restrictColorSpace==1) { // Grayscale
10111 $info = $this->_convImage($data, $colspace, 'DeviceGray', $w, $h, $ppUx, $pngalpha);
10112 }
10113 else if ($this->restrictColorSpace==3) { // CMYK
10114 $info = $this->_convImage($data, $colspace, 'DeviceCMYK', $w, $h, $ppUx, $pngalpha);
10115 }
10116 else if ($this->PDFA ) { // RGB
10117 $info = $this->_convImage($data, $colspace, 'DeviceRGB', $w, $h, $ppUx, $pngalpha);
10118 }
10119 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.)"; }
10120 }
10121 else if ($errpng || $pngalpha) {
10122 if (function_exists('gd_info')) { $gd = gd_info(); }
10123 else {$gd = array(); }
10124 if (!isset($gd['PNG Support'])) { return $this->_imageError($file, $firsttime, 'GD library required for PNG image ('.$errpng.')'); }
10125 $im = imagecreatefromstring($data);
10126 if (!$im) { return $this->_imageError($file, $firsttime, 'Error creating GD image from PNG file ('.$errpng.')'); }
10127 $w = imagesx($im);
10128 $h = imagesy($im);
10129 if ($im) {
10130 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.md5($file).RAND(1,10000).'.png';
10131 // Alpha channel set
10132 if ($pngalpha) {
10133 if ($this->PDFA) { $this->Error("PDFA1-b does not permit images with alpha channel transparency (".$file.")."); }
10134 $imgalpha = imagecreate($w, $h);
10135 // generate gray scale pallete
10136 for ($c = 0; $c < 256; ++$c) { ImageColorAllocate($imgalpha, $c, $c, $c); }
10137 // extract alpha channel
10138 for ($xpx = 0; $xpx < $w; ++$xpx) {
10139 for ($ypx = 0; $ypx < $h; ++$ypx) {
10140 $alpha = (imagecolorat($im, $xpx, $ypx) & 0x7F000000) >> 24;
10141 // mPDF 5.7.2
10142 if ($alpha < 127) {
10143 imagesetpixel($imgalpha, $xpx, $ypx, (255-($alpha * 2)));
10144 }
10145 }
10146 }
10147 // create temp alpha file
10148 $tempfile_alpha = _MPDF_TEMP_PATH.'_tempMskPNG'.md5($file).RAND(1,10000).'.png';
10149 if (!is_writable(_MPDF_TEMP_PATH)) { // mPDF 5.7.2
10150 ob_start();
10151 $check = @imagepng($imgalpha);
10152 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
10153 imagedestroy($imgalpha);
10154 $this->_tempimg = ob_get_contents();
10155 $this->_tempimglnk = 'var:_tempimg';
10156 ob_end_clean();
10157 // extract image without alpha channel
10158 $imgplain = imagecreatetruecolor($w, $h);
10159 imagealphablending( $imgplain, false ); // mPDF 5.7.2
10160 imagecopy($imgplain, $im, 0, 0, 0, 0, $w, $h);
10161 // create temp image file
10162 $minfo = $this->_getImage($this->_tempimglnk, false);
10163 if (!$minfo) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
10164 ob_start();
10165 $check = @imagepng($imgplain);
10166 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
10167 $this->_tempimg = ob_get_contents();
10168 $this->_tempimglnk = 'var:_tempimg';
10169 ob_end_clean();
10170 $info = $this->_getImage($this->_tempimglnk, false);
10171 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
10172 imagedestroy($imgplain);
10173 $imgmask = count($this->images)+1;
10174 $minfo['cs'] = 'DeviceGray';
10175 $minfo['i']=$imgmask ;
10176 $this->images[$tempfile_alpha] = $minfo;
10177
10178 }
10179 else {
10180 $check = @imagepng($imgalpha, $tempfile_alpha);
10181 if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile_alpha.') parsing PNG image with alpha channel ('.$errpng.')'); }
10182 imagedestroy($imgalpha);
10183
10184 // extract image without alpha channel
10185 $imgplain = imagecreatetruecolor($w, $h);
10186 imagealphablending( $imgplain, false ); // mPDF 5.7.2
10187 imagecopy($imgplain, $im, 0, 0, 0, 0, $w, $h);
10188
10189 // create temp image file
10190 $check = @imagepng($imgplain, $tempfile);
10191 if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile.') parsing PNG image with alpha channel ('.$errpng.')'); }
10192 imagedestroy($imgplain);
10193 // embed mask image
10194 $minfo = $this->_getImage($tempfile_alpha, false);
10195 unlink($tempfile_alpha);
10196 if (!$minfo) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile_alpha.') created with GD library to parse PNG image'); }
10197 $imgmask = count($this->images)+1;
10198 $minfo['cs'] = 'DeviceGray';
10199 $minfo['i']=$imgmask ;
10200 $this->images[$tempfile_alpha] = $minfo;
10201 // embed image, masked with previously embedded mask
10202 $info = $this->_getImage($tempfile, false);
10203 unlink($tempfile);
10204 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse PNG image'); }
10205
10206 }
10207 $info['masked'] = $imgmask;
10208 if ($ppUx) { $info['set-dpi'] = $ppUx; }
10209 $info['type']='png';
10210 if ($firsttime) {
10211 $info['i']=count($this->images)+1;
10212 $this->images[$file]=$info;
10213 }
10214 return $info;
10215 }
10216 else { // No alpha/transparency set
10217 imagealphablending($im, false);
10218 imagesavealpha($im, false);
10219 imageinterlace($im, false);
10220 if (!is_writable($tempfile)) {
10221 ob_start();
10222 $check = @imagepng($im);
10223 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
10224 $this->_tempimg = ob_get_contents();
10225 $this->_tempimglnk = 'var:_tempimg';
10226 ob_end_clean();
10227 $info = $this->_getImage($this->_tempimglnk, false);
10228 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
10229 imagedestroy($im);
10230 }
10231 else {
10232 $check = @imagepng($im, $tempfile );
10233 if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile.') parsing PNG image ('.$errpng.')'); }
10234 imagedestroy($im);
10235 $info = $this->_getImage($tempfile, false) ;
10236 unlink($tempfile );
10237 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse PNG image'); }
10238 }
10239 if ($ppUx) { $info['set-dpi'] = $ppUx; }
10240 $info['type']='png';
10241 if ($firsttime) {
10242 $info['i']=count($this->images)+1;
10243 $this->images[$file]=$info;
10244 }
10245 return $info;
10246 }
10247 }
10248 }
10249
10250 else {
10251 $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
10252 //Scan chunks looking for palette, transparency and image data
10253 $pal='';
10254 $trns='';
10255 $pngdata='';
10256 $p = 33;
10257 do {
10258 $n=$this->_fourbytes2int(substr($data,$p,4)); $p += 4;
10259 $type=substr($data,$p,4); $p += 4;
10260 if($type=='PLTE') {
10261 //Read palette
10262 $pal=substr($data,$p,$n); $p += $n;
10263 $p += 4;
10264 }
10265 elseif($type=='tRNS') {
10266 //Read transparency info
10267 $t=substr($data,$p,$n); $p += $n;
10268 if($ct==0) $trns=array(ord(substr($t,1,1)));
10269 elseif($ct==2) $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
10270 else
10271 {
10272 $pos=strpos($t,chr(0));
10273 if(is_int($pos)) $trns=array($pos);
10274 }
10275 $p += 4;
10276 }
10277 elseif($type=='IDAT') {
10278 $pngdata.=substr($data,$p,$n); $p += $n;
10279 $p += 4;
10280 }
10281 elseif($type=='IEND') { break; }
10282 else if (preg_match('/[a-zA-Z]{4}/',$type)) { $p += $n+4; }
10283 else { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data'); }
10284 }
10285 while($n);
10286 if (!$pngdata) { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data - no IDAT data found'); }
10287 if($colspace=='Indexed' and empty($pal)) { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data - missing colour palette'); }
10288 $info = array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$pngdata);
10289 $info['type']='png';
10290 if ($ppUx) { $info['set-dpi'] = $ppUx; }
10291 }
10292
10293 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing or converting PNG image'); }
10294
10295 if ($firsttime) {
10296 $info['i']=count($this->images)+1;
10297 $this->images[$file]=$info;
10298 }
10299 return $info;
10300 }
10301
10302 // GIF
10303 else if ($type == 'gif') {
10304 if (function_exists('gd_info')) { $gd = gd_info(); }
10305 else {$gd = array(); }
10306 if (isset($gd['GIF Read Support']) && $gd['GIF Read Support']) {
10307 $im = @imagecreatefromstring($data);
10308 if ($im) {
10309 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.md5($file).RAND(1,10000).'.png';
10310 imagealphablending($im, false);
10311 imagesavealpha($im, false);
10312 imageinterlace($im, false);
10313 if (!is_writable($tempfile)) {
10314 ob_start();
10315 $check = @imagepng($im);
10316 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse GIF image'); }
10317 $this->_tempimg = ob_get_contents();
10318 $this->_tempimglnk = 'var:_tempimg';
10319 ob_end_clean();
10320 $info = $this->_getImage($this->_tempimglnk, false);
10321 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse GIF image'); }
10322 imagedestroy($im);
10323 }
10324 else {
10325 $check = @imagepng($im, $tempfile);
10326 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse GIF image'); }
10327 $info = $this->_getImage($tempfile, false);
10328 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse GIF image'); }
10329 imagedestroy($im);
10330 unlink($tempfile);
10331 }
10332 $info['type']='gif';
10333 if ($firsttime) {
10334 $info['i']=count($this->images)+1;
10335 $this->images[$file]=$info;
10336 }
10337 return $info;
10338 }
10339 else { return $this->_imageError($file, $firsttime, 'Error creating GD image file from GIF image'); }
10340 }
10341
10342 if (!class_exists('gif', false)) {
10343 include_once(_MPDF_PATH.'classes/gif.php');
10344 }
10345 $gif=new CGIF();
10346
10347 $h=0;
10348 $w=0;
10349 $gif->loadFile($data, 0);
10350
10351 if(isset($gif->m_img->m_gih->m_bLocalClr) && $gif->m_img->m_gih->m_bLocalClr) {
10352 $nColors = $gif->m_img->m_gih->m_nTableSize;
10353 $pal = $gif->m_img->m_gih->m_colorTable->toString();
10354 if((isset($bgColor)) and $bgColor != -1) { // mPDF 5.7.3
10355 $bgColor = $gif->m_img->m_gih->m_colorTable->colorIndex($bgColor);
10356 }
10357 $colspace='Indexed';
10358 } elseif(isset($gif->m_gfh->m_bGlobalClr) && $gif->m_gfh->m_bGlobalClr) {
10359 $nColors = $gif->m_gfh->m_nTableSize;
10360 $pal = $gif->m_gfh->m_colorTable->toString();
10361 if((isset($bgColor)) and $bgColor != -1) {
10362 $bgColor = $gif->m_gfh->m_colorTable->colorIndex($bgColor);
10363 }
10364 $colspace='Indexed';
10365 } else {
10366 $nColors = 0;
10367 $bgColor = -1;
10368 $colspace='DeviceGray';
10369 $pal='';
10370 }
10371
10372 $trns='';
10373 if(isset($gif->m_img->m_bTrans) && $gif->m_img->m_bTrans && ($nColors > 0)) {
10374 $trns=array($gif->m_img->m_nTrans);
10375 }
10376 $gifdata=$gif->m_img->m_data;
10377 $w=$gif->m_gfh->m_nWidth;
10378 $h=$gif->m_gfh->m_nHeight;
10379 $gif->ClearData();
10380
10381 if($colspace=='Indexed' and empty($pal)) {
10382 return $this->_imageError($file, $firsttime, 'Error parsing GIF image - missing colour palette');
10383 }
10384 if ($this->compress) {
10385 $gifdata=gzcompress($gifdata);
10386 $info = array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'f'=>'FlateDecode', 'pal'=>$pal, 'trns'=>$trns, 'data'=>$gifdata);
10387 }
10388 else {
10389 $info = array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'pal'=>$pal, 'trns'=>$trns, 'data'=>$gifdata);
10390 }
10391 $info['type']='gif';
10392 if ($firsttime) {
10393 $info['i']=count($this->images)+1;
10394 $this->images[$file]=$info;
10395 }
10396 return $info;
10397 }
10398
10399 /*-- IMAGES-BMP --*/
10400 // BMP (Windows Bitmap)
10401 else if ($type == 'bmp') {
10402 if (!class_exists('bmp', false)) { include(_MPDF_PATH.'classes/bmp.php'); }
10403 if (empty($this->bmp)) { $this->bmp = new bmp($this); }
10404 $info = $this->bmp->_getBMPimage($data, $file);
10405 if (isset($info['error'])) {
10406 return $this->_imageError($file, $firsttime, $info['error']);
10407 }
10408 if ($firsttime) {
10409 $info['i']=count($this->images)+1;
10410 $this->images[$file]=$info;
10411 }
10412 return $info;
10413 }
10414 /*-- END IMAGES-BMP --*/
10415 /*-- IMAGES-WMF --*/
10416 // WMF
10417 else if ($type == 'wmf') {
10418 if (!class_exists('wmf', false)) { include(_MPDF_PATH.'classes/wmf.php'); }
10419 if (empty($this->wmf)) { $this->wmf = new wmf($this); }
10420 $wmfres = $this->wmf->_getWMFimage($data);
10421 if ($wmfres[0]==0) {
10422 if ($wmfres[1]) { return $this->_imageError($file, $firsttime, $wmfres[1]); }
10423 return $this->_imageError($file, $firsttime, 'Error parsing WMF image');
10424 }
10425 $info = array('x'=>$wmfres[2][0],'y'=>$wmfres[2][1],'w'=>$wmfres[3][0],'h'=>$wmfres[3][1],'data'=>$wmfres[1]);
10426 $info['i']=count($this->formobjects)+1;
10427 $info['type']='wmf';
10428 $this->formobjects[$file]=$info;
10429 return $info;
10430 }
10431 /*-- END IMAGES-WMF --*/
10432
10433 // UNKNOWN TYPE - try GD imagecreatefromstring
10434 else {
10435 if (function_exists('gd_info')) { $gd = gd_info(); }
10436 else {$gd = array(); }
10437 if (isset($gd['PNG Support']) && $gd['PNG Support']) {
10438 $im = @imagecreatefromstring($data);
10439 if (!$im) { return $this->_imageError($file, $firsttime, 'Error parsing image file - image type not recognised, and not supported by GD imagecreate'); }
10440 $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.md5($file).RAND(1,10000).'.png';
10441 imagealphablending($im, false);
10442 imagesavealpha($im, false);
10443 imageinterlace($im, false);
10444 $check = @imagepng($im, $tempfile);
10445 if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse unknown image type'); }
10446 $info = $this->_getImage($tempfile, false);
10447 imagedestroy($im);
10448 unlink($tempfile);
10449 if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse unknown image type'); }
10450 $info['type']='png';
10451 if ($firsttime) {
10452 $info['i']=count($this->images)+1;
10453 $this->images[$file]=$info;
10454 }
10455 return $info;
10456 }
10457 }
10458
10459 return $this->_imageError($file, $firsttime, 'Error parsing image file - image type not recognised');
10460 }
10461 //==============================================================
10462 function _convImage(&$data, $colspace, $targetcs, $w, $h, $dpi, $mask) {
10463 if ($this->PDFA || $this->PDFX) { $mask=false; }
10464 $im = @imagecreatefromstring($data);
10465 $info = array();
10466 if ($im) {
10467 $imgdata = '';
10468 $mimgdata = '';
10469 $minfo = array();
10470 //Read transparency info
10471 $trns=array();
10472 $trnsrgb = false;
10473 if (!$this->PDFA && !$this->PDFX) {
10474 $p = strpos($data,'tRNS');
10475 if ($p) {
10476 $n=$this->_fourbytes2int(substr($data,($p-4),4));
10477 $t = substr($data,($p+4),$n);
10478 if ($colspace=='DeviceGray') {
10479 $trns=array(ord(substr($t,1,1)));
10480 $trnsrgb = array($trns[0],$trns[0],$trns[0]);
10481 }
10482 else if ($colspace=='DeviceRGB') {
10483 $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
10484 $trnsrgb = $trns;
10485 if ($targetcs=='DeviceCMYK') {
10486 $col = $this->rgb2cmyk(array(3,$trns[0],$trns[1],$trns[2]));
10487 $c1 = intval($col[1]*2.55);
10488 $c2 = intval($col[2]*2.55);
10489 $c3 = intval($col[3]*2.55);
10490 $c4 = intval($col[4]*2.55);
10491 $trns = array($c1,$c2,$c3,$c4);
10492 }
10493 else if ($targetcs=='DeviceGray') {
10494 $c = intval(($trns[0] * .21) + ($trns[1] * .71) + ($trns[2] * .07));
10495 $trns = array($c);
10496 }
10497 }
10498 else { // Indexed
10499 $pos = strpos($t,chr(0));
10500 if (is_int($pos)) {
10501 $pal = imagecolorsforindex($im, $pos);
10502 $r = $pal['red'];
10503 $g = $pal['green'];
10504 $b = $pal['blue'];
10505 $trns=array($r,$g,$b); // ****
10506 $trnsrgb = $trns;
10507 if ($targetcs=='DeviceCMYK') {
10508 $col = $this->rgb2cmyk(array(3,$r,$g,$b));
10509 $c1 = intval($col[1]*2.55);
10510 $c2 = intval($col[2]*2.55);
10511 $c3 = intval($col[3]*2.55);
10512 $c4 = intval($col[4]*2.55);
10513 $trns = array($c1,$c2,$c3,$c4);
10514 }
10515 else if ($targetcs=='DeviceGray') {
10516 $c = intval(($r * .21) + ($g * .71) + ($b * .07));
10517 $trns = array($c);
10518 }
10519 }
10520 }
10521 }
10522 }
10523 for ($i = 0; $i < $h; $i++) {
10524 for ($j = 0; $j < $w; $j++) {
10525 $rgb = imagecolorat($im, $j, $i);
10526 $r = ($rgb >> 16) & 0xFF;
10527 $g = ($rgb >> 8) & 0xFF;
10528 $b = $rgb & 0xFF;
10529 if ($colspace=='Indexed') {
10530 $pal = imagecolorsforindex($im, $rgb);
10531 $r = $pal['red'];
10532 $g = $pal['green'];
10533 $b = $pal['blue'];
10534 }
10535
10536 if ($targetcs=='DeviceCMYK') {
10537 $col = $this->rgb2cmyk(array(3,$r,$g,$b));
10538 $c1 = intval($col[1]*2.55);
10539 $c2 = intval($col[2]*2.55);
10540 $c3 = intval($col[3]*2.55);
10541 $c4 = intval($col[4]*2.55);
10542 if ($trnsrgb) {
10543 // original pixel was not set as transparent but processed color does match
10544 if ($trnsrgb!=array($r,$g,$b) && $trns==array($c1,$c2,$c3,$c4)) {
10545 if ($c4==0) { $c4=1; } else { $c4--; }
10546 }
10547 }
10548 $imgdata .= chr($c1).chr($c2).chr($c3).chr($c4);
10549 }
10550 else if ($targetcs=='DeviceGray') {
10551 $c = intval(($r * .21) + ($g * .71) + ($b * .07));
10552 if ($trnsrgb) {
10553 // original pixel was not set as transparent but processed color does match
10554 if ($trnsrgb!=array($r,$g,$b) && $trns==array($c)) {
10555 if ($c==0) { $c=1; } else { $c--; }
10556 }
10557 }
10558 $imgdata .= chr($c);
10559 }
10560 else if ($targetcs=='DeviceRGB') {
10561 $imgdata .= chr($r).chr($g).chr($b);
10562 }
10563 if ($mask) {
10564 // mPDF 5.7.2 Gamma correction
10565 $alpha = ($rgb & 0x7F000000) >> 24;
10566 if ($alpha < 127) { $mimgdata .= chr(255-($alpha * 2)); }
10567 else { $mimgdata .= chr(0); }
10568 }
10569 }
10570 }
10571
10572 if ($targetcs=='DeviceGray') { $ncols = 1; }
10573 else if ($targetcs=='DeviceRGB') { $ncols = 3; }
10574 else if ($targetcs=='DeviceCMYK') { $ncols = 4; }
10575
10576 $imgdata = gzcompress($imgdata);
10577 $info = array('w'=>$w,'h'=>$h,'cs'=>$targetcs,'bpc'=>8,'f'=>'FlateDecode','data'=>$imgdata, 'type'=>'png',
10578 'parms'=>'/DecodeParms <</Colors '.$ncols.' /BitsPerComponent 8 /Columns '.$w.'>>');
10579 if ($dpi) { $info['set-dpi'] = $dpi; }
10580 if ($mask) {
10581 $mimgdata = gzcompress($mimgdata);
10582 $minfo = array('w'=>$w,'h'=>$h,'cs'=>'DeviceGray','bpc'=>8,'f'=>'FlateDecode','data'=>$mimgdata, 'type'=>'png',
10583 'parms'=>'/DecodeParms <</Colors '.$ncols.' /BitsPerComponent 8 /Columns '.$w.'>>');
10584 if ($dpi) { $minfo['set-dpi'] = $dpi; }
10585 $tempfile = '_tempImgPNG'.md5($file).RAND(1,10000).'.png';
10586 $imgmask = count($this->images)+1;
10587 $minfo['i']=$imgmask ;
10588 $this->images[$tempfile] = $minfo;
10589 $info['masked'] = $imgmask;
10590 }
10591 else if ($trns) { $info['trns'] = $trns; }
10592 imagedestroy($im);
10593 }
10594 return $info;
10595 }
10596
10597
10598
10599
10600 function _fourbytes2int($s) {
10601 //Read a 4-byte integer from string
10602 return (ord($s[0])<<24) + (ord($s[1])<<16) + (ord($s[2])<<8) + ord($s[3]);
10603 }
10604
10605 function _twobytes2int($s) {
10606 //Read a 2-byte integer from string
10607 return (ord(substr($s, 0, 1))<<8) + ord(substr($s, 1, 1));
10608 }
10609
10610 function _jpgHeaderFromString(&$data) {
10611 $p = 4;
10612 $p += $this->_twobytes2int(substr($data, $p, 2)); // Length of initial marker block
10613 $marker = substr($data, $p, 2);
10614 while($marker != chr(255).chr(192) && $marker != chr(255).chr(194) && $p<strlen($data)) {
10615 // Start of frame marker (FFC0) or (FFC2) mPDF 4.4.004
10616 $p += ($this->_twobytes2int(substr($data, $p+2, 2))) + 2; // Length of marker block
10617 $marker = substr($data, $p, 2);
10618 }
10619 if ($marker != chr(255).chr(192) && $marker != chr(255).chr(194)) { return false; }
10620 return substr($data, $p+2, 10);
10621 }
10622
10623 function _jpgDataFromHeader($hdr) {
10624 $bpc = ord(substr($hdr, 2, 1));
10625 if (!$bpc) { $bpc = 8; }
10626 $h = $this->_twobytes2int(substr($hdr, 3, 2));
10627 $w = $this->_twobytes2int(substr($hdr, 5, 2));
10628 $channels = ord(substr($hdr, 7, 1));
10629 if ($channels==3) { $colspace='DeviceRGB'; }
10630 elseif($channels==4) { $colspace='DeviceCMYK'; }
10631 else { $colspace='DeviceGray'; }
10632 return array($w, $h, $colspace, $bpc);
10633 }
10634
10635 function file_get_contents_by_curl($url, &$data) {
10636 $timeout = 5;
10637 $ch = curl_init($url);
10638 curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0.1'); // mPDF 5.7.4
10639 curl_setopt($ch, CURLOPT_HEADER, 0);
10640 curl_setopt($ch, CURLOPT_NOBODY, 0);
10641 curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , 1 );
10642 curl_setopt ( $ch , CURLOPT_CONNECTTIMEOUT , $timeout );
10643 $data = curl_exec($ch);
10644 curl_close($ch);
10645 }
10646
10647
10648 function file_get_contents_by_socket($url, &$data) {
10649 // mPDF 5.7.3
10650 $timeout = 1;
10651 $p = parse_url($url);
10652 $file = $p['path'];
10653 if ($p['scheme']=='https') {
10654 $prefix = 'ssl://';
10655 $port = ($p['port'] ? $p['port'] : 443);
10656 }
10657 else {
10658 $prefix = '';
10659 $port = ($p['port'] ? $p['port'] : 80);
10660 }
10661 if ($p['query']) { $file .= '?'.$p['query']; }
10662 if(!($fh = @fsockopen($prefix.$p['host'], $port, $errno, $errstr, $timeout))) { return false; }
10663
10664 $getstring =
10665 "GET ".$file." HTTP/1.0 \r\n" .
10666 "Host: ".$p['host']." \r\n" .
10667 "Connection: close\r\n\r\n";
10668 fwrite($fh, $getstring);
10669 // Get rid of HTTP header
10670 $s = fgets($fh, 1024);
10671 if (!$s) { return false; }
10672 $httpheader .= $s;
10673 while (!feof($fh)) {
10674 $s = fgets($fh, 1024);
10675 if ( $s == "\r\n" ) { break; }
10676 }
10677 $data = '';
10678 while (!feof($fh)) {
10679 $data .= fgets($fh, 1024);
10680 }
10681 fclose($fh);
10682 }
10683
10684 //==============================================================
10685
10686 function _imageTypeFromString(&$data) {
10687 $type = '';
10688 if (substr($data, 6, 4)== 'JFIF' || substr($data, 6, 4)== 'Exif' || substr($data, 0, 2)== chr(255).chr(216)) { // 0xFF 0xD8 // mpDF 5.7.2
10689 $type = 'jpeg';
10690 }
10691 else if (substr($data, 0, 6)== "GIF87a" || substr($data, 0, 6)== "GIF89a") {
10692 $type = 'gif';
10693 }
10694 else if (substr($data, 0, 8)== chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
10695 $type = 'png';
10696 }
10697 /*-- IMAGES-WMF --*/
10698 else if (substr($data, 0, 4)== chr(215).chr(205).chr(198).chr(154)) {
10699 $type = 'wmf';
10700 }
10701 /*-- END IMAGES-WMF --*/
10702 else if (preg_match('/<svg.*<\/svg>/is',$data)) {
10703 $type = 'svg';
10704 }
10705 // BMP images
10706 else if (substr($data, 0, 2)== "BM") {
10707 $type = 'bmp';
10708 }
10709 return $type;
10710 }
10711 //==============================================================
10712
10713 // Moved outside WMF as also needed for SVG
10714 function _putformobjects() {
10715 reset($this->formobjects);
10716 while(list($file,$info)=each($this->formobjects)) {
10717 $this->_newobj();
10718 $this->formobjects[$file]['n']=$this->n;
10719 $this->_out('<</Type /XObject');
10720 $this->_out('/Subtype /Form');
10721 $this->_out('/Group '.($this->n+1).' 0 R');
10722 $this->_out('/BBox ['.$info['x'].' '.$info['y'].' '.($info['w']+$info['x']).' '.($info['h']+$info['y']).']');
10723 if ($this->compress)
10724 $this->_out('/Filter /FlateDecode');
10725 $data=($this->compress) ? gzcompress($info['data']) : $info['data'];
10726 $this->_out('/Length '.strlen($data).'>>');
10727 $this->_putstream($data);
10728 unset($this->formobjects[$file]['data']);
10729 $this->_out('endobj');
10730 // Required for SVG transparency (opacity) to work
10731 $this->_newobj();
10732 $this->_out('<</Type /Group');
10733 $this->_out('/S /Transparency');
10734 $this->_out('>>');
10735 $this->_out('endobj');
10736 }
10737 }
10738
10739 function _freadint($f)
10740 {
10741 //Read a 4-byte integer from file
10742 $i=ord(fread($f,1))<<24;
10743 $i+=ord(fread($f,1))<<16;
10744 $i+=ord(fread($f,1))<<8;
10745 $i+=ord(fread($f,1));
10746 return $i;
10747 }
10748
10749 function _UTF16BEtextstring($s) {
10750 $s = $this->UTF8ToUTF16BE($s, true);
10751 /*-- ENCRYPTION --*/
10752 if ($this->encrypted) {
10753 $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
10754 }
10755 /*-- END ENCRYPTION --*/
10756 return '('. $this->_escape($s).')';
10757 }
10758
10759 function _textstring($s) {
10760 /*-- ENCRYPTION --*/
10761 if ($this->encrypted) {
10762 $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
10763 }
10764 /*-- END ENCRYPTION --*/
10765 return '('. $this->_escape($s).')';
10766 }
10767
10768
10769 function _escape($s)
10770 {
10771 // the chr(13) substitution fixes the Bugs item #1421290.
10772 return strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r'));
10773 }
10774
10775 function _putstream($s) {
10776 /*-- ENCRYPTION --*/
10777 if ($this->encrypted) {
10778 $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
10779 }
10780 /*-- END ENCRYPTION --*/
10781 $this->_out('stream');
10782 $this->_out($s);
10783 $this->_out('endstream');
10784 }
10785
10786
10787 function _out($s,$ln=true) {
10788 if($this->state==2) {
10789 if ($this->bufferoutput) {
10790 $this->headerbuffer.= $s."\n";
10791 }
10792 /*-- COLUMNS --*/
10793 else if (($this->ColActive) && !$this->processingHeader && !$this->processingFooter) {
10794 // Captures everything in buffer for columns; Almost everything is sent from fn. Cell() except:
10795 // Images sent from Image() or
10796 // later sent as _out($textto) in printbuffer
10797 // Line()
10798 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
10799 $h = ($m[1]/_MPDFK);
10800 // Update/overwrite the lowest bottom of printing y value for a column
10801 $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$h;
10802 }
10803 /*-- TABLES --*/
10804 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
10805 $h = ($m[1]/_MPDFK);
10806 // Update/overwrite the lowest bottom of printing y value for a column
10807 $this->ColDetails[$this->CurrCol]['bottom_margin'] = max($this->ColDetails[$this->CurrCol]['bottom_margin'],($this->y+$h));
10808 }
10809 /*-- END TABLES --*/
10810 else { // Td Text Set in Cell()
10811 if (isset($this->ColDetails[$this->CurrCol]['bottom_margin'])) { $h = $this->ColDetails[$this->CurrCol]['bottom_margin'] - $this->y; }
10812 else { $h = 0; }
10813 }
10814 if ($h < 0) { $h = -$h; }
10815 $this->columnbuffer[] = array(
10816 's' => $s, // Text string to output
10817 'col' => $this->CurrCol, // Column when printed
10818 'x' => $this->x, // x when printed
10819 'y' => $this->y, // this->y when printed (after column break)
10820 'h' => $h // actual y at bottom when printed = y+h
10821 );
10822 }
10823 /*-- END COLUMNS --*/
10824 /*-- TABLES --*/
10825 else if ($this->table_rotate && !$this->processingHeader && !$this->processingFooter) {
10826 // Captures eveything in buffer for rotated tables;
10827 $this->tablebuffer .= $s . "\n";
10828 }
10829 /*-- END TABLES --*/
10830 else if ($this->kwt && !$this->processingHeader && !$this->processingFooter) {
10831 // Captures eveything in buffer for keep-with-table (h1-6);
10832 $this->kwt_buffer[] = array(
10833 's' => $s, // Text string to output
10834 'x' => $this->x, // x when printed
10835 'y' => $this->y, // y when printed
10836 );
10837 }
10838 else if (($this->keep_block_together) && !$this->processingHeader && !$this->processingFooter) {
10839 if (!isset($this->ktBlock[$this->page]['bottom_margin'])) {
10840 $this->ktBlock[$this->page]['bottom_margin'] = $this->y;
10841 }
10842
10843 // Captures eveything in buffer;
10844 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
10845 $h = ($m[1]/_MPDFK);
10846 // Update/overwrite the lowest bottom of printing y value for Keep together block
10847 $this->ktBlock[$this->page]['bottom_margin'] = $this->y+$h;
10848 }
10849 else { // Td Text Set in Cell()
10850 if (isset($this->ktBlock[$this->page]['bottom_margin'])) { $h = $this->ktBlock[$this->page]['bottom_margin'] - $this->y; }
10851 else { $h = 0; }
10852 }
10853 if ($h < 0) { $h = -$h; }
10854 $this->divbuffer[] = array(
10855 'page' => $this->page,
10856 's' => $s, // Text string to output
10857 'x' => $this->x, // x when printed
10858 'y' => $this->y, // y when printed (after column break)
10859 'h' => $h // actual y at bottom when printed = y+h
10860 );
10861 }
10862 else {
10863 $this->pages[$this->page] .= $s.($ln == true ? "\n" : '');
10864 }
10865
10866 }
10867 else {
10868 $this->buffer .= $s.($ln == true ? "\n" : '');
10869 }
10870 }
10871
10872 /*-- WATERMARK --*/
10873 // add a watermark
10874 function watermark( $texte, $angle=45, $fontsize=96, $alpha=0.2 ) {
10875 if ($this->PDFA || $this->PDFX) { $this->Error('PDFA and PDFX do not permit transparency, so mPDF does not allow Watermarks!'); }
10876 if (!$this->watermark_font) { $this->watermark_font = $this->default_font; }
10877 $this->SetFont( $this->watermark_font, "B", $fontsize, false ); // Don't output
10878 $texte= $this->purify_utf8_text($texte);
10879 if ($this->text_input_as_HTML) {
10880 $texte= $this->all_entities_to_utf8($texte);
10881 }
10882 if ($this->usingCoreFont) { $texte = mb_convert_encoding($texte,$this->mb_enc,'UTF-8'); }
10883 // DIRECTIONALITY
10884 $this->magic_reverse_dir($texte, true, $this->directionality); // *RTL*
10885 // Font-specific ligature substitution for Indic fonts
10886 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($texte); // *INDIC*
10887
10888 $this->SetAlpha($alpha);
10889
10890 $this->SetTColor($this->ConvertColor(0));
10891 $szfont = $fontsize;
10892 $loop = 0;
10893 $maxlen = (min($this->w,$this->h) ); // sets max length of text as 7/8 width/height of page
10894 while ( $loop == 0 )
10895 {
10896 $this->SetFont( $this->watermark_font, "B", $szfont, false ); // Don't output
10897 $offset = ((sin(deg2rad($angle))) * ($szfont/_MPDFK));
10898
10899 $strlen = $this->GetStringWidth($texte);
10900 if ( $strlen > $maxlen - $offset )
10901 $szfont --;
10902 else
10903 $loop ++;
10904 }
10905
10906 $this->SetFont( $this->watermark_font, "B", $szfont-0.1, true, true); // Output The -0.1 is because SetFont above is not written to PDF
10907 // Repeating it will not output anything as mPDF thinks it is set
10908 $adj = ((cos(deg2rad($angle))) * ($strlen/2));
10909 $opp = ((sin(deg2rad($angle))) * ($strlen/2));
10910 $wx = ($this->w/2) - $adj + $offset/3;
10911 $wy = ($this->h/2) + $opp;
10912 $this->Rotate($angle,$wx,$wy);
10913 $this->Text($wx,$wy,$texte);
10914 $this->Rotate(0);
10915 $this->SetTColor($this->ConvertColor(0));
10916
10917 $this->SetAlpha(1);
10918
10919 }
10920
10921 function watermarkImg( $src, $alpha=0.2 ) {
10922 if ($this->PDFA || $this->PDFX) { $this->Error('PDFA and PDFX do not permit transparency, so mPDF does not allow Watermarks!'); }
10923 if ($this->watermarkImgBehind) { $this->watermarkImgAlpha = $this->SetAlpha($alpha, 'Normal', true); }
10924 else { $this->SetAlpha($alpha, $this->watermarkImgAlphaBlend); }
10925 $this->Image($src,0,0,0,0,'','', true, true, true);
10926 if (!$this->watermarkImgBehind) { $this->SetAlpha(1); }
10927 }
10928 /*-- END WATERMARK --*/
10929
10930
10931 function Rotate($angle,$x=-1,$y=-1)
10932 {
10933 if($x==-1)
10934 $x=$this->x;
10935 if($y==-1)
10936 $y=$this->y;
10937 if($this->angle!=0)
10938 $this->_out('Q');
10939 $this->angle=$angle;
10940 if($angle!=0)
10941 {
10942 $angle*=M_PI/180;
10943 $c=cos($angle);
10944 $s=sin($angle);
10945 $cx=$x*_MPDFK;
10946 $cy=($this->h-$y)*_MPDFK;
10947 $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));
10948 }
10949 }
10950
10951
10952
10953 function CircularText($x, $y, $r, $text, $align='top', $fontfamily='', $fontsize=0, $fontstyle='', $kerning=120, $fontwidth=100, $divider) { // mPDF 5.5.23
10954 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
10955 if (empty($this->directw)) { $this->directw = new directw($this); }
10956 $this->directw->CircularText($x, $y, $r, $text, $align, $fontfamily, $fontsize, $fontstyle, $kerning, $fontwidth, $divider); // mPDF 5.5.23
10957 }
10958
10959
10960 // From Invoice
10961 function RoundedRect($x, $y, $w, $h, $r, $style = '')
10962 {
10963 $hp = $this->h;
10964 if($style=='F')
10965 $op='f';
10966 elseif($style=='FD' or $style=='DF')
10967 $op='B';
10968 else
10969 $op='S';
10970 $MyArc = 4/3 * (sqrt(2) - 1);
10971 $this->_out(sprintf('%.3F %.3F m',($x+$r)*_MPDFK,($hp-$y)*_MPDFK ));
10972 $xc = $x+$w-$r ;
10973 $yc = $y+$r;
10974 $this->_out(sprintf('%.3F %.3F l', $xc*_MPDFK,($hp-$y)*_MPDFK ));
10975
10976 $this->_Arc($xc + $r*$MyArc, $yc - $r, $xc + $r, $yc - $r*$MyArc, $xc + $r, $yc);
10977 $xc = $x+$w-$r ;
10978 $yc = $y+$h-$r;
10979 $this->_out(sprintf('%.3F %.3F l',($x+$w)*_MPDFK,($hp-$yc)*_MPDFK));
10980 $this->_Arc($xc + $r, $yc + $r*$MyArc, $xc + $r*$MyArc, $yc + $r, $xc, $yc + $r);
10981 $xc = $x+$r ;
10982 $yc = $y+$h-$r;
10983 $this->_out(sprintf('%.3F %.3F l',$xc*_MPDFK,($hp-($y+$h))*_MPDFK));
10984 $this->_Arc($xc - $r*$MyArc, $yc + $r, $xc - $r, $yc + $r*$MyArc, $xc - $r, $yc);
10985 $xc = $x+$r ;
10986 $yc = $y+$r;
10987 $this->_out(sprintf('%.3F %.3F l',($x)*_MPDFK,($hp-$yc)*_MPDFK ));
10988 $this->_Arc($xc - $r, $yc - $r*$MyArc, $xc - $r*$MyArc, $yc - $r, $xc, $yc - $r);
10989 $this->_out($op);
10990 }
10991
10992 function _Arc($x1, $y1, $x2, $y2, $x3, $y3)
10993 {
10994 $h = $this->h;
10995 $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', $x1*_MPDFK, ($h-$y1)*_MPDFK,
10996 $x2*_MPDFK, ($h-$y2)*_MPDFK, $x3*_MPDFK, ($h-$y3)*_MPDFK));
10997 }
10998
10999
11000
11001
11002 //====================================================
11003
11004
11005
11006 /*-- DIRECTW --*/
11007 function Shaded_box( $text,$font='',$fontstyle='B',$szfont='',$width='70%',$style='DF',$radius=2.5,$fill='#FFFFFF',$color='#000000',$pad=2 ) {
11008 // F (shading - no line),S (line, no shading),DF (both)
11009 if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
11010 if (empty($this->directw)) { $this->directw = new directw($this); }
11011 $this->directw->Shaded_box( $text,$font,$fontstyle,$szfont,$width,$style,$radius,$fill,$color,$pad);
11012 }
11013 /*-- END DIRECTW --*/
11014
11015
11016 function UTF8StringToArray($str, $addSubset=true) {
11017 $out = array();
11018 $len = strlen($str);
11019 for ($i = 0; $i < $len; $i++) {
11020 $uni = -1;
11021 $h = ord($str[$i]);
11022 if ( $h <= 0x7F )
11023 $uni = $h;
11024 elseif ( $h >= 0xC2 ) {
11025 if ( ($h <= 0xDF) && ($i < $len -1) )
11026 $uni = ($h & 0x1F) << 6 | (ord($str[++$i]) & 0x3F);
11027 elseif ( ($h <= 0xEF) && ($i < $len -2) )
11028 $uni = ($h & 0x0F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F);
11029 elseif ( ($h <= 0xF4) && ($i < $len -3) )
11030 $uni = ($h & 0x0F) << 18 | (ord($str[++$i]) & 0x3F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F);
11031 }
11032 if ($uni >= 0) {
11033 $out[] = $uni;
11034 if ($addSubset && isset($this->CurrentFont['subset'])) {
11035 $this->CurrentFont['subset'][$uni] = $uni;
11036 }
11037 }
11038 }
11039 return $out;
11040 }
11041
11042
11043 //Convert utf-8 string to <HHHHHH> for Font Subsets
11044 function UTF8toSubset($str) {
11045 $ret = '<';
11046 $str = preg_replace('/'.preg_quote($this->aliasNbPg,'/').'/', chr(7), $str );
11047 $str = preg_replace('/'.preg_quote($this->aliasNbPgGp,'/').'/', chr(8), $str );
11048 $unicode = $this->UTF8StringToArray($str);
11049 $orig_fid = $this->CurrentFont['subsetfontids'][0];
11050 $last_fid = $this->CurrentFont['subsetfontids'][0];
11051 foreach($unicode as $c) {
11052 if ($c == 7 || $c == 8) {
11053 if ($orig_fid != $last_fid) {
11054 $ret .= '> Tj /F'.$orig_fid.' '.$this->FontSizePt.' Tf <';
11055 $last_fid = $orig_fid;
11056 }
11057 if ($c == 7) { $ret .= $this->aliasNbPgHex; }
11058 else { $ret .= $this->aliasNbPgGpHex; }
11059 continue;
11060 }
11061 for ($i=0; $i<99; $i++) {
11062 // return c as decimal char
11063 $init = array_search($c, $this->CurrentFont['subsets'][$i]);
11064 if ($init!==false) {
11065 if ($this->CurrentFont['subsetfontids'][$i] != $last_fid) {
11066 $ret .= '> Tj /F'.$this->CurrentFont['subsetfontids'][$i].' '.$this->FontSizePt.' Tf <';
11067 $last_fid = $this->CurrentFont['subsetfontids'][$i];
11068 }
11069 $ret .= sprintf("%02s", strtoupper(dechex($init)));
11070 break;
11071 }
11072 // TrueType embedded SUBSETS
11073 else if (count($this->CurrentFont['subsets'][$i]) < 255) {
11074 $n = count($this->CurrentFont['subsets'][$i]);
11075 $this->CurrentFont['subsets'][$i][$n] = $c;
11076 if ($this->CurrentFont['subsetfontids'][$i] != $last_fid) {
11077 $ret .= '> Tj /F'.$this->CurrentFont['subsetfontids'][$i].' '.$this->FontSizePt.' Tf <';
11078 $last_fid = $this->CurrentFont['subsetfontids'][$i];
11079 }
11080 $ret .= sprintf("%02s", strtoupper(dechex($n)));
11081 break;
11082 }
11083 else if (!isset($this->CurrentFont['subsets'][($i+1)])) {
11084 // TrueType embedded SUBSETS
11085 $this->CurrentFont['subsets'][($i+1)] = array(0=>0);
11086 $new_fid = count($this->fonts)+$this->extraFontSubsets+1;
11087 $this->CurrentFont['subsetfontids'][($i+1)] = $new_fid;
11088 $this->extraFontSubsets++;
11089 }
11090 }
11091 }
11092 $ret .= '>';
11093 if ($last_fid != $orig_fid) {
11094 $ret .= ' Tj /F'.$orig_fid.' '.$this->FontSizePt.' Tf <> ';
11095 }
11096 return $ret;
11097 }
11098
11099
11100 // Converts UTF-8 strings to UTF16-BE.
11101 function UTF8ToUTF16BE($str, $setbom=true) {
11102 if ($this->checkSIP && preg_match("/([\x{20000}-\x{2FFFF}])/u", $str)) {
11103 if (!in_array($this->currentfontfamily, array('gb','big5','sjis','uhc','gbB','big5B','sjisB','uhcB','gbI','big5I','sjisI','uhcI',
11104 'gbBI','big5BI','sjisBI','uhcBI'))) {
11105 $str = preg_replace("/[\x{20000}-\x{2FFFF}]/u", chr(0), $str);
11106 }
11107 }
11108 if ($this->checkSMP && preg_match("/([\x{10000}-\x{1FFFF}])/u", $str )) {
11109 $str = preg_replace("/[\x{10000}-\x{1FFFF}]/u", chr(0), $str );
11110 }
11111 $outstr = ""; // string to be returned
11112 if ($setbom) {
11113 $outstr .= "\xFE\xFF"; // Byte Order Mark (BOM)
11114 }
11115 $outstr .= mb_convert_encoding($str, 'UTF-16BE', 'UTF-8');
11116 return $outstr;
11117 }
11118
11119
11120
11121
11122
11123 // ====================================================
11124 // ====================================================
11125 /*-- CJK-FONTS --*/
11126
11127 // from class PDF_Chinese CJK EXTENSIONS
11128 function AddCIDFont($family,$style,$name,&$cw,$CMap,$registry,$desc)
11129 {
11130 $fontkey=strtolower($family).strtoupper($style);
11131 if(isset($this->fonts[$fontkey]))
11132 $this->Error("Font already added: $family $style");
11133 $i=count($this->fonts)+$this->extraFontSubsets+1;
11134 $name=str_replace(' ','',$name);
11135 if ($family == 'sjis') { $up = -120; } else { $up = -130; }
11136 // ? 'up' and 'ut' do not seem to be referenced anywhere
11137 $this->fonts[$fontkey]=array('i'=>$i,'type'=>'Type0','name'=>$name,'up'=>$up,'ut'=>40,'cw'=>$cw,'CMap'=>$CMap,'registry'=>$registry,'MissingWidth'=>1000,'desc'=>$desc);
11138 }
11139
11140 function AddCJKFont($family) {
11141
11142 if ($this->PDFA || $this->PDFX) {
11143 $this->Error("Adobe CJK fonts cannot be embedded in mPDF (required for PDFA1-b and PDFX/1-a).");
11144 }
11145 if ($family == 'big5') { $this->AddBig5Font(); }
11146 else if ($family == 'gb') { $this->AddGBFont(); }
11147 else if ($family == 'sjis') { $this->AddSJISFont(); }
11148 else if ($family == 'uhc') { $this->AddUHCFont(); }
11149 }
11150
11151 function AddBig5Font()
11152 {
11153 //Add Big5 font with proportional Latin
11154 $family='big5';
11155 $name='MSungStd-Light-Acro';
11156 $cw=$this->Big5_widths;
11157 $CMap='UniCNS-UTF16-H';
11158 $registry=array('ordering'=>'CNS1','supplement'=>4);
11159 $desc = array(
11160 'Ascent' => 880,
11161 'Descent' => -120,
11162 'CapHeight' => 880,
11163 'Flags' => 6,
11164 'FontBBox' => '[-160 -249 1015 1071]',
11165 'ItalicAngle' => 0,
11166 'StemV' => 93,
11167 );
11168 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
11169 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
11170 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
11171 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
11172 }
11173
11174
11175 function AddGBFont()
11176 {
11177 //Add GB font with proportional Latin
11178 $family='gb';
11179 $name='STSongStd-Light-Acro';
11180 $cw=$this->GB_widths;
11181 $CMap='UniGB-UTF16-H';
11182 $registry=array('ordering'=>'GB1','supplement'=>4);
11183 $desc = array(
11184 'Ascent' => 752,
11185 'Descent' => -271,
11186 'CapHeight' => 737,
11187 'Flags' => 6,
11188 'FontBBox' => '[-25 -254 1000 880]',
11189 'ItalicAngle' => 0,
11190 'StemV' => 58,
11191 'Style' => '<< /Panose <000000000400000000000000> >>',
11192 );
11193 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
11194 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
11195 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
11196 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
11197 }
11198
11199
11200 function AddSJISFont()
11201 {
11202 //Add SJIS font with proportional Latin
11203 $family='sjis';
11204 $name='KozMinPro-Regular-Acro';
11205 $cw=$this->SJIS_widths;
11206 $CMap='UniJIS-UTF16-H';
11207 $registry=array('ordering'=>'Japan1','supplement'=>5);
11208 $desc = array(
11209 'Ascent' => 880,
11210 'Descent' => -120,
11211 'CapHeight' => 740,
11212 'Flags' => 6,
11213 'FontBBox' => '[-195 -272 1110 1075]',
11214 'ItalicAngle' => 0,
11215 'StemV' => 86,
11216 'XHeight' => 502,
11217 );
11218 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
11219 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
11220 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
11221 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
11222 }
11223
11224 function AddUHCFont()
11225 {
11226 //Add UHC font with proportional Latin
11227 $family='uhc';
11228 $name='HYSMyeongJoStd-Medium-Acro';
11229 $cw=$this->UHC_widths;
11230 $CMap='UniKS-UTF16-H';
11231 $registry=array('ordering'=>'Korea1','supplement'=>2);
11232 $desc = array(
11233 'Ascent' => 880,
11234 'Descent' => -120,
11235 'CapHeight' => 720,
11236 'Flags' => 6,
11237 'FontBBox' => '[-28 -148 1001 880]',
11238 'ItalicAngle' => 0,
11239 'StemV' => 60,
11240 'Style' => '<< /Panose <000000000600000000000000> >>',
11241 );
11242 $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
11243 $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
11244 $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
11245 $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
11246 }
11247
11248 /*-- END CJK-FONTS --*/
11249
11250 //////////////////////////////////////////////////////////////////////////////
11251 //////////////////////////////////////////////////////////////////////////////
11252 //////////////////////////////////////////////////////////////////////////////
11253 //////////////////////////////////////////////////////////////////////////////
11254 //////////////////////////////////////////////////////////////////////////////
11255 //////////////////////////////////////////////////////////////////////////////
11256 //////////////////////////////////////////////////////////////////////////////
11257 function SetAutoFont($af = AUTOFONT_ALL) {
11258 if ($this->onlyCoreFonts) { return false; }
11259 if (!$af && $af !== 0) { $af = AUTOFONT_ALL; }
11260 $this->autoFontGroups = $af;
11261 if ($this->autoFontGroups ) {
11262 $this->useLang = true;
11263 }
11264 }
11265
11266
11267 function SetDefaultFont($font) {
11268 // Disallow embedded fonts to be used as defaults in PDFA
11269 if ($this->PDFA || $this->PDFX) {
11270 if (strtolower($font) == 'ctimes') { $font = 'serif'; }
11271 if (strtolower($font) == 'ccourier') { $font = 'monospace'; }
11272 if (strtolower($font) == 'chelvetica') { $font = 'sans-serif'; }
11273 }
11274 $font = $this->SetFont($font); // returns substituted font if necessary
11275 $this->default_font = $font;
11276 $this->original_default_font = $font;
11277 if (!$this->watermark_font ) { $this->watermark_font = $font; } // *WATERMARK*
11278 $this->defaultCSS['BODY']['FONT-FAMILY'] = $font;
11279 $this->cssmgr->CSS['BODY']['FONT-FAMILY'] = $font;
11280 }
11281
11282 function SetDefaultFontSize($fontsize) {
11283 $this->default_font_size = $fontsize;
11284 $this->original_default_font_size = $fontsize;
11285 $this->SetFontSize($fontsize);
11286 $this->defaultCSS['BODY']['FONT-SIZE'] = $fontsize . 'pt';
11287 $this->cssmgr->CSS['BODY']['FONT-SIZE'] = $fontsize . 'pt';
11288 }
11289
11290 function SetDefaultBodyCSS($prop, $val) {
11291 if ($prop) {
11292 $this->defaultCSS['BODY'][strtoupper($prop)] = $val;
11293 $this->cssmgr->CSS['BODY'][strtoupper($prop)] = $val;
11294 }
11295 }
11296
11297
11298 function SetDirectionality($dir='ltr') {
11299 /*-- RTL --*/
11300 if (strtolower($dir) == 'rtl') {
11301 if ($this->directionality != 'rtl') {
11302 // Swop L/R Margins so page 1 RTL is an 'even' page
11303 $tmp = $this->DeflMargin;
11304 $this->DeflMargin = $this->DefrMargin;
11305 $this->DefrMargin = $tmp;
11306 $this->orig_lMargin = $this->DeflMargin;
11307 $this->orig_rMargin = $this->DefrMargin;
11308
11309 $this->SetMargins($this->DeflMargin,$this->DefrMargin,$this->tMargin);
11310 }
11311 $this->directionality = 'rtl';
11312 $this->defaultAlign = 'R';
11313 $this->defaultTableAlign = 'R';
11314 }
11315 else {
11316 /*-- END RTL --*/
11317 $this->directionality = 'ltr';
11318 $this->defaultAlign = 'L';
11319 $this->defaultTableAlign = 'L';
11320 } // *RTL*
11321 $this->cssmgr->CSS['BODY']['DIRECTION'] = $this->directionality;
11322 }
11323
11324
11325
11326 // Added to set line-height-correction
11327 function SetLineHeightCorrection($val) {
11328 if ($val > 0) { $this->default_lineheight_correction = $val; }
11329 else { $this->default_lineheight_correction = 1.2; }
11330 }
11331
11332 // Set a (fixed) lineheight to an actual value - either to named fontsize(pts) or default
11333 function SetLineHeight($FontPt='',$spacing = '') {
11334 if ($this->shrin_k > 1) { $k = $this->shrin_k; }
11335 else { $k = 1; }
11336 if ($spacing > 0) {
11337 if (preg_match('/mm/',$spacing)) {
11338 $this->lineheight = ($spacing + 0.0) / $k; // convert to number
11339 }
11340 else {
11341 if ($FontPt) { $this->lineheight = (($FontPt/_MPDFK) *$spacing); }
11342 else { $this->lineheight = (($this->FontSizePt/_MPDFK) *$spacing); }
11343 }
11344 }
11345 else {
11346 if ($FontPt) { $this->lineheight = (($FontPt/_MPDFK) *$this->normalLineheight); }
11347 else { $this->lineheight = (($this->FontSizePt/_MPDFK) *$this->normalLineheight); }
11348 }
11349 }
11350
11351 function _computeLineheight($lh, $fs='') {
11352 if ($this->shrin_k > 1) { $k = $this->shrin_k; }
11353 else { $k = 1; }
11354 if (!$fs) { $fs = $this->FontSize; }
11355 if (preg_match('/mm/',$lh)) {
11356 return (($lh + 0.0) / $k); // convert to number
11357 }
11358 else if ($lh > 0) {
11359 return ($fs * $lh);
11360 }
11361 else if (isset($this->normalLineheight)) { return ($fs * $this->normalLineheight); }
11362 else return ($fs * $this->default_lineheight_correction);
11363 }
11364
11365
11366 function SetBasePath($str='') {
11367 if ( isset($_SERVER['HTTP_HOST']) ) { $host = $_SERVER['HTTP_HOST']; }
11368 else if ( isset($_SERVER['SERVER_NAME']) ) { $host = $_SERVER['SERVER_NAME']; }
11369 else { $host = ''; }
11370 if (!$str) {
11371 if ($_SERVER['SCRIPT_NAME']) { $currentPath = dirname($_SERVER['SCRIPT_NAME']); }
11372 else { $currentPath = dirname($_SERVER['PHP_SELF']); }
11373 $currentPath = str_replace("\\","/",$currentPath);
11374 if ($currentPath == '/') { $currentPath = ''; }
11375 if ($host) { $currpath = 'http://' . $host . $currentPath .'/'; }
11376 else { $currpath = ''; }
11377 $this->basepath = $currpath;
11378 $this->basepathIsLocal = true;
11379 return;
11380 }
11381 $str = preg_replace('/\?.*/','',$str);
11382 if (!preg_match('/(http|https|ftp):\/\/.*\//i',$str)) { $str .= '/'; }
11383 $str .= 'xxx'; // in case $str ends in / e.g. http://www.bbc.co.uk/
11384 $this->basepath = dirname($str) . "/"; // returns e.g. e.g. http://www.google.com/dir1/dir2/dir3/
11385 $this->basepath = str_replace("\\","/",$this->basepath); //If on Windows
11386 $tr = parse_url($this->basepath);
11387 if (isset($tr['host']) && ($tr['host'] == $host)) { $this->basepathIsLocal = true; }
11388 else { $this->basepathIsLocal = false; }
11389 }
11390
11391
11392 function GetFullPath(&$path,$basepath='') {
11393 // When parsing CSS need to pass temporary basepath - so links are relative to current stylesheet
11394 if (!$basepath) { $basepath = $this->basepath; }
11395 //Fix path value
11396 $path = str_replace("\\","/",$path); //If on Windows
11397 // mPDF 5.7.2
11398 if (substr($path,0,2) == "//") {
11399 $tr = parse_url($basepath);
11400 $path = $tr['scheme'].':'.$path;
11401 }
11402 $regexp = '|^./|'; // Inadvertently corrects "./path/etc" and "//www.domain.com/etc"
11403 $path = preg_replace($regexp,'',$path);
11404
11405
11406 if(substr($path,0,1) == '#') { return; }
11407 // mPDF 5.7.4
11408 if (substr($path,0,7) == "mailto:") { return; }
11409 if (substr($path,0,3) == "../") { //It is a Relative Link
11410 $backtrackamount = substr_count($path,"../");
11411 $maxbacktrack = substr_count($basepath,"/") - 3; // mPDF 5.6.18
11412 $filepath = str_replace("../",'',$path);
11413 $path = $basepath;
11414 //If it is an invalid relative link, then make it go to directory root
11415 if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
11416 //Backtrack some directories
11417 for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") );
11418 $path = $path . "/" . $filepath; //Make it an absolute path
11419 }
11420 else if( strpos($path,":/") === false || strpos($path,":/") > 10) { //It is a Local Link
11421 if (substr($path,0,1) == "/") {
11422 $tr = parse_url($basepath);
11423 // mPDF 5.7.2
11424 $root = '';
11425 if (!empty($tr['scheme'])) { $root .= $tr['scheme'].'://'; }
11426 $root .= $tr['host'];
11427 $root .= ($tr['port'] ? (':'.$tr['port']) : ''); // mPDF 5.7.3
11428 $path = $root . $path;
11429 }
11430 else { $path = $basepath . $path; }
11431 }
11432 //Do nothing if it is an Absolute Link
11433 }
11434
11435
11436 // Used for external CSS files
11437 function _get_file($path) {
11438 // If local file try using local path (? quicker, but also allowed even if allow_url_fopen false)
11439 $contents = '';
11440 // mPDF 5.7.3
11441 if (strpos($path,"//") === false ) { $path = preg_replace('/\.css\?.*$/', '.css', $path); }
11442 $contents = @file_get_contents($path);
11443 if ($contents) { return $contents; }
11444 if ($this->basepathIsLocal) {
11445 $tr = parse_url($path);
11446 $lp=getenv("SCRIPT_NAME");
11447 $ap=realpath($lp);
11448 $ap=str_replace("\\","/",$ap);
11449 $docroot=substr($ap,0,strpos($ap,$lp));
11450 // WriteHTML parses all paths to full URLs; may be local file name
11451 if ($tr['scheme'] && $tr['host'] && $_SERVER["DOCUMENT_ROOT"] ) {
11452 $localpath = $_SERVER["DOCUMENT_ROOT"] . $tr['path'];
11453 }
11454 // DOCUMENT_ROOT is not returned on IIS
11455 else if ($docroot) {
11456 $localpath = $docroot . $tr['path'];
11457 }
11458 else { $localpath = $path; }
11459 $contents = @file_get_contents($localpath);
11460 }
11461 // if not use full URL
11462 else if (!$contents && !ini_get('allow_url_fopen') && function_exists("curl_init")) {
11463 $ch = curl_init($path);
11464 curl_setopt($ch, CURLOPT_HEADER, 0);
11465 curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , 1 );
11466 $contents = curl_exec($ch);
11467 curl_close($ch);
11468 }
11469 return $contents;
11470 }
11471
11472
11473 function docPageNum($num = 0, $extras = false) {
11474 if ($num < 1) { $num = $this->page; }
11475 $type = '1'; // set default decimal
11476 $ppgno = $num;
11477 $suppress = 0;
11478 $offset = 0;
11479 $lastreset = 0;
11480 foreach($this->PageNumSubstitutions AS $psarr) {
11481 if ($num >= $psarr['from']) {
11482 if ($psarr['reset']) {
11483 if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
11484 $ppgno = $num - $psarr['from'] + 1 + $offset;
11485 $lastreset = $psarr['from'];
11486 }
11487 if ($psarr['type']) { $type = $psarr['type']; }
11488 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
11489 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
11490 }
11491 }
11492 if ($suppress) { return ''; }
11493
11494 foreach($this->pgsIns AS $k=>$v) {
11495 if ($k>$lastreset && $k<$num) {
11496 $ppgno -= $v;
11497 }
11498 }
11499 if ($type=='A') { $ppgno = $this->dec2alpha($ppgno,true); }
11500 else if ($type=='a') { $ppgno = $this->dec2alpha($ppgno,false);}
11501 else if ($type=='I') { $ppgno = $this->dec2roman($ppgno,true); }
11502 else if ($type=='i') { $ppgno = $this->dec2roman($ppgno,false); }
11503 if ($extras) { $ppgno = $this->pagenumPrefix . $ppgno . $this->pagenumSuffix; }
11504 return $ppgno;
11505 }
11506
11507
11508 function docPageSettings($num = 0) {
11509 // Returns current type (numberstyle), suppression state for this page number;
11510 // reset is only returned if set for this page number
11511 if ($num < 1) { $num = $this->page; }
11512 $type = '1'; // set default decimal
11513 $ppgno = $num;
11514 $suppress = 0;
11515 $offset = 0;
11516 $reset = '';
11517 foreach($this->PageNumSubstitutions AS $psarr) {
11518 if ($num >= $psarr['from']) {
11519 if ($psarr['reset']) {
11520 if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
11521 $ppgno = $num - $psarr['from'] + 1 + $offset;
11522 }
11523 if ($psarr['type']) { $type = $psarr['type']; }
11524 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
11525 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
11526 }
11527 if ($num == $psarr['from']) { $reset = $psarr['reset']; }
11528 }
11529 if ($suppress) { $suppress = 'on'; }
11530 else { $suppress = 'off'; }
11531 return array($type, $suppress, $reset);
11532 }
11533
11534 function docPageNumTotal($num = 0, $extras = false) {
11535 if ($num < 1) { $num = $this->page; }
11536 $type = '1'; // set default decimal
11537 $ppgstart = 1;
11538 $ppgend = count($this->pages)+1;
11539 $suppress = 0;
11540 $offset = 0;
11541 foreach($this->PageNumSubstitutions AS $psarr) {
11542 if ($num >= $psarr['from']) {
11543 if ($psarr['reset']) {
11544 if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
11545 $ppgstart = $psarr['from'] + $offset;
11546 $ppgend = count($this->pages)+1 + $offset;
11547 }
11548 if ($psarr['type']) { $type = $psarr['type']; }
11549 if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
11550 else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
11551 }
11552 if ($num < $psarr['from']) {
11553 if ($psarr['reset']) {
11554 $ppgend = $psarr['from'] + $offset;
11555 break;
11556 }
11557 }
11558 }
11559 if ($suppress) { return ''; }
11560 $ppgno = $ppgend-$ppgstart+$offset;
11561
11562 // mPDF 5.6.47
11563 foreach($this->pgsIns AS $k => $v) {
11564 if ($k>$ppgstart && $k<$ppgend) {
11565 $ppgno -= $v;
11566 }
11567 }
11568
11569 if ($extras) { $ppgno = $this->nbpgPrefix . $ppgno . $this->nbpgSuffix; }
11570 return $ppgno;
11571 }
11572
11573 function RestartDocTemplate() {
11574 $this->docTemplateStart = $this->page;
11575 }
11576
11577
11578
11579 //Page header
11580 function Header($content='') {
11581
11582 $this->cMarginL = 0;
11583 $this->cMarginR = 0;
11584
11585
11586 /*-- HTMLHEADERS-FOOTERS --*/
11587 if (($this->mirrorMargins && ($this->page%2==0) && $this->HTMLHeaderE) || ($this->mirrorMargins && ($this->page%2==1) && $this->HTMLHeader) || (!$this->mirrorMargins && $this->HTMLHeader)) {
11588 $this->writeHTMLHeaders();
11589 return;
11590 }
11591 /*-- END HTMLHEADERS-FOOTERS --*/
11592 $this->processingHeader=true;
11593 $h = $this->headerDetails;
11594 if(count($h)) {
11595
11596 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
11597 $this->_out(sprintf('q 0 -1 1 0 0 %.3F cm ',($this->h*_MPDFK)));
11598 $yadj = $this->w - $this->h;
11599 $headerpgwidth = $this->h - $this->orig_lMargin - $this->orig_rMargin;
11600 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
11601 $headerlmargin = $this->orig_rMargin;
11602 }
11603 else {
11604 $headerlmargin = $this->orig_lMargin;
11605 }
11606 }
11607 else {
11608 $yadj = 0;
11609 $headerpgwidth = $this->pgwidth;
11610 $headerlmargin = $this->lMargin;
11611 }
11612
11613 $this->y = $this->margin_header - $yadj ;
11614 $this->SetTColor($this->ConvertColor(0));
11615 $this->SUP = false;
11616 $this->SUB = false;
11617 $this->bullet = false;
11618
11619 // only show pagenumber if numbering on
11620 $pgno = $this->docPageNum($this->page, true);
11621
11622 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
11623 $side = 'even';
11624 }
11625 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS = DEFAULT
11626 $side = 'odd';
11627 }
11628 $maxfontheight = 0;
11629 foreach(array('L','C','R') AS $pos) {
11630 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
11631 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
11632 else { $hfsz = $this->default_font_size; }
11633 $maxfontheight = max($maxfontheight,$hfsz);
11634 }
11635 }
11636 // LEFT-CENTER-RIGHT
11637 foreach(array('L','C','R') AS $pos) {
11638 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
11639 $hd = str_replace('{PAGENO}',$pgno,$h[$side][$pos]['content']);
11640 $hd = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->aliasNbPgGp.$this->nbpgSuffix,$hd);
11641 $hd = preg_replace_callback('/\{DATE\s+(.*?)\}/', array($this, 'date_callback') ,$hd); // mPDF 5.7
11642 if (isset($h[$side][$pos]['font-family']) && $h[$side][$pos]['font-family']) { $hff = $h[$side][$pos]['font-family']; }
11643 else { $hff = $this->original_default_font; }
11644 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
11645 else { $hfsz = $this->original_default_font_size; } // pts
11646 $maxfontheight = max($maxfontheight,$hfsz);
11647 $hfst = '';
11648 if (isset($h[$side][$pos]['font-style']) && $h[$side][$pos]['font-style']) {
11649 $hfst = $h[$side][$pos]['font-style'];
11650 }
11651 if (isset($h[$side][$pos]['color']) && $h[$side][$pos]['color']) {
11652 $hfcol = $h[$side][$pos]['color'];
11653 $cor = $this->ConvertColor($hfcol);
11654 if ($cor) { $this->SetTColor($cor); }
11655 }
11656 else { $hfcol = ''; }
11657 $this->SetFont($hff,$hfst,$hfsz,true,true);
11658 $this->x = $headerlmargin ;
11659 $this->y = $this->margin_header - $yadj ;
11660
11661 $hd = $this->purify_utf8_text($hd);
11662 if ($this->text_input_as_HTML) {
11663 $hd = $this->all_entities_to_utf8($hd);
11664 }
11665 // CONVERT CODEPAGE
11666 if ($this->usingCoreFont) { $hd = mb_convert_encoding($hd,$this->mb_enc,'UTF-8'); }
11667 // DIRECTIONALITY RTL
11668 $this->magic_reverse_dir($hd, true, $this->directionality); // *RTL*
11669 // Font-specific ligature substitution for Indic fonts
11670 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($hd); // *INDIC*
11671 $align = $pos;
11672 /*-- RTL --*/
11673 if ($this->directionality == 'rtl') {
11674 if ($pos == 'L') { $align = 'R'; }
11675 else if ($pos == 'R') { $align = 'L'; }
11676 }
11677 /*-- END RTL --*/
11678 if ($pos!='L' && (strpos($hd,$this->aliasNbPg)!==false || strpos($hd,$this->aliasNbPgGp)!==false)) {
11679 if (strpos($hd,$this->aliasNbPgGp)!==false) { $type= 'nbpggp'; } else { $type= 'nbpg'; }
11680 $this->_out('{mpdfheader'.$type.' '.$pos.' ff='.$hff.' fs='.$hfst.' fz='.$hfsz.'}');
11681 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
11682 $this->_out('Q');
11683 }
11684 else {
11685 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
11686 }
11687 if ($hfcol) { $this->SetTColor($this->ConvertColor(0)); }
11688 }
11689 }
11690 //Return Font to normal
11691 $this->SetFont($this->default_font,'',$this->original_default_font_size);
11692 // LINE
11693 if (isset($h[$side]['line']) && $h[$side]['line']) {
11694 $this->SetLineWidth(0.1);
11695 $this->SetDColor($this->ConvertColor(0));
11696 $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 );
11697 }
11698 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
11699 $this->_out('Q');
11700 }
11701 }
11702 $this->SetY($this->tMargin);
11703 if ($this->ColActive) { $this->pgwidth = $this->ColWidth; } // *COLUMNS*
11704
11705 $this->processingHeader=false;
11706 }
11707
11708
11709
11710 /*-- TABLES --*/
11711 function TableHeaderFooter($content='',$tablestartpage='',$tablestartcolumn ='',$horf = 'H',$level, $firstSpread=true, $finalSpread=true) {
11712 if(($horf=='H' || $horf=='F') && !empty($content)) { // mPDF 5.7.2
11713 $table = &$this->table[1][1];
11714
11715 // mPDF 5.7.2
11716 if ($horf=='F') { // Table Footer
11717 $firstrow = count($table['cells']) - $table['footernrows'];
11718 $lastrow = count($table['cells']) - 1;
11719 }
11720 else { // Table Header
11721 $firstrow = 0;
11722 $lastrow = $table['headernrows'] - 1;
11723 }
11724 if(empty($content[$firstrow])) {
11725 if ($this->debug) { $this->Error("&lt;tfoot&gt; must precede &lt;tbody&gt; in a table"); }
11726 else { return; }
11727 }
11728
11729 // Advance down page by half width of top border
11730 if ($horf=='H') { // Only if header
11731 if ($table['borders_separate']) { $adv = $table['border_spacing_V']/2 + $table['border_details']['T']['w'] + $table['padding']['T']; }
11732 else { $adv = $table['max_cell_border_width']['T'] /2 ; }
11733 if ($adv) {
11734 if ($this->table_rotate) {
11735 $this->y += ($adv);
11736 }
11737 else {
11738 $this->DivLn($adv,$this->blklvl,true);
11739 }
11740 }
11741 }
11742
11743
11744 $topy = $content[$firstrow][0]['y']-$this->y;
11745
11746 for ($i=$firstrow ; $i<=$lastrow; $i++) {
11747
11748 $y = $this->y;
11749
11750 /*-- COLUMNS --*/
11751 // If outside columns, this is done in PaintDivBB
11752 if ($this->ColActive) {
11753 //OUTER FILL BGCOLOR of DIVS
11754 if ($this->blklvl > 0) {
11755 $firstblockfill = $this->GetFirstBlockFill();
11756 if ($firstblockfill && $this->blklvl >= $firstblockfill) {
11757 $divh = $content[$i][0]['h'];
11758 $bak_x = $this->x;
11759 $this->DivLn($divh,-3,false);
11760 // Reset current block fill
11761 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
11762 $this->SetFColor($bcor);
11763 $this->x = $bak_x;
11764 }
11765 }
11766 }
11767 /*-- END COLUMNS --*/
11768
11769 $colctr = 0;
11770 foreach($content[$i] as $tablehf) {
11771 $colctr++;
11772 $y = $tablehf['y'] - $topy;
11773 $this->y = $y;
11774 //Set some cell values
11775 $x = $tablehf['x'];
11776 if (($this->mirrorMargins) && ($tablestartpage == 'ODD') && (($this->page)%2==0)) { // EVEN
11777 $x = $x +$this->MarginCorrection;
11778 }
11779 else if (($this->mirrorMargins) && ($tablestartpage == 'EVEN') && (($this->page)%2==1)) { // ODD
11780 $x = $x +$this->MarginCorrection;
11781 }
11782 /*-- COLUMNS --*/
11783 // Added to correct for Columns
11784 if ($this->ColActive) {
11785 if ($this->directionality == 'rtl') { // *RTL*
11786 $x -= ($this->CurrCol - $tablestartcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
11787 } // *RTL*
11788 else { // *RTL*
11789 $x += ($this->CurrCol - $tablestartcolumn) * ($this->ColWidth+$this->ColGap);
11790 } // *RTL*
11791 }
11792 /*-- END COLUMNS --*/
11793
11794 if ($colctr==1) { $x0 = $x; }
11795
11796 // mPDF ITERATION
11797 if ($this->iterationCounter) {
11798 foreach($tablehf['textbuffer'] AS $k=>$t) {
11799 if (!is_array($t[0]) && preg_match('/{iteration ([a-zA-Z0-9_]+)}/',$t[0], $m)) { // mPDF 5.5.06
11800 $vname = '__'.$m[1].'_';
11801 if (!isset($this->$vname)) { $this->$vname = 1; }
11802 else { $this->$vname++; }
11803 $tablehf['textbuffer'][$k][0] = preg_replace('/{iteration '.$m[1].'}/', $this->$vname, $tablehf['textbuffer'][$k][0]);
11804 }
11805 }
11806 }
11807
11808
11809 $w = $tablehf['w'];
11810 $h = $tablehf['h'];
11811 $va = $tablehf['va'];
11812 $R = $tablehf['R'];
11813 $mih = $tablehf['mih'];
11814 $border = $tablehf['border'];
11815 $border_details = $tablehf['border_details'];
11816 $padding = $tablehf['padding'];
11817 $this->tabletheadjustfinished = true;
11818
11819 $textbuffer = $tablehf['textbuffer'];
11820
11821 $align = $tablehf['a'];
11822 //Align
11823 $this->divalign=$align;
11824 $this->x = $x;
11825
11826 if ($this->ColActive) {
11827 if ($table['borders_separate']) {
11828 $tablefill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
11829 if ($tablefill) {
11830 $color = $this->ConvertColor($tablefill);
11831 if ($color) {
11832 $xadj = ($table['border_spacing_H']/2);
11833 $yadj = ($table['border_spacing_V']/2);
11834 $wadj = $table['border_spacing_H'];
11835 $hadj = $table['border_spacing_V'];
11836 if ($i == $firstrow && $horf=='H') { // Top
11837 $yadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
11838 $hadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
11839 }
11840 if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i+$tablehf['rowspan']) == ($lastrow+1)) || (!isset($tablehf['rowspan']) && ($i+1) == ($lastrow+1))) && $horf=='F') { // Bottom
11841 $hadj += $table['padding']['B'] + $table['border_details']['B']['w'] ;
11842 }
11843 if ($colctr == 1) { // Left
11844 $xadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
11845 $wadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
11846 }
11847 if ($colctr == count($content[$i]) ) { // Right
11848 $wadj += $table['padding']['R'] + $table['border_details']['R']['w'] ;
11849 }
11850 $this->SetFColor($color);
11851 $this->Rect($x - $xadj, $y - $yadj, $w + $wadj, $h + $hadj, 'F');
11852 }
11853 }
11854 }
11855 }
11856
11857 if ($table['empty_cells']!='hide' || !empty($textbuffer) || !$table['borders_separate']) { $paintcell = true; }
11858 else { $paintcell = false; }
11859
11860 //Vertical align
11861 if ($R && INTVAL($R) > 0 && isset($va) && $va!='B') { $va='B';}
11862
11863 if (!isset($va) || empty($va) || $va=='M') $this->y += ($h-$mih)/2;
11864 elseif (isset($va) && $va=='B') $this->y += $h-$mih;
11865
11866
11867 //TABLE ROW OR CELL FILL BGCOLOR
11868 $fill = 0;
11869 if (isset($tablehf['bgcolor']) && $tablehf['bgcolor'] && $tablehf['bgcolor']!='transparent') {
11870 $fill = $tablehf['bgcolor'];
11871 $leveladj = 6;
11872 }
11873 else if (isset($content[$i][0]['trbgcolor']) && $content[$i][0]['trbgcolor'] && $content[$i][0]['trbgcolor']!='transparent') { // Row color
11874 $fill = $content[$i][0]['trbgcolor'];
11875 $leveladj = 3;
11876 }
11877 if ($fill && $paintcell) {
11878 $color = $this->ConvertColor($fill);
11879 if ($color) {
11880 if ($table['borders_separate']) {
11881 if ($this->ColActive) {
11882 $this->SetFColor($color);
11883 $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');
11884 }
11885 else {
11886 $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);
11887 }
11888 }
11889 else {
11890 if ($this->ColActive) {
11891 $this->SetFColor($color);
11892 $this->Rect($x, $y, $w, $h, 'F');
11893 }
11894 else {
11895 $this->tableBackgrounds[$level*9+$leveladj][] = array('gradient'=>false, 'x'=>$x, 'y'=>$y, 'w'=>$w, 'h'=>$h, 'col'=>$color);
11896 }
11897 }
11898 }
11899 }
11900
11901
11902 /*-- BACKGROUNDS --*/
11903 if (isset($tablehf['gradient']) && $tablehf['gradient'] && $paintcell){
11904 $g = $this->grad->parseBackgroundGradient($tablehf['gradient']);
11905 if ($g) {
11906 if ($table['borders_separate']) {
11907 $px = $x+ ($table['border_spacing_H']/2);
11908 $py = $y+ ($table['border_spacing_V']/2);
11909 $pw = $w- $table['border_spacing_H'];
11910 $ph = $h- $table['border_spacing_V'];
11911 }
11912 else {
11913 $px = $x;
11914 $py = $y;
11915 $pw = $w;
11916 $ph = $h;
11917 }
11918 if ($this->ColActive) {
11919 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
11920 }
11921 else {
11922 $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'=>'');
11923 }
11924 }
11925 }
11926
11927 if (isset($tablehf['background-image']) && $paintcell){
11928 if ($tablehf['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $tablehf['background-image']['gradient'] )) {
11929 $g = $this->grad->parseMozGradient( $tablehf['background-image']['gradient'] );
11930 if ($g) {
11931 if ($table['borders_separate']) {
11932 $px = $x+ ($table['border_spacing_H']/2);
11933 $py = $y+ ($table['border_spacing_V']/2);
11934 $pw = $w- $table['border_spacing_H'];
11935 $ph = $h- $table['border_spacing_V'];
11936 }
11937 else {
11938 $px = $x;
11939 $py = $y;
11940 $pw = $w;
11941 $ph = $h;
11942 }
11943 if ($this->ColActive) {
11944 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
11945 }
11946 else {
11947 $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'=>'');
11948 }
11949 }
11950 }
11951 else if ($tablehf['background-image']['image_id']) { // Background pattern
11952 $n = count($this->patterns)+1;
11953 if ($table['borders_separate']) {
11954 $px = $x+ ($table['border_spacing_H']/2);
11955 $py = $y+ ($table['border_spacing_V']/2);
11956 $pw = $w- $table['border_spacing_H'];
11957 $ph = $h- $table['border_spacing_V'];
11958 }
11959 else {
11960 $px = $x;
11961 $py = $y;
11962 $pw = $w;
11963 $ph = $h;
11964 }
11965 if ($this->ColActive) {
11966 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']);
11967 $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']);
11968 if ($tablehf['background-image']['opacity']>0 && $tablehf['background-image']['opacity']<1) { $opac = $this->SetAlpha($tablehf['background-image']['opacity'],'Normal',true); }
11969 else { $opac = ''; }
11970 $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));
11971 }
11972 else {
11973 $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']);
11974 }
11975 }
11976 }
11977 /*-- END BACKGROUNDS --*/
11978
11979 //Cell Border
11980 if ($table['borders_separate'] && $paintcell && $border) {
11981 $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']);
11982 }
11983 else if ($paintcell && $border) {
11984 $this->_tableRect($x, $y, $w, $h, $border, $border_details, true, $table['borders_separate']); // true causes buffer
11985 }
11986
11987 //Print cell content
11988 //$this->divheight = $this->table_lineheight*$this->lineheight;
11989 if (!empty($textbuffer)) {
11990 if ($horf=='F' && preg_match('/{colsum([0-9]*)[_]*}/', $textbuffer[0][0], $m)) {
11991 $rep = sprintf("%01.".intval($m[1])."f", $this->colsums[$colctr-1]);
11992 $textbuffer[0][0] = preg_replace('/{colsum[0-9_]*}/', $rep ,$textbuffer[0][0]);
11993 }
11994
11995 if ($R) {
11996 $cellPtSize = $textbuffer[0][11] / $this->shrin_k;
11997 if (!$cellPtSize) { $cellPtSize = $this->default_font_size; }
11998 $cellFontHeight = ($cellPtSize/_MPDFK);
11999 $opx = $this->x;
12000 $opy = $this->y;
12001 $angle = INTVAL($R);
12002 // Only allow 45 - 90 degrees (when bottom-aligned) or -90
12003 if ($angle > 90) { $angle = 90; }
12004 else if ($angle > 0 && (isset($va) && $va!='B')) { $angle = 90; }
12005 else if ($angle > 0 && $angle <45) { $angle = 45; }
12006 else if ($angle < 0) { $angle = -90; }
12007 $offset = ((sin(deg2rad($angle))) * 0.37 * $cellFontHeight);
12008 if (isset($align) && $align =='R') {
12009 $this->x += ($w) + ($offset) - ($cellFontHeight/3) - ($padding['R'] + $border_details['R']['w']);
12010 }
12011 else if (!isset($align ) || $align =='C') {
12012 $this->x += ($w/2) + ($offset);
12013 }
12014 else {
12015 $this->x += ($offset) + ($cellFontHeight/3)+($padding['L'] + $border_details['L']['w']);
12016 }
12017 $str = '';
12018 foreach($tablehf['textbuffer'] AS $t) { $str .= $t[0].' '; }
12019 $str = trim($str);
12020
12021 if (!isset($va) || $va=='M') {
12022 $this->y -= ($h-$mih)/2; //Undo what was added earlier VERTICAL ALIGN
12023 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'])); }
12024 else if ($angle < 0) { $this->y += (($h-$mih)/2)+($padding['T'] + $border_details['T']['w']); }
12025 }
12026 else if (isset($va) && $va=='B') {
12027 $this->y -= $h-$mih; //Undo what was added earlier VERTICAL ALIGN
12028 if ($angle > 0) { $this->y += $h-($border_details['B']['w']+$padding['B']); }
12029 else if ($angle < 0) { $this->y += $h-$mih+($padding['T'] + $border_details['T']['w']); }
12030 }
12031 else if (isset($va) && $va=='T') {
12032 if ($angle > 0) { $this->y += $mih-($border_details['B']['w']+$padding['B']); }
12033 else if ($angle < 0) { $this->y += ($padding['T'] + $border_details['T']['w']); }
12034 }
12035
12036 $this->Rotate($angle,$this->x,$this->y);
12037 $s_fs = $this->FontSizePt;
12038 $s_f = $this->FontFamily;
12039 $s_st = $this->FontStyle;
12040 if (!empty($textbuffer[0][3])) { //Font Color
12041 $cor = $textbuffer[0][3];
12042 $this->SetTColor($cor);
12043 }
12044 $s_str = $this->strike;
12045 $this->strike = $textbuffer[0][8]; //Strikethrough
12046 $this->SetFont($textbuffer[0][4],$textbuffer[0][2],$cellPtSize,true,true);
12047 $this->Text($this->x,$this->y,$str);
12048 $this->Rotate(0);
12049 $this->SetFont($s_f,$s_st,$s_fs,true,true);
12050 $this->SetTColor(0);
12051 $this->strike = $s_str;
12052 $this->x = $opx;
12053 $this->y = $opy;
12054 }
12055 else {
12056 if ($table['borders_separate']) { // NB twice border width
12057 $xadj = $border_details['L']['w'] + $padding['L'] +($table['border_spacing_H']/2);
12058 $wadj = $border_details['L']['w'] + $border_details['R']['w'] + $padding['L'] +$padding['R'] + $table['border_spacing_H'];
12059 $yadj = $border_details['T']['w'] + $padding['T'] + ($table['border_spacing_H']/2);
12060 }
12061 else {
12062 $xadj = $border_details['L']['w']/2 + $padding['L'];
12063 $wadj = ($border_details['L']['w'] + $border_details['R']['w'])/2 + $padding['L'] + $padding['R'];
12064 $yadj = $border_details['T']['w']/2 + $padding['T'];
12065 }
12066
12067 $this->divwidth=$w-($wadj);
12068 $this->x += $xadj;
12069 $this->y += $yadj;
12070 $this->printbuffer($textbuffer,'',true);
12071 }
12072
12073 }
12074 $textbuffer = array();
12075
12076 /*-- BACKGROUNDS --*/
12077 if (!$this->ColActive) {
12078 if (isset($content[$i][0]['trgradients']) && ($colctr==1 || $table['borders_separate'])) {
12079 $g = $this->grad->parseBackgroundGradient($content[$i][0]['trgradients']);
12080 if ($g) {
12081 $gx = $x0;
12082 $gy = $y;
12083 $gh = $h;
12084 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
12085 if ($table['borders_separate']) {
12086 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
12087 $s = '';
12088 $clx = $x+ ($table['border_spacing_H']/2);
12089 $cly = $y+ ($table['border_spacing_V']/2);
12090 $clw = $w- $table['border_spacing_H'];
12091 $clh = $h- $table['border_spacing_V'];
12092 // Set clipping path
12093 $s = ' q 0 w '; // Line width=0
12094 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
12095 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
12096 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
12097 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
12098 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
12099 $s .= ' W n '; // Ends path no-op & Sets the clipping path
12100 $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);
12101 }
12102 else {
12103 $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'=>'');
12104 }
12105 }
12106 }
12107
12108 if (isset($content[$i][0]['trbackground-images']) && ($colctr==1 || $table['borders_separate'])) {
12109 if ($content[$i][0]['trbackground-images']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $content[$i][0]['trbackground-images']['gradient'] )) {
12110 $g = $this->grad->parseMozGradient( $content[$i][0]['trbackground-images']['gradient'] );
12111 if ($g) {
12112 $gx = $x0;
12113 $gy = $y;
12114 $gh = $h;
12115 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
12116 if ($table['borders_separate']) {
12117 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
12118 $s = '';
12119 $clx = $x+ ($table['border_spacing_H']/2);
12120 $cly = $y+ ($table['border_spacing_V']/2);
12121 $clw = $w- $table['border_spacing_H'];
12122 $clh = $h- $table['border_spacing_V'];
12123 // Set clipping path
12124 $s = ' q 0 w '; // Line width=0
12125 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
12126 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
12127 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
12128 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
12129 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
12130 $s .= ' W n '; // Ends path no-op & Sets the clipping path
12131 $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);
12132 }
12133 else {
12134 $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'=>'');
12135 }
12136 }
12137 }
12138 else {
12139 $image_id = $content[$i][0]['trbackground-images']['image_id'];
12140 $orig_w = $content[$i][0]['trbackground-images']['orig_w'];
12141 $orig_h = $content[$i][0]['trbackground-images']['orig_h'];
12142 $x_pos = $content[$i][0]['trbackground-images']['x_pos'];
12143 $y_pos = $content[$i][0]['trbackground-images']['y_pos'];
12144 $x_repeat = $content[$i][0]['trbackground-images']['x_repeat'];
12145 $y_repeat = $content[$i][0]['trbackground-images']['y_repeat'];
12146 $resize = $content[$i][0]['trbackground-images']['resize'];
12147 $opacity = $content[$i][0]['trbackground-images']['opacity'];
12148 $itype = $content[$i][0]['trbackground-images']['itype'];
12149
12150 $clippath = '';
12151 $gx = $x0;
12152 $gy = $y;
12153 $gh = $h;
12154 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
12155 if ($table['borders_separate']) {
12156 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
12157 $s = '';
12158 $clx = $x+ ($table['border_spacing_H']/2);
12159 $cly = $y+ ($table['border_spacing_V']/2);
12160 $clw = $w- $table['border_spacing_H'];
12161 $clh = $h- $table['border_spacing_V'];
12162 // Set clipping path
12163 $s = ' q 0 w '; // Line width=0
12164 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
12165 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
12166 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
12167 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
12168 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
12169 $s .= ' W n '; // Ends path no-op & Sets the clipping path
12170 $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);
12171 }
12172 else {
12173 $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);
12174 }
12175 }
12176 }
12177 }
12178 /*-- END BACKGROUNDS --*/
12179
12180 // TABLE BORDER - if separate OR collapsed and only table border
12181 if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) {
12182 $halfspaceL = $table['padding']['L'] + ($table['border_spacing_H']/2);
12183 $halfspaceR = $table['padding']['R'] + ($table['border_spacing_H']/2);
12184 $halfspaceT = $table['padding']['T'] + ($table['border_spacing_V']/2);
12185 $halfspaceB = $table['padding']['B'] + ($table['border_spacing_V']/2);
12186 $tbx = $x;
12187 $tby = $y;
12188 $tbw = $w;
12189 $tbh = $h;
12190 $tab_bord = 0;
12191 $corner = '';
12192 if ($i == $firstrow && $horf=='H') { // Top
12193 $tby -= $halfspaceT + ($table['border_details']['T']['w']/2);
12194 $tbh += $halfspaceT + ($table['border_details']['T']['w']/2);
12195 $this->setBorder($tab_bord , _BORDER_TOP);
12196 $corner .= 'T';
12197 }
12198 if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i+$tablehf['rowspan']) == ($lastrow+1))) && $horf=='F') { // Bottom
12199 $tbh += $halfspaceB + ($table['border_details']['B']['w']/2);
12200 $this->setBorder($tab_bord , _BORDER_BOTTOM);
12201 $corner .= 'B';
12202 }
12203 if ($colctr == 1 && $firstSpread) { // Left
12204 $tbx -= $halfspaceL + ($table['border_details']['L']['w']/2);
12205 $tbw += $halfspaceL + ($table['border_details']['L']['w']/2);
12206 $this->setBorder($tab_bord , _BORDER_LEFT);
12207 $corner .= 'L';
12208 }
12209 if ($colctr == count($content[$i]) && $finalSpread) { // Right
12210 $tbw += $halfspaceR + ($table['border_details']['R']['w']/2);
12211 $this->setBorder($tab_bord , _BORDER_RIGHT);
12212 $corner .= 'R';
12213 }
12214 $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'] );
12215 }
12216
12217
12218 }// end column $content
12219 $this->y = $y + $h; //Update y coordinate
12220 }// end row $i
12221 unset($table );
12222 $this->colsums = array();
12223 }
12224 }
12225 /*-- END TABLES --*/
12226
12227 /*-- HTMLHEADERS-FOOTERS --*/
12228 function SetHTMLHeader($header='',$OE='',$write=false) {
12229
12230 $height = 0;
12231 if (is_array($header) && isset($header['html']) && $header['html']) {
12232 $Hhtml = $header['html'];
12233 if ($this->setAutoTopMargin) {
12234 if (isset($header['h'])) { $height = $header['h']; }
12235 else { $height = $this->_gethtmlheight($Hhtml); }
12236 }
12237 }
12238 else if (!is_array($header) && $header) {
12239 $Hhtml = $header;
12240 if ($this->setAutoTopMargin) { $height = $this->_gethtmlheight($Hhtml); }
12241 }
12242 else { $Hhtml = ''; }
12243
12244 if ($OE != 'E') { $OE = 'O'; }
12245 if ($OE == 'E') {
12246
12247 if ($Hhtml) {
12248 $this->HTMLHeaderE['html'] = $Hhtml;
12249 $this->HTMLHeaderE['h'] = $height;
12250 }
12251 else { $this->HTMLHeaderE = ''; }
12252 }
12253 else {
12254
12255 if ($Hhtml) {
12256 $this->HTMLHeader['html'] = $Hhtml;
12257 $this->HTMLHeader['h'] = $height;
12258 }
12259 else { $this->HTMLHeader = ''; }
12260 }
12261 if (!$this->mirrorMargins && $OE == 'E') { return; }
12262 if ($Hhtml=='') { return; }
12263 if ($OE == 'E') {
12264 $this->headerDetails['even'] = array(); // override and clear any other non-HTML header/footer
12265 }
12266 else {
12267 $this->headerDetails['odd'] = array(); // override and clear any non-HTML other header/footer
12268 }
12269
12270 if ($this->setAutoTopMargin=='pad') {
12271 $this->tMargin = $this->margin_header + $height + $this->orig_tMargin;
12272 if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) { $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin; }
12273 }
12274 else if ($this->setAutoTopMargin=='stretch') {
12275 $this->tMargin = max($this->orig_tMargin, $this->margin_header + $height + $this->autoMarginPadding);
12276 if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) { $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin; }
12277 }
12278 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(); }
12279 }
12280
12281 function SetHTMLFooter($footer='',$OE='') {
12282
12283 $height = 0;
12284 if (is_array($footer) && isset($footer['html']) && $footer['html']) {
12285 $Fhtml = $footer['html'];
12286 if ($this->setAutoBottomMargin) {
12287 if (isset($footer['h'])) { $height = $footer['h']; }
12288 else { $height = $this->_gethtmlheight($Fhtml); }
12289 }
12290 }
12291 else if (!is_array($footer) && $footer) {
12292 $Fhtml = $footer;
12293 if ($this->setAutoBottomMargin) { $height = $this->_gethtmlheight($Fhtml); }
12294 }
12295 else { $Fhtml = ''; }
12296
12297 if ($OE != 'E') { $OE = 'O'; }
12298 if ($OE == 'E') {
12299
12300 if ($Fhtml) {
12301 $this->HTMLFooterE['html'] = $Fhtml;
12302 $this->HTMLFooterE['h'] = $height;
12303 }
12304 else { $this->HTMLFooterE = ''; }
12305 }
12306 else {
12307
12308 if ($Fhtml) {
12309 $this->HTMLFooter['html'] = $Fhtml;
12310 $this->HTMLFooter['h'] = $height;
12311 }
12312 else { $this->HTMLFooter = ''; }
12313 }
12314 if (!$this->mirrorMargins && $OE == 'E') { return; }
12315 if ($Fhtml=='') { return false; }
12316 if ($OE == 'E') {
12317 $this->footerDetails['even'] = array(); // override and clear any other header/footer
12318 }
12319 else {
12320 $this->footerDetails['odd'] = array(); // override and clear any other header/footer
12321 }
12322
12323 if ($this->setAutoBottomMargin=='pad') {
12324 $this->bMargin = $this->margin_footer + $height + $this->orig_bMargin;
12325 $this->PageBreakTrigger=$this->h-$this->bMargin ;
12326 if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) { $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin; }
12327 }
12328 else if ($this->setAutoBottomMargin=='stretch') {
12329 $this->bMargin = max($this->orig_bMargin, $this->margin_footer + $height + $this->autoMarginPadding);
12330 $this->PageBreakTrigger=$this->h-$this->bMargin ;
12331 if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) { $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin; }
12332 }
12333 }
12334
12335
12336 function _getHtmlHeight($html) {
12337 $save_state = $this->state;
12338 if($this->state==0) {
12339 $this->AddPage($this->CurOrientation);
12340 }
12341 $this->state = 2;
12342 $this->Reset();
12343 $this->pageoutput[$this->page] = array();
12344 $save_x = $this->x;
12345 $save_y = $this->y;
12346 $this->x = $this->lMargin;
12347 $this->y = $this->margin_header;
12348 $html = str_replace('{PAGENO}',$this->pagenumPrefix.$this->docPageNum($this->page).$this->pagenumSuffix,$html);
12349 $html = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->docPageNumTotal($this->page).$this->nbpgSuffix,$html );
12350 $html = str_replace($this->aliasNbPg,$this->page,$html );
12351 $html = preg_replace_callback('/\{DATE\s+(.*?)\}/', array($this, 'date_callback') ,$html ); // mPDF 5.7
12352 $this->HTMLheaderPageLinks = array();
12353 $this->HTMLheaderPageAnnots = array();
12354 $this->HTMLheaderPageForms = array();
12355 $savepb = $this->pageBackgrounds;
12356 $this->writingHTMLheader = true;
12357 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
12358 $this->writingHTMLheader = false;
12359 $h = ($this->y - $this->margin_header);
12360 $this->Reset();
12361 // mPDF 5.7.2 - Clear in case Float used in Header/Footer
12362 $this->blk[0]['blockContext'] = 0;
12363 $this->blk[0]['float_endpos'] = 0;
12364
12365 $this->pageoutput[$this->page] = array();
12366 $this->headerbuffer = '';
12367 $this->pageBackgrounds = $savepb;
12368 $this->x = $save_x;
12369 $this->y = $save_y;
12370 $this->state = $save_state;
12371 if($save_state==0) {
12372 unset($this->pages[1]);
12373 $this->page = 0;
12374 }
12375 return $h;
12376 }
12377
12378
12379 // Called internally from Header
12380 function writeHTMLHeaders() {
12381
12382 if ($this->mirrorMargins && ($this->page)%2==0) { $OE = 'E'; } // EVEN
12383 else { $OE = 'O'; }
12384 if ($OE == 'E') {
12385 $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeaderE['html'] ;
12386 }
12387 else {
12388 $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeader['html'] ;
12389 }
12390 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
12391 $this->saveHTMLHeader[$this->page][$OE]['rotate'] = true;
12392 $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->tMargin;
12393 $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->bMargin;
12394 $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header;
12395 $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer;
12396 $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->h;
12397 $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->w;
12398 }
12399 else {
12400 $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->lMargin;
12401 $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->rMargin;
12402 $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header;
12403 $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer;
12404 $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->w;
12405 $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->h;
12406 }
12407 }
12408
12409 function writeHTMLFooters() {
12410
12411 if ($this->mirrorMargins && ($this->page)%2==0) { $OE = 'E'; } // EVEN
12412 else { $OE = 'O'; }
12413 if ($OE == 'E') {
12414 $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooterE['html'] ;
12415 }
12416 else {
12417 $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooter['html'] ;
12418 }
12419 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
12420 $this->saveHTMLFooter[$this->page][$OE]['rotate'] = true;
12421 $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->tMargin;
12422 $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->bMargin;
12423 $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->rMargin;
12424 $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->lMargin;
12425 $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header;
12426 $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer;
12427 $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->h;
12428 $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->w;
12429 }
12430 else {
12431 $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->lMargin;
12432 $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->rMargin;
12433 $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->tMargin;
12434 $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->bMargin;
12435 $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header;
12436 $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer;
12437 $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->w;
12438 $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->h;
12439 }
12440 }
12441 /*-- END HTMLHEADERS-FOOTERS --*/
12442
12443 function DefHeaderByName($name,$arr) {
12444 if (!$name) { $name = '_default'; }
12445 $this->pageheaders[$name] = $arr;
12446 }
12447
12448 function DefFooterByName($name,$arr) {
12449 if (!$name) { $name = '_default'; }
12450 $this->pagefooters[$name] = $arr;
12451 }
12452
12453 function SetHeaderByName($name,$side='O',$write=false) {
12454 if (!$name) { $name = '_default'; }
12455 if ($side=='E') { $this->headerDetails['even'] = $this->pageheaders[$name]; }
12456 else { $this->headerDetails['odd'] = $this->pageheaders[$name]; }
12457 if ($write) { $this->Header(); }
12458 }
12459
12460 function SetFooterByName($name,$side='O') {
12461 if (!$name) { $name = '_default'; }
12462 if ($side=='E') { $this->footerDetails['even'] = $this->pagefooters[$name]; }
12463 else { $this->footerDetails['odd'] = $this->pagefooters[$name]; }
12464 }
12465
12466 /*-- HTMLHEADERS-FOOTERS --*/
12467 function DefHTMLHeaderByName($name,$html) {
12468 if (!$name) { $name = '_default'; }
12469
12470 $this->pageHTMLheaders[$name]['html'] = $html;
12471 $this->pageHTMLheaders[$name]['h'] = $this->_gethtmlheight($html);
12472 }
12473
12474 function DefHTMLFooterByName($name,$html) {
12475 if (!$name) { $name = '_default'; }
12476
12477 $this->pageHTMLfooters[$name]['html'] = $html;
12478 $this->pageHTMLfooters[$name]['h'] = $this->_gethtmlheight($html);
12479 }
12480
12481 function SetHTMLHeaderByName($name,$side='O',$write=false) {
12482 if (!$name) { $name = '_default'; }
12483 $this->SetHTMLHeader($this->pageHTMLheaders[$name],$side,$write);
12484 }
12485
12486 function SetHTMLFooterByName($name,$side='O') {
12487 if (!$name) { $name = '_default'; }
12488 $this->SetHTMLFooter($this->pageHTMLfooters[$name],$side);
12489 }
12490 /*-- END HTMLHEADERS-FOOTERS --*/
12491
12492
12493 function SetHeader($Harray=array(),$side='',$write=false) {
12494 if (is_string($Harray)) {
12495 if (strlen($Harray)==0) {
12496 if ($side=='O') { $this->headerDetails['odd'] = array(); }
12497 else if ($side=='E') { $this->headerDetails['even'] = array(); }
12498 else { $this->headerDetails = array(); }
12499 }
12500 else if (strpos($Harray,'|') || strpos($Harray,'|')===0) {
12501 $hdet = explode('|',$Harray);
12502 $this->headerDetails = array (
12503 'odd' => array (
12504 'L' => array ('content' => $hdet[0], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12505 'C' => array ('content' => $hdet[1], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12506 'R' => array ('content' => $hdet[2], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12507 'line' => $this->defaultheaderline,
12508 ),
12509 'even' => array (
12510 'R' => array ('content' => $hdet[0], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12511 'C' => array ('content' => $hdet[1], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12512 'L' => array ('content' => $hdet[2], 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12513 'line' => $this->defaultheaderline,
12514 )
12515 );
12516 }
12517 else {
12518 $this->headerDetails = array (
12519 'odd' => array (
12520 'R' => array ('content' => $Harray, 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12521 'line' => $this->defaultheaderline,
12522 ),
12523 'even' => array (
12524 'L' => array ('content' => $Harray, 'font-size' => $this->defaultheaderfontsize, 'font-style' => $this->defaultheaderfontstyle),
12525 'line' => $this->defaultheaderline,
12526 )
12527 );
12528 }
12529 }
12530 else if (is_array($Harray)) {
12531 if ($side=='O') { $this->headerDetails['odd'] = $Harray; }
12532 else if ($side=='E') { $this->headerDetails['even'] = $Harray; }
12533 else { $this->headerDetails = $Harray; }
12534 }
12535 /*-- HTMLHEADERS-FOOTERS --*/
12536 // Overwrite any HTML Header previously set
12537 if ($side=='E') { $this->SetHTMLHeader('','E'); }
12538 else if ($side=='O') { $this->SetHTMLHeader(''); }
12539 else {
12540 $this->SetHTMLHeader('');
12541 $this->SetHTMLHeader('','E');
12542 }
12543 /*-- END HTMLHEADERS-FOOTERS --*/
12544
12545 if ($write) {
12546 $save_y = $this->y;
12547 $this->Header();
12548 $this->SetY($save_y) ;
12549 }
12550 }
12551
12552
12553
12554
12555 function SetFooter($Farray=array(),$side='') {
12556 if (is_string($Farray)) {
12557 if (strlen($Farray)==0) {
12558 if ($side=='O') { $this->footerDetails['odd'] = array(); }
12559 else if ($side=='E') { $this->footerDetails['even'] = array(); }
12560 else { $this->footerDetails = array(); }
12561 }
12562 else if (strpos($Farray,'|') || strpos($Farray,'|')===0) {
12563 $fdet = explode('|',$Farray);
12564 $this->footerDetails = array (
12565 'odd' => array (
12566 'L' => array ('content' => $fdet[0], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12567 'C' => array ('content' => $fdet[1], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12568 'R' => array ('content' => $fdet[2], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12569 'line' => $this->defaultfooterline,
12570 ),
12571 'even' => array (
12572 'R' => array ('content' => $fdet[0], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12573 'C' => array ('content' => $fdet[1], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12574 'L' => array ('content' => $fdet[2], 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12575 'line' => $this->defaultfooterline,
12576 )
12577 );
12578 }
12579 else {
12580 $this->footerDetails = array (
12581 'odd' => array (
12582 'R' => array ('content' => $Farray, 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12583 'line' => $this->defaultfooterline,
12584 ),
12585 'even' => array (
12586 'L' => array ('content' => $Farray, 'font-size' => $this->defaultfooterfontsize, 'font-style' => $this->defaultfooterfontstyle),
12587 'line' => $this->defaultfooterline,
12588 )
12589 );
12590 }
12591 }
12592 else if (is_array($Farray)) {
12593 if ($side=='O') { $this->footerDetails['odd'] = $Farray; }
12594 else if ($side=='E') { $this->footerDetails['even'] = $Farray; }
12595 else { $this->footerDetails = $Farray; }
12596 }
12597 /*-- HTMLHEADERS-FOOTERS --*/
12598 // Overwrite any HTML Footer previously set
12599 if ($side=='E') { $this->SetHTMLFooter('','E'); }
12600 else if ($side=='O') { $this->SetHTMLFooter(''); }
12601 else {
12602 $this->SetHTMLFooter('');
12603 $this->SetHTMLFooter('','E');
12604 }
12605 /*-- END HTMLHEADERS-FOOTERS --*/
12606 }
12607
12608 /*-- WATERMARK --*/
12609 function setUnvalidatedText($txt='', $alpha=-1) {
12610 if ($alpha>=0) $this->watermarkTextAlpha = $alpha;
12611 $this->watermarkText = $txt;
12612 }
12613 function SetWatermarkText($txt='', $alpha=-1) {
12614 if ($alpha>=0) $this->watermarkTextAlpha = $alpha;
12615 $this->watermarkText = $txt;
12616 }
12617
12618 function SetWatermarkImage($src, $alpha=-1, $size='D', $pos='F') {
12619 if ($alpha>=0) $this->watermarkImageAlpha = $alpha;
12620 $this->watermarkImage = $src;
12621 $this->watermark_size = $size;
12622 $this->watermark_pos = $pos;
12623 }
12624 /*-- END WATERMARK --*/
12625
12626
12627 //Page footer
12628 function Footer() {
12629 /*-- CSS-PAGE --*/
12630 // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
12631 if ($this->show_marks == 'CROP' || $this->show_marks == 'CROPCROSS') {
12632 // Show TICK MARKS
12633 $this->SetLineWidth(0.1); // = 0.1 mm
12634 $this->SetDColor($this->ConvertColor(0));
12635 $l = $this->cropMarkLength;
12636 $m = $this->cropMarkMargin; // Distance of crop mark from margin
12637 $b = $this->nonPrintMargin; // Non-printable border at edge of paper sheet
12638 $ax1 = $b;
12639 $bx = $this->page_box['outer_width_LR'] - $m;
12640 $ax = max($ax1, $bx-$l);
12641 $cx1 = $this->w - $b;
12642 $dx = $this->w - $this->page_box['outer_width_LR'] + $m;
12643 $cx = min($cx1, $dx+$l);
12644 $ay1 = $b;
12645 $by = $this->page_box['outer_width_TB'] - $m;
12646 $ay = max($ay1, $by-$l);
12647 $cy1 = $this->h - $b;
12648 $dy = $this->h - $this->page_box['outer_width_TB'] + $m;
12649 $cy = min($cy1, $dy+$l);
12650
12651 $this->Line($ax, $this->page_box['outer_width_TB'], $bx, $this->page_box['outer_width_TB']);
12652 $this->Line($cx, $this->page_box['outer_width_TB'], $dx, $this->page_box['outer_width_TB']);
12653 $this->Line($ax, $this->h - $this->page_box['outer_width_TB'], $bx, $this->h - $this->page_box['outer_width_TB']);
12654 $this->Line($cx, $this->h - $this->page_box['outer_width_TB'], $dx, $this->h - $this->page_box['outer_width_TB']);
12655 $this->Line($this->page_box['outer_width_LR'], $ay, $this->page_box['outer_width_LR'], $by);
12656 $this->Line($this->page_box['outer_width_LR'], $cy, $this->page_box['outer_width_LR'], $dy);
12657 $this->Line($this->w - $this->page_box['outer_width_LR'], $ay, $this->w - $this->page_box['outer_width_LR'], $by);
12658 $this->Line($this->w - $this->page_box['outer_width_LR'], $cy, $this->w - $this->page_box['outer_width_LR'], $dy);
12659
12660 if ($this->printers_info) {
12661 $hd = date('Y-m-d H:i').' Page '.$this->page.' of {nb}';
12662 $this->SetTColor($this->ConvertColor(0));
12663 $this->SetFont('arial','',7.5,true,true);
12664 $this->x = $this->page_box['outer_width_LR'] + 1.5;
12665 $this->y = 1;
12666 $this->Cell($headerpgwidth ,$this->FontSize,$hd,0,0,'L',0,'',0,0,0,'M');
12667 $this->SetFont($this->default_font,'',$this->original_default_font_size);
12668 }
12669
12670 }
12671 if ($this->show_marks == 'CROSS' || $this->show_marks == 'CROPCROSS') {
12672 $this->SetLineWidth(0.1); // = 0.1 mm
12673 $this->SetDColor($this->ConvertColor(0));
12674 $l = 14 /2; // longer length of the cross line (half)
12675 $w = 6 /2; // shorter width of the cross line (half)
12676 $r = 1.2; // radius of circle
12677 $m = $this->crossMarkMargin; // Distance of cross mark from margin
12678 $x1 = $this->page_box['outer_width_LR'] - $m;
12679 $x2 = $this->w - $this->page_box['outer_width_LR'] + $m;
12680 $y1 = $this->page_box['outer_width_TB'] - $m;
12681 $y2 = $this->h - $this->page_box['outer_width_TB'] + $m;
12682 // Left
12683 $this->Circle($x1, $this->h/2, $r, 'S') ;
12684 $this->Line($x1-$w, $this->h/2, $x1+$w, $this->h/2);
12685 $this->Line($x1, $this->h/2-$l, $x1, $this->h/2+$l);
12686 // Right
12687 $this->Circle($x2, $this->h/2, $r, 'S') ;
12688 $this->Line($x2-$w, $this->h/2, $x2+$w, $this->h/2);
12689 $this->Line($x2, $this->h/2-$l, $x2, $this->h/2+$l);
12690 // Top
12691 $this->Circle($this->w/2, $y1, $r, 'S') ;
12692 $this->Line($this->w/2, $y1-$w, $this->w/2, $y1+$w);
12693 $this->Line($this->w/2-$l, $y1, $this->w/2+$l, $y1);
12694 // Bottom
12695 $this->Circle($this->w/2, $y2, $r, 'S') ;
12696 $this->Line($this->w/2, $y2-$w, $this->w/2, $y2+$w);
12697 $this->Line($this->w/2-$l, $y2, $this->w/2+$l, $y2);
12698 }
12699
12700
12701 // If @page set non-HTML headers/footers named, they were not read until later in the HTML code - so now set them
12702 if ($this->page==1) {
12703 if ($this->firstPageBoxHeader) {
12704 $this->headerDetails['odd'] = $this->pageheaders[$this->firstPageBoxHeader];
12705 $this->Header();
12706 }
12707 if ($this->firstPageBoxFooter) {
12708 $this->footerDetails['odd'] = $this->pagefooters[$this->firstPageBoxFooter];
12709 }
12710 $this->firstPageBoxHeader='';
12711 $this->firstPageBoxFooter='';
12712 }
12713 /*-- END CSS-PAGE --*/
12714
12715
12716
12717 /*-- HTMLHEADERS-FOOTERS --*/
12718 if (($this->mirrorMargins && ($this->page%2==0) && $this->HTMLFooterE) || ($this->mirrorMargins && ($this->page%2==1) && $this->HTMLFooter) || (!$this->mirrorMargins && $this->HTMLFooter)) {
12719 $this->writeHTMLFooters();
12720 /*-- WATERMARK --*/
12721 if (($this->watermarkText) && ($this->showWatermarkText)) {
12722 $this->watermark( $this->watermarkText, 45, 120, $this->watermarkTextAlpha); // Watermark text
12723 }
12724 if (($this->watermarkImage) && ($this->showWatermarkImage)) {
12725 $this->watermarkImg( $this->watermarkImage, $this->watermarkImageAlpha); // Watermark image
12726 }
12727 /*-- END WATERMARK --*/
12728 return;
12729 }
12730 /*-- END HTMLHEADERS-FOOTERS --*/
12731
12732 $this->processingHeader=true;
12733 $this->ResetMargins(); // necessary after columns
12734 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
12735 /*-- WATERMARK --*/
12736 if (($this->watermarkText) && ($this->showWatermarkText)) {
12737 $this->watermark( $this->watermarkText, 45, 120, $this->watermarkTextAlpha); // Watermark text
12738 }
12739 if (($this->watermarkImage) && ($this->showWatermarkImage)) {
12740 $this->watermarkImg( $this->watermarkImage, $this->watermarkImageAlpha); // Watermark image
12741 }
12742 /*-- END WATERMARK --*/
12743 $h = $this->footerDetails;
12744 if(count($h)) {
12745
12746 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
12747 $this->_out(sprintf('q 0 -1 1 0 0 %.3F cm ',($this->h*_MPDFK)));
12748 $headerpgwidth = $this->h - $this->orig_lMargin - $this->orig_rMargin;
12749 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
12750 $headerlmargin = $this->orig_rMargin;
12751 }
12752 else {
12753 $headerlmargin = $this->orig_lMargin;
12754 }
12755 }
12756 else {
12757 $yadj = 0;
12758 $headerpgwidth = $this->pgwidth;
12759 $headerlmargin = $this->lMargin;
12760 }
12761 $this->SetY(-$this->margin_footer);
12762
12763 $this->SetTColor($this->ConvertColor(0));
12764 $this->SUP = false;
12765 $this->SUB = false;
12766 $this->bullet = false;
12767
12768 // only show pagenumber if numbering on
12769 $pgno = $this->docPageNum($this->page, true);
12770
12771 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
12772 $side = 'even';
12773 }
12774 else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS = DEFAULT
12775 $side = 'odd';
12776 }
12777 $maxfontheight = 0;
12778 foreach(array('L','C','R') AS $pos) {
12779 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
12780 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
12781 else { $hfsz = $this->default_font_size; }
12782 $maxfontheight = max($maxfontheight,$hfsz);
12783 }
12784 }
12785 // LEFT-CENTER-RIGHT
12786 foreach(array('L','C','R') AS $pos) {
12787 if (isset($h[$side][$pos]['content']) && $h[$side][$pos]['content']) {
12788 $hd = str_replace('{PAGENO}',$pgno,$h[$side][$pos]['content']);
12789 $hd = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->aliasNbPgGp.$this->nbpgSuffix,$hd);
12790 $hd = preg_replace_callback('/\{DATE\s+(.*?)\}/', array($this, 'date_callback') ,$hd); // mPDF 5.7
12791 if (isset($h[$side][$pos]['font-family']) && $h[$side][$pos]['font-family']) { $hff = $h[$side][$pos]['font-family']; }
12792 else { $hff = $this->original_default_font; }
12793 if (isset($h[$side][$pos]['font-size']) && $h[$side][$pos]['font-size']) { $hfsz = $h[$side][$pos]['font-size']; }
12794 else { $hfsz = $this->original_default_font_size; }
12795 $maxfontheight = max($maxfontheight,$hfsz);
12796 if (isset($h[$side][$pos]['font-style']) && $h[$side][$pos]['font-style']) { $hfst = $h[$side][$pos]['font-style']; }
12797 else { $hfst = ''; }
12798 if (isset($h[$side][$pos]['color']) && $h[$side][$pos]['color']) {
12799 $hfcol = $h[$side][$pos]['color'];
12800 $cor = $this->ConvertColor($hfcol);
12801 if ($cor) { $this->SetTColor($cor); }
12802 }
12803 else { $hfcol = ''; }
12804 $this->SetFont($hff,$hfst,$hfsz,true,true);
12805 $this->x = $headerlmargin ;
12806 $this->y = $this->h - $this->margin_footer - ($maxfontheight/_MPDFK);
12807 $hd = $this->purify_utf8_text($hd);
12808 if ($this->text_input_as_HTML) {
12809 $hd = $this->all_entities_to_utf8($hd);
12810 }
12811 // CONVERT CODEPAGE
12812 if ($this->usingCoreFont) { $hd = mb_convert_encoding($hd,$this->mb_enc,'UTF-8'); }
12813 // DIRECTIONALITY RTL
12814 $this->magic_reverse_dir($hd, true, $this->directionality); // *RTL*
12815 // Font-specific ligature substitution for Indic fonts
12816 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($hd); // *INDIC*
12817 $align = $pos;
12818 if ($this->directionality == 'rtl') {
12819 if ($pos == 'L') { $align = 'R'; }
12820 else if ($pos == 'R') { $align = 'L'; }
12821 }
12822
12823 if ($pos!='L' && (strpos($hd,$this->aliasNbPg)!==false || strpos($hd,$this->aliasNbPgGp)!==false)) {
12824 if (strpos($hd,$this->aliasNbPgGp)!==false) { $type= 'nbpggp'; } else { $type= 'nbpg'; }
12825 $this->_out('{mpdfheader'.$type.' '.$pos.' ff='.$hff.' fs='.$hfst.' fz='.$hfsz.'}');
12826 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
12827 $this->_out('Q');
12828 }
12829 else {
12830 $this->Cell($headerpgwidth ,$maxfontheight/_MPDFK ,$hd,0,0,$align,0,'',0,0,0,'M');
12831 }
12832 if ($hfcol) { $this->SetTColor($this->ConvertColor(0)); }
12833 }
12834 }
12835 // Return Font to normal
12836 $this->SetFont($this->default_font,'',$this->original_default_font_size);
12837
12838 // LINE
12839
12840 if (isset($h[$side]['line']) && $h[$side]['line']) {
12841 $this->SetLineWidth(0.1);
12842 $this->SetDColor($this->ConvertColor(0));
12843 $this->Line($headerlmargin , $this->y-($maxfontheight*($this->footer_line_spacing)/_MPDFK), $headerlmargin +$headerpgwidth, $this->y-($maxfontheight*($this->footer_line_spacing)/_MPDFK));
12844 }
12845 if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
12846 $this->_out('Q');
12847 }
12848 }
12849 $this->processingHeader=false;
12850
12851 }
12852
12853 ///////////////////
12854 // HYPHENATION
12855 ///////////////////
12856 // mPDF 5.6.21
12857 // Hard hyphens
12858 function hardHyphenate($word, $maxWidth) {
12859 // Don't hyphenate web addresses
12860 if (preg_match('/^(http:|www\.)/',$word)) { return array(false,'','',''); }
12861
12862 // Get dictionary
12863 $poss = array();
12864 $softhyphens = array();
12865 $offset = 0;
12866 $p = true;
12867 if ($this->usingCoreFont) {
12868 $wl = strlen($word);
12869 }
12870 else {
12871 $wl = mb_strlen($word,'UTF-8');
12872 }
12873 while($offset < $wl) {
12874 if (!$this->usingCoreFont) {
12875 $p = mb_strpos($word, "-", $offset, 'UTF-8');
12876 }
12877 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
12878 $p = strpos($word, "-", $offset);
12879 }
12880 if ($p !== false) { $poss[] = $p; } // mPDF 5.7.2
12881 else { break; }
12882 $offset = $p+1;
12883 }
12884 $success = false;
12885 foreach($poss AS $i) {
12886 if ($this->usingCoreFont) {
12887 $a = substr($word,0,$i);
12888 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12889 $pre = $a;
12890 $post = substr($word,$i,strlen($word));
12891 $prelength = strlen($pre);
12892 }
12893 else {
12894 $a = mb_substr($word,0,$i,'UTF-8');
12895 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12896 $pre = $a;
12897 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8');
12898 $prelength = mb_strlen($pre, 'UTF-8');
12899 }
12900 $success = true;
12901 }
12902 return array($success,$pre,$post,$prelength);
12903 }
12904
12905
12906 /*-- HYPHENATION --*/
12907 ///////////////////
12908 ///////////////////
12909 // HYPHENATION
12910 ///////////////////
12911 // Soft hyphs
12912 function softHyphenate($word, $maxWidth) {
12913 // Don't hyphenate web addresses
12914 if (preg_match('/^(http:|www\.)/',$word)) { return array(false,'','',''); }
12915
12916 // Get dictionary
12917 $poss = array();
12918 $softhyphens = array();
12919 $offset = 0;
12920 $p = true;
12921 if ($this->usingCoreFont) {
12922 $wl = strlen($word);
12923 }
12924 else {
12925 $wl = mb_strlen($word,'UTF-8');
12926 }
12927 while($offset < $wl) {
12928 // Soft Hyphens chr(173)
12929 if (!$this->usingCoreFont) {
12930 $p = mb_strpos($word, "\xc2\xad", $offset, 'UTF-8');
12931 }
12932 else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
12933 $p = strpos($word, chr(173), $offset);
12934 }
12935 // mPDF 5.7.2
12936 //if ($p !== false) { $poss[] = $p - count($poss); }
12937 if ($p !== false) { $poss[] = $p; }
12938 else { break; }
12939 $offset = $p+1;
12940 }
12941 $success = false;
12942 foreach($poss AS $i) {
12943 if ($this->usingCoreFont) {
12944 $a = substr($word,0,$i);
12945 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12946 $pre = $a;
12947 $post = substr($word,$i,strlen($word));
12948 $prelength = strlen($pre);
12949 }
12950 else {
12951 $a = mb_substr($word,0,$i,'UTF-8');
12952 if ($this->GetStringWidth($a.'-') > $maxWidth) { break ; }
12953 $pre = $a;
12954 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8');
12955 $prelength = mb_strlen($pre, 'UTF-8');
12956 }
12957 $success = true;
12958 }
12959 return array($success,$pre,$post,$prelength);
12960 }
12961
12962 ///////////////////
12963 // Word hyphenation
12964 function hyphenateWord($word, $maxWidth) {
12965 // Do everything inside this function in utf-8
12966 // Don't hyphenate web addresses
12967 if (preg_match('/^(http:|www\.)/',$word)) { return array(false,'','',''); }
12968
12969
12970 // Get dictionary
12971 if (!$this->loadedSHYdictionary) {
12972 if (file_exists(_MPDF_PATH.'patterns/dictionary.txt')) {
12973 $this->SHYdictionary = file(_MPDF_PATH.'patterns/dictionary.txt',FILE_SKIP_EMPTY_LINES);
12974 foreach($this->SHYdictionary as $entry) {
12975 $entry = trim($entry);
12976 $poss = array();
12977 $offset = 0;
12978 $p = true;
12979 $wl = mb_strlen($entry ,'UTF-8');
12980 while($offset < $wl) {
12981 $p = mb_strpos($entry, '/', $offset, 'UTF-8');
12982 if ($p !== false) { $poss[] = $p - count($poss); }
12983 else { break; }
12984 $offset = $p+1;
12985 }
12986 if (count($poss)) { $this->SHYdictionaryWords[str_replace('/', '', mb_strtolower($entry))] = $poss; }
12987 }
12988 }
12989 $this->loadedSHYdictionary = true;
12990 }
12991
12992 if (!in_array($this->SHYlang,$this->SHYlanguages)) { return array(false,'','',''); }
12993 // If no pattern loaded or not the best one
12994 if (count($this->SHYpatterns) < 1 || ($this->loadedSHYpatterns && $this->loadedSHYpatterns != $this->SHYlang)) {
12995 include(_MPDF_PATH."patterns/" . $this->SHYlang . ".php");
12996 $patterns = explode(' ', $patterns);
12997 $new_patterns = array();
12998 for($i = 0; $i < count($patterns); $i++) {
12999 $value = $patterns[$i];
13000 $new_patterns[preg_replace('/[0-9]/', '', $value)] = $value;
13001 }
13002 $this->SHYpatterns = $new_patterns;
13003 $this->loadedSHYpatterns = $this->SHYlang;
13004 }
13005
13006 if ($this->usingCoreFont) { $word = mb_convert_encoding($word,'UTF-8',$this->mb_enc); }
13007
13008 $prepre = '';
13009 $postpost = '';
13010 $startpunctuation = "\xc2\xab\xc2\xbf\xe2\x80\x98\xe2\x80\x9b\xe2\x80\x9c\xe2\x80\x9f";
13011 $endpunctuation = "\xe2\x80\x9e\xe2\x80\x9d\xe2\x80\x9a\xe2\x80\x99\xc2\xbb";
13012 $pre = '';
13013 $post = '';
13014
13015
13016 if (preg_match('/^(["\''.$startpunctuation .'])+(.{'.$this->SHYcharmin.',})$/u',$word,$m)) {
13017 $prepre = $m[1];
13018 $word = $m[2];
13019 }
13020 if (preg_match('/^(.{'.$this->SHYcharmin.',})([\'\.,;:!?"'.$endpunctuation .']+)$/u',$word,$m)) {
13021 $word = $m[1];
13022 $postpost = $m[2];
13023 }
13024 if(mb_strlen($word,'UTF-8') < $this->SHYcharmin) {
13025 return array(false,'','','');
13026 }
13027 $success = false;
13028
13029 if(isset($this->SHYdictionaryWords[mb_strtolower($word)])) {
13030 foreach($this->SHYdictionaryWords[mb_strtolower($word)] AS $i) {
13031 $a = $prepre . mb_substr($word,0,$i,'UTF-8');
13032 if ($this->usingCoreFont) { $testa = mb_convert_encoding($a,$this->mb_enc,'UTF-8'); }
13033 else { $testa = $a; }
13034 if ($this->GetStringWidth($testa.'-') > $maxWidth) { break ; }
13035 $pre = $a;
13036 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8') . $postpost;
13037 $success = true;
13038 }
13039 }
13040
13041 if (!$success) {
13042 $text_word = '_' . $word . '_';
13043 $word_length = mb_strlen($text_word,'UTF-8');
13044
13045 $single_character = preg_split('//u', $text_word);
13046
13047 $text_word = mb_strtolower($text_word,'UTF-8');
13048 $hyphenated_word = array();
13049 $numb3rs = array('0' => true, '1' => true, '2' => true, '3' => true, '4' => true, '5' => true, '6' => true, '7' => true, '8' => true, '9' => true);
13050 for($position = 0; $position <= ($word_length - $this->SHYcharmin); $position++) {
13051 $maxwins = min(($word_length - $position), $this->SHYcharmax);
13052 for($win = $this->SHYcharmin; $win <= $maxwins; $win++) {
13053 if(isset($this->SHYpatterns[mb_substr($text_word, $position, $win,'UTF-8')])) {
13054 $pattern = $this->SHYpatterns[mb_substr($text_word, $position, $win,'UTF-8')];
13055 $digits = 1;
13056 $pattern_length = mb_strlen($pattern,'UTF-8');
13057 for($i = 0; $i < $pattern_length; $i++) {
13058 $char = $pattern[$i];
13059 if(isset($numb3rs[$char])) {
13060 $zero = ($i == 0) ? $position - 1 : $position + $i - $digits;
13061 if(!isset($hyphenated_word[$zero]) || $hyphenated_word[$zero] != $char) $hyphenated_word[$zero] = $char;
13062 $digits++;
13063 }
13064 }
13065 }
13066 }
13067 }
13068
13069 for($i = $this->SHYleftmin; $i <= (mb_strlen($word,'UTF-8') - $this->SHYrightmin); $i++) {
13070 if(isset($hyphenated_word[$i]) && $hyphenated_word[$i] % 2 != 0) {
13071 $a = $prepre . mb_substr($word,0,$i,'UTF-8');
13072 if ($this->usingCoreFont) { $testa = mb_convert_encoding($a,$this->mb_enc,'UTF-8'); }
13073 else { $testa = $a; }
13074 if ($this->GetStringWidth($testa.'-') > $maxWidth + 0.0001) { break ; }
13075 $pre = $a;
13076 $post = mb_substr($word,$i,mb_strlen($word,'UTF-8'),'UTF-8') . $postpost;
13077 $success = true;
13078 }
13079 }
13080 }
13081 if ($this->usingCoreFont) {
13082 $pre = mb_convert_encoding($pre,$this->mb_enc,'UTF-8');
13083 $post = mb_convert_encoding($post,$this->mb_enc,'UTF-8');
13084 $prelength = strlen($pre);
13085 }
13086 else {
13087 $prelength = mb_strlen($pre);
13088 }
13089 return array($success,$pre,$post,$prelength);
13090
13091 }
13092 /*-- END HYPHENATION --*/
13093
13094
13095 /*-- HTML-CSS --*/
13096 ///////////////////
13097 /// HTML parser ///
13098 ///////////////////
13099 function WriteHTML($html,$sub=0,$init=true,$close=true) {
13100 // $sub ADDED - 0 = default; 1=headerCSS only; 2=HTML body (parts) only; 3 - HTML parses only
13101 // 4 - writes HTML headers
13102 // $close Leaves buffers etc. in current state, so that it can continue a block etc.
13103 // $init - Clears and sets buffers to Top level block etc.
13104
13105 if (empty($html)) { $html = ''; }
13106 if ($this->progressBar) { $this->UpdateProgressBar(1,0,'Parsing CSS & Headers'); } // *PROGRESS-BAR*
13107
13108 if ($init) {
13109 $this->headerbuffer='';
13110 $this->textbuffer = array();
13111 $this->fixedPosBlockSave = array();
13112 }
13113 if ($sub == 1) { $html = '<style> '.$html.' </style>'; } // stylesheet only
13114
13115 if ($this->allow_charset_conversion) {
13116 if ($sub < 1) {
13117 $this->ReadCharset($html);
13118 }
13119 if ($this->charset_in && $sub!=4) { // mPDF 5.4.14
13120 $success = iconv($this->charset_in,'UTF-8//TRANSLIT',$html);
13121 if ($success) { $html = $success; }
13122 }
13123 }
13124 $html = $this->purify_utf8($html,false);
13125 if ($init) {
13126 $this->blklvl = 0;
13127 $this->lastblocklevelchange = 0;
13128 $this->blk = array();
13129 $this->initialiseBlock($this->blk[0]);
13130 $this->blk[0]['width'] =& $this->pgwidth;
13131 $this->blk[0]['inner_width'] =& $this->pgwidth;
13132 $this->blk[0]['blockContext'] = $this->blockContext;
13133 }
13134
13135 $zproperties = array();
13136 if ($sub < 2) {
13137 $this->ReadMetaTags($html);
13138
13139 // mPDF 5.6.18
13140 if (preg_match('/<base[^>]*href=["\']([^"\'>]*)["\']/i', $html, $m)) {
13141 $this->SetBasePath($m[1]);
13142 }
13143 // NB default stylesheet now in mPDF.css - read on initialising class
13144 $html = $this->cssmgr->ReadCSS($html);
13145
13146 if ($this->useLang && !$this->usingCoreFont && preg_match('/<html [^>]*lang=[\'\"](.*?)[\'\"]/ism',$html,$m)) {
13147 $html_lang = $m[1];
13148 }
13149
13150 if (preg_match('/<html [^>]*dir=[\'\"]\s*rtl\s*[\'\"]/ism',$html)) {
13151 $zproperties['DIRECTION'] = 'rtl';
13152 }
13153
13154 // allow in-line CSS for body tag to be parsed // Get <body> tag inline CSS
13155 if (preg_match('/<body([^>]*)>(.*?)<\/body>/ism',$html,$m) || preg_match('/<body([^>]*)>(.*)$/ism',$html,$m)) {
13156 $html = $m[2];
13157 // Changed to allow style="background: url('bg.jpg')"
13158 if (preg_match('/style=[\"](.*?)[\"]/ism',$m[1],$mm) || preg_match('/style=[\'](.*?)[\']/ism',$m[1],$mm)) {
13159 $zproperties = $this->cssmgr->readInlineCSS($mm[1]);
13160 }
13161 if (preg_match('/dir=[\'\"]\s*rtl\s*[\'\"]/ism',$m[1])) {
13162 $zproperties['DIRECTION'] = 'rtl';
13163 }
13164 if (isset($html_lang) && $html_lang) { $zproperties['LANG'] = $html_lang; }
13165 if ($this->useLang && !$this->onlyCoreFonts && preg_match('/lang=[\'\"](.*?)[\'\"]/ism',$m[1],$mm)) {
13166 $zproperties['LANG'] = $mm[1];
13167 }
13168
13169 }
13170 }
13171 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
13172 if ($zproperties) { $properties = $this->cssmgr->array_merge_recursive_unique($properties,$zproperties); }
13173
13174 if (isset($properties['DIRECTION']) && $properties['DIRECTION']) {
13175 $this->cssmgr->CSS['BODY']['DIRECTION'] = $properties['DIRECTION'];
13176 }
13177 if (!isset($this->cssmgr->CSS['BODY']['DIRECTION'])) {
13178 $this->cssmgr->CSS['BODY']['DIRECTION'] = $this->directionality;
13179 }
13180 else { $this->SetDirectionality($this->cssmgr->CSS['BODY']['DIRECTION']); }
13181
13182 $this->setCSS($properties,'','BODY');
13183 $this->blk[0]['InlineProperties'] = $this->saveInlineProperties();
13184
13185 if ($sub == 1) { return ''; }
13186 if (!isset($this->cssmgr->CSS['BODY'])) { $this->cssmgr->CSS['BODY'] = array(); }
13187
13188 /*-- BACKGROUNDS --*/
13189 if (isset($properties['BACKGROUND-GRADIENT'])) {
13190 $this->bodyBackgroundGradient = $properties['BACKGROUND-GRADIENT'];
13191 }
13192
13193 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE']) {
13194 $ret = $this->SetBackground($properties, $this->pgwidth);
13195 if ($ret) { $this->bodyBackgroundImage = $ret; }
13196 }
13197 /*-- END BACKGROUNDS --*/
13198
13199 /*-- CSS-PAGE --*/
13200 // If page-box is set
13201 if ($this->state==0 && ((isset($this->cssmgr->CSS['@PAGE']) && $this->cssmgr->CSS['@PAGE']) || (isset($this->cssmgr->CSS['@PAGE>>PSEUDO>>FIRST']) && $this->cssmgr->CSS['@PAGE>>PSEUDO>>FIRST'])) ) { // mPDF 5.7.3
13202 $this->page_box['current'] = '';
13203 $this->page_box['using'] = true;
13204 list($pborientation,$pbmgl,$pbmgr,$pbmgt,$pbmgb,$pbmgh,$pbmgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS('', false, 'O');
13205 $this->DefOrientation = $this->CurOrientation = $pborientation;
13206 $this->orig_lMargin = $this->DeflMargin = $pbmgl;
13207 $this->orig_rMargin = $this->DefrMargin = $pbmgr;
13208 $this->orig_tMargin = $this->tMargin = $pbmgt;
13209 $this->orig_bMargin = $this->bMargin = $pbmgb;
13210 $this->orig_hMargin = $this->margin_header = $pbmgh;
13211 $this->orig_fMargin = $this->margin_footer = $pbmgf;
13212 list($pborientation,$pbmgl,$pbmgr,$pbmgt,$pbmgb,$pbmgh,$pbmgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS('', true, 'O'); // true=first page
13213 $this->show_marks = $marks;
13214 if ($hname && !preg_match('/^html_(.*)$/i',$hname)) $this->firstPageBoxHeader = $hname;
13215 if ($fname && !preg_match('/^html_(.*)$/i',$fname)) $this->firstPageBoxFooter = $fname;
13216 }
13217 /*-- END CSS-PAGE --*/
13218
13219 $parseonly = false;
13220 $this->bufferoutput = false;
13221 if ($sub == 3) {
13222 $parseonly = true;
13223 // Close any open block tags
13224 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
13225 // Output any text left in buffer
13226 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); }
13227 $this->textbuffer=array();
13228 }
13229 else if ($sub == 4) {
13230 // Close any open block tags
13231 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
13232 // Output any text left in buffer
13233 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); }
13234 $this->bufferoutput = true;
13235 $this->textbuffer=array();
13236 $this->headerbuffer='';
13237 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
13238 $this->setCSS($properties,'','BODY');
13239 }
13240
13241 mb_internal_encoding('UTF-8');
13242
13243 $html = $this->AdjustHTML($html, $this->tabSpaces); //Try to make HTML look more like XHTML
13244
13245 if ($this->autoFontGroups) { $html = $this->AutoFont($html); }
13246
13247 /*-- HTMLHEADERS-FOOTERS --*/
13248 preg_match_all('/<htmlpageheader([^>]*)>(.*?)<\/htmlpageheader>/si',$html,$h);
13249 for($i=0;$i<count($h[1]);$i++) {
13250 if (preg_match('/name=[\'|\"](.*?)[\'|\"]/',$h[1][$i],$n)) {
13251 $this->pageHTMLheaders[$n[1]]['html'] = $h[2][$i];
13252 $this->pageHTMLheaders[$n[1]]['h'] = $this->_gethtmlheight($h[2][$i]);
13253 }
13254 }
13255 preg_match_all('/<htmlpagefooter([^>]*)>(.*?)<\/htmlpagefooter>/si',$html,$f);
13256 for($i=0;$i<count($f[1]);$i++) {
13257 if (preg_match('/name=[\'|\"](.*?)[\'|\"]/',$f[1][$i],$n)) {
13258 $this->pageHTMLfooters[$n[1]]['html'] = $f[2][$i];
13259 $this->pageHTMLfooters[$n[1]]['h'] = $this->_gethtmlheight($f[2][$i]);
13260 }
13261 }
13262 /*-- END HTMLHEADERS-FOOTERS --*/
13263 $html = preg_replace('/<htmlpageheader.*?<\/htmlpageheader>/si','',$html);
13264 $html = preg_replace('/<htmlpagefooter.*?<\/htmlpagefooter>/si','',$html);
13265
13266 if($this->state==0 && $sub!=1 && $sub!=3 && $sub!=4) {
13267 $this->AddPage($this->CurOrientation);
13268 }
13269
13270
13271 /*-- HTMLHEADERS-FOOTERS --*/
13272
13273 if (isset($hname) && preg_match('/^html_(.*)$/i',$hname,$n)) $this->SetHTMLHeader($this->pageHTMLheaders[$n[1]],'O',true);
13274 if (isset($fname) && preg_match('/^html_(.*)$/i',$fname,$n)) $this->SetHTMLFooter($this->pageHTMLfooters[$n[1]],'O');
13275
13276 /*-- END HTMLHEADERS-FOOTERS --*/
13277
13278 $html=str_replace('<?','< ',$html); //Fix '<?XML' bug from HTML code generated by MS Word
13279
13280 $this->checkSIP = false;
13281 $this->checkSMP = false;
13282 $this->checkCJK = false;
13283 if ($this->onlyCoreFonts) { $html = $this->SubstituteChars($html); }
13284 else {
13285 if (preg_match("/([".$this->pregRTLchars."])/u", $html)) { $this->biDirectional = true; } // *RTL*
13286 if (preg_match("/([\x{20000}-\x{2FFFF}])/u", $html)) { $this->checkSIP = true; }
13287 if (preg_match("/([\x{10000}-\x{1FFFF}])/u", $html)) { $this->checkSMP = true; }
13288 /*-- CJK-FONTS --*/
13289 if (preg_match("/([".$this->pregCJKchars."])/u", $html)) { $this->checkCJK = true; }
13290 /*-- END CJK-FONTS --*/
13291 }
13292
13293 // Don't allow non-breaking spaces that are converted to substituted chars or will break anyway and mess up table width calc.
13294 $html = str_replace('<tta>160</tta>',chr(32),$html);
13295 $html = str_replace('</tta><tta>','|',$html);
13296 $html = str_replace('</tts><tts>','|',$html);
13297 $html = str_replace('</ttz><ttz>','|',$html);
13298
13299 //Add new supported tags in the DisableTags function
13300 $html=strip_tags($html,$this->enabledtags); //remove all unsupported tags, but the ones inside the 'enabledtags' string
13301
13302 //Explode the string in order to parse the HTML code
13303 $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
13304 // ? more accurate regexp that allows e.g. <a name="Silly <name>">
13305 // if changing - also change in fn.SubstituteChars()
13306 // $a = preg_split ('/<((?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+)>/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
13307
13308 if ($this->mb_enc) {
13309 mb_internal_encoding($this->mb_enc);
13310 }
13311 $pbc = 0;
13312 if ($this->progressBar) { $this->UpdateProgressBar(1,0); } // *PROGRESS-BAR*
13313 $this->subPos = -1;
13314 $cnt = count($a);
13315 for($i=0;$i<$cnt; $i++) {
13316 $e = $a[$i];
13317 if($i%2==0) {
13318 //TEXT
13319 if ($this->blk[$this->blklvl]['hide']) { continue; }
13320 if ($this->inlineDisplayOff) { continue; }
13321 if ($this->inMeter) { continue; } // mPDF 5.5.09
13322
13323 if ($this->inFixedPosBlock) { $this->fixedPosBlock .= $e; continue; } // *CSS-POSITION*
13324 if (strlen($e) == 0) { continue; }
13325
13326 $e = strcode2utf($e);
13327 $e = $this->lesser_entity_decode($e);
13328
13329 if ($this->usingCoreFont) {
13330 // If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
13331 if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->subPos<$i && !$this->specialcontent) {
13332 $cnt += $this->SubstituteCharsNonCore($a, $i, $e);
13333 }
13334 // CONVERT ENCODING
13335 $e = mb_convert_encoding($e,$this->mb_enc,'UTF-8');
13336 // mPDF 5.6.41
13337 if ($this->toupper) { $e = mb_strtoupper($e,$this->mb_enc); }
13338 if ($this->tolower) { $e = mb_strtolower($e,$this->mb_enc); }
13339 if ($this->capitalize) { $e = mb_convert_case($e, MB_CASE_TITLE, "UTF-8"); }
13340 }
13341 else {
13342 if ($this->checkSIP && $this->CurrentFont['sipext'] && $this->subPos<$i && !$this->specialcontent) {
13343 $cnt += $this->SubstituteCharsSIP($a, $i, $e);
13344 }
13345
13346 if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->CurrentFont['type']!='Type0' && $this->subPos<$i && !$this->specialcontent) {
13347 // mPDF 5.6.62 removes U+200E/U+200F LTR and RTL mark and U+200C/U+200D Zero-width Joiner and Non-joiner
13348 $e = preg_replace("/[\xe2\x80\x8c\xe2\x80\x8d\xe2\x80\x8e\xe2\x80\x8f]/u",'',$e);
13349 $cnt += $this->SubstituteCharsMB($a, $i, $e);
13350 }
13351 if ($this->biDirectional) { // *RTL*
13352 // mPDF 5.7+
13353 $e = preg_replace_callback("/([".$this->pregRTLchars."]+)/u", array($this, 'arabJoinPregCallback'), $e ); // *RTL*
13354 } // *RTL*
13355 // Font-specific ligature substitution for Indic fonts
13356 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($e); // *INDIC*
13357
13358 // mPDF 5.6.62 removes U+200E/U+200F LTR and RTL mark and U+200C/U+200D Zero-width Joiner and Non-joiner
13359 $e = preg_replace("/[\xe2\x80\x8c\xe2\x80\x8d\xe2\x80\x8e\xe2\x80\x8f]/u",'',$e);
13360
13361 if ($this->toupper) { $e = mb_strtoupper($e,$this->mb_enc); }
13362 if ($this->tolower) { $e = mb_strtolower($e,$this->mb_enc); }
13363 if ($this->capitalize) { $e = mb_convert_case($e, MB_CASE_TITLE, "UTF-8"); }
13364 }
13365 if (($this->tts) || ($this->ttz) || ($this->tta)) {
13366 $es = explode('|',$e);
13367 $e = '';
13368 foreach($es AS $val) {
13369 $e .= chr($val);
13370 }
13371 }
13372 //Adjust lineheight
13373
13374 // FORM ELEMENTS
13375 if ($this->specialcontent) {
13376 /*-- FORMS --*/
13377 //SELECT tag (form element)
13378 if ($this->specialcontent == "type=select") {
13379 $e = ltrim($e);
13380 $stringwidth = $this->GetStringWidth($e);
13381 if (!isset($this->selectoption['MAXWIDTH']) || $stringwidth > $this->selectoption['MAXWIDTH']) { $this->selectoption['MAXWIDTH'] = $stringwidth; }
13382 if (!isset($this->selectoption['SELECTED']) || $this->selectoption['SELECTED'] == '') { $this->selectoption['SELECTED'] = $e; }
13383 // mPDD 1.4 Active Forms
13384 if (isset($this->selectoption['ACTIVE']) && $this->selectoption['ACTIVE']) {
13385 $this->selectoption['ITEMS'][]=array('exportValue'=>$this->selectoption['currentVAL'], 'content'=>$e, 'selected'=>$this->selectoption['currentSEL']);
13386 }
13387 }
13388 // TEXTAREA
13389 else {
13390 $objattr = unserialize($this->specialcontent);
13391 $objattr['text'] = $e;
13392 $te = "\xbb\xa4\xactype=textarea,objattr=".serialize($objattr)."\xbb\xa4\xac";
13393 if ($this->tdbegin) {
13394 $this->_saveCellTextBuffer($te, $this->HREF);
13395 }
13396 else {
13397 $this->_saveTextBuffer($te, $this->HREF);
13398 }
13399 }
13400 /*-- END FORMS --*/
13401 }
13402
13403 // TABLE
13404 else if ($this->tableLevel) {
13405 /*-- TABLES --*/
13406 if ($this->tdbegin) {
13407 if (($this->ignorefollowingspaces) && !$this->ispre) { $e = ltrim($e); }
13408 if ($e || $e==='0') {
13409 if (($this->blockjustfinished || $this->listjustfinished) && $this->cell[$this->row][$this->col]['s']>0) {
13410 $this->_saveCellTextBuffer("\n");
13411 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
13412 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
13413 }
13414 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
13415 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
13416 }
13417 $this->cell[$this->row][$this->col]['s'] = 0;// reset
13418 }
13419 $this->blockjustfinished=false;
13420 $this->listjustfinished=false;
13421
13422 $this->_saveCellTextBuffer($e, $this->HREF);
13423
13424 if (!isset($this->cell[$this->row][$this->col]['R']) || !$this->cell[$this->row][$this->col]['R']) {
13425 if (isset($this->cell[$this->row][$this->col]['s'])) {
13426 $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($e, false);
13427 }
13428 else { $this->cell[$this->row][$this->col]['s'] = $this->GetStringWidth($e, false); }
13429 if (!empty($this->spanborddet)) {
13430 $this->cell[$this->row][$this->col]['s'] += $this->spanborddet['L']['w'] + $this->spanborddet['R']['w'];
13431 }
13432 }
13433
13434 if ($this->checkCJK && preg_match("/([".$this->pregCJKchars."])/u", $e)) { $this->tableCJK = true; } // *CJK-FONTS*
13435
13436 // mPDF 5.6.13 Decimal mark alignment
13437 if (substr($this->cell[$this->row][$this->col]['a'],0,1) == 'D') {
13438 $dp = $this->decimal_align[substr($this->cell[$this->row][$this->col]['a'],0,2)];
13439 $s = preg_split('/'.preg_quote($dp,'/').'/', $e, 2); // ? needs to be /u if not core
13440 $s0 = $this->GetStringWidth($s[0], false);
13441 if ($s[1]) { $s1 = $this->GetStringWidth(($s[1].$dp), false); }
13442 else $s1 = 0;
13443 if (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'])) {
13444 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'] = $s0;
13445 }
13446 else {
13447 $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']);
13448 }
13449 if (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'])) {
13450 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'] = $s1;
13451 }
13452 else {
13453 $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']);
13454 }
13455 }
13456
13457 if ($this->tableLevel==1 && $this->useGraphs) {
13458 $this->graphs[$this->currentGraphId]['data'][$this->row][$this->col] = $e;
13459 }
13460 $this->nestedtablejustfinished = false;
13461 $this->linebreakjustfinished=false;
13462 }
13463 }
13464 /*-- END TABLES --*/
13465 }
13466 // ALL ELSE
13467 else {
13468 if ($this->ignorefollowingspaces and !$this->ispre) { $e = ltrim($e); }
13469 if ($e || $e==='0') $this->_saveTextBuffer($e, $this->HREF);
13470 }
13471 }
13472
13473
13474 else { // TAG **
13475
13476 if($e[0]=='/') {
13477 /*-- PROGRESS-BAR --*/
13478 if ($this->progressBar) { // 10% increments
13479 if (intval($i*10/$cnt) != $pbc) { $pbc = intval($i*10/$cnt); $this->UpdateProgressBar(1,$pbc*10,$tag); }
13480 }
13481 /*-- END PROGRESS-BAR --*/
13482
13483
13484 // Check for tags where HTML specifies optional end tags,
13485 // and/or does not allow nesting e.g. P inside P, or
13486 $endtag = trim(strtoupper(substr($e,1))); // mPDF 5.4.20
13487 if($this->blk[$this->blklvl]['hide']) {
13488 if (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags)) {
13489 unset($this->blk[$this->blklvl]);
13490 $this->blklvl--;
13491 }
13492 continue;
13493 }
13494
13495 /*-- CSS-POSITION --*/
13496 if ($this->inFixedPosBlock) {
13497 if (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags)) { $this->fixedPosBlockDepth--; }
13498 if ($this->fixedPosBlockDepth == 0) {
13499 $this->fixedPosBlockSave[] = array($this->fixedPosBlock, $this->fixedPosBlockBBox, $this->page);
13500 $this->fixedPosBlock = '';
13501 $this->inFixedPosBlock = false;
13502 continue;
13503 }
13504 $this->fixedPosBlock .= '<'.$e.'>';
13505 continue;
13506 }
13507 /*-- END CSS-POSITION --*/
13508 if ($this->allow_html_optional_endtags && !$parseonly) {
13509 if (($endtag == 'DIV' || $endtag =='FORM' || $endtag =='CENTER') && $this->lastoptionaltag == 'P') { $this->CloseTag($this->lastoptionaltag ); }
13510 if ($this->lastoptionaltag == 'LI' && $endtag == 'OL') { $this->CloseTag($this->lastoptionaltag ); }
13511 if ($this->lastoptionaltag == 'LI' && $endtag == 'UL') { $this->CloseTag($this->lastoptionaltag ); }
13512 if ($this->lastoptionaltag == 'DD' && $endtag == 'DL') { $this->CloseTag($this->lastoptionaltag ); }
13513 if ($this->lastoptionaltag == 'DT' && $endtag == 'DL') { $this->CloseTag($this->lastoptionaltag ); }
13514 if ($this->lastoptionaltag == 'OPTION' && $endtag == 'SELECT') { $this->CloseTag($this->lastoptionaltag ); }
13515 /*-- TABLES --*/
13516 if ($endtag == 'TABLE') {
13517 if ($this->lastoptionaltag == 'THEAD' || $this->lastoptionaltag == 'TBODY' || $this->lastoptionaltag == 'TFOOT') {
13518 $this->CloseTag($this->lastoptionaltag);
13519 }
13520 if ($this->lastoptionaltag == 'TR') { $this->CloseTag('TR'); }
13521 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); }
13522 }
13523 if ($endtag == 'THEAD' || $endtag == 'TBODY' || $endtag == 'TFOOT') {
13524 if ($this->lastoptionaltag == 'TR') { $this->CloseTag('TR'); }
13525 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); }
13526 }
13527 if ($endtag == 'TR') {
13528 if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); }
13529 }
13530 /*-- END TABLES --*/
13531 }
13532 $this->CloseTag($endtag);
13533 }
13534
13535 else { // OPENING TAG
13536 if($this->blk[$this->blklvl]['hide']) {
13537 if (strpos($e,' ')) { $te = strtoupper(substr($e,0,strpos($e,' '))); }
13538 else { $te = strtoupper($e); }
13539 if (in_array($te, $this->outerblocktags) || in_array($te, $this->innerblocktags)) {
13540 $this->blklvl++;
13541 $this->blk[$this->blklvl]['hide']=true;
13542 }
13543 continue;
13544 }
13545
13546 /*-- CSS-POSITION --*/
13547 if ($this->inFixedPosBlock) {
13548 if (strpos($e,' ')) { $te = strtoupper(substr($e,0,strpos($e,' '))); }
13549 else { $te = strtoupper($e); }
13550 $this->fixedPosBlock .= '<'.$e.'>';
13551 if (in_array($te, $this->outerblocktags) || in_array($te, $this->innerblocktags)) { $this->fixedPosBlockDepth++; }
13552 continue;
13553 }
13554 /*-- END CSS-POSITION --*/
13555 $regexp = '|=\'(.*?)\'|s'; // eliminate single quotes, if any
13556 $e = preg_replace($regexp,"=\"\$1\"",$e);
13557 // changes anykey=anyvalue to anykey="anyvalue" (only do this inside [some] tags)
13558 if (substr($e,0,10)!='pageheader' && substr($e,0,10)!='pagefooter' && substr($e,0,12)!='tocpagebreak') { // mPDF 5.6.69
13559 $regexp = '| (\\w+?)=([^\\s>"]+)|si';
13560 $e = preg_replace($regexp," \$1=\"\$2\"",$e);
13561 }
13562
13563 $e = preg_replace('/ (\\S+?)\s*=\s*"/i', " \\1=\"", $e);
13564
13565 //Fix path values, if needed
13566 $orig_srcpath = '';
13567 if ((stristr($e,"href=") !== false) or (stristr($e,"src=") !== false) ) {
13568 $regexp = '/ (href|src)\s*=\s*"(.*?)"/i';
13569 preg_match($regexp,$e,$auxiliararray);
13570 if (isset($auxiliararray[2])) { $path = $auxiliararray[2]; }
13571 else { $path = ''; }
13572 if (trim($path) != '' && !(stristr($e,"src=") !== false && substr($path,0,4)=='var:')) {
13573 $path=htmlspecialchars_decode($path); // mPDF 5.7.4 URLs
13574 $orig_srcpath = $path;
13575 $this->GetFullPath($path);
13576 $regexp = '/ (href|src)="(.*?)"/i';
13577 $e = preg_replace($regexp,' \\1="'.$path.'"',$e);
13578 }
13579 }//END of Fix path values
13580
13581
13582 //Extract attributes
13583 $contents=array();
13584 $contents1=array(); // mPDF 5.5.17
13585 $contents2=array();
13586 // Changed to allow style="background: url('bg.jpg')"
13587 // mPDF 5.5.17 Changed to improve performance; maximum length of \S (attribute) = 16
13588 // mPDF 5.6.30 Increase allowed attribute name to 32 - cutting off "toc-even-header-name" etc.
13589 preg_match_all('/\\S{1,32}=["][^"]*["]/',$e,$contents1);
13590 preg_match_all('/\\S{1,32}=[\'][^\']*[\']/i',$e,$contents2);
13591
13592 $contents = array_merge($contents1, $contents2);
13593 preg_match('/\\S+/',$e,$a2);
13594 $tag=strtoupper($a2[0]);
13595 $attr=array();
13596 if ($orig_srcpath) { $attr['ORIG_SRC'] = $orig_srcpath; }
13597 if (!empty($contents)) {
13598 foreach($contents[0] as $v) {
13599 // Changed to allow style="background: url('bg.jpg')"
13600 if(preg_match('/^([^=]*)=["]?([^"]*)["]?$/',$v,$a3) || preg_match('/^([^=]*)=[\']?([^\']*)[\']?$/',$v,$a3)) {
13601 if (strtoupper($a3[1])=='ID' || strtoupper($a3[1])=='CLASS') { // 4.2.013 Omits STYLE
13602 $attr[strtoupper($a3[1])]=trim(strtoupper($a3[2]));
13603 }
13604 // includes header-style-right etc. used for <pageheader>
13605 else if (preg_match('/^(HEADER|FOOTER)-STYLE/i',$a3[1])) {
13606 $attr[strtoupper($a3[1])]=trim(strtoupper($a3[2]));
13607 }
13608 else {
13609 $attr[strtoupper($a3[1])]=trim($a3[2]);
13610 }
13611 }
13612 }
13613 }
13614 $this->OpenTag($tag,$attr);
13615 /*-- CSS-POSITION --*/
13616 if ($this->inFixedPosBlock) {
13617 $this->fixedPosBlockBBox = array($tag,$attr, $this->x, $this->y);
13618 $this->fixedPosBlock = '';
13619 $this->fixedPosBlockDepth = 1;
13620 }
13621 /*-- END CSS-POSITION --*/
13622 // mPDF 5.5.09
13623 if (preg_match('/\/$/',$e)) { $this->closeTag($tag); }
13624
13625 }
13626
13627 } // end TAG
13628 } //end of foreach($a as $i=>$e)
13629
13630 if ($close) {
13631
13632 // Close any open block tags
13633 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
13634
13635 // Output any text left in buffer
13636 if (count($this->textbuffer) && !$parseonly) { $this->printbuffer($this->textbuffer); }
13637 if (!$parseonly) $this->textbuffer=array();
13638
13639 /*-- CSS-FLOAT --*/
13640 // If ended with a float, need to move to end page
13641 $currpos = $this->page*1000 + $this->y;
13642 if (isset($this->blk[$this->blklvl]['float_endpos']) && $this->blk[$this->blklvl]['float_endpos'] > $currpos) {
13643 $old_page = $this->page;
13644 $new_page = intval($this->blk[$this->blklvl]['float_endpos'] /1000);
13645 if ($old_page != $new_page) {
13646 $s = $this->PrintPageBackgrounds();
13647 // Writes after the marker so not overwritten later by page background etc.
13648 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
13649 $this->pageBackgrounds = array();
13650 $this->page = $new_page;
13651 $this->ResetMargins();
13652 $this->Reset();
13653 $this->pageoutput[$this->page] = array();
13654 }
13655 $this->y = (($this->blk[$this->blklvl]['float_endpos'] *1000) % 1000000)/1000; // mod changes operands to integers before processing
13656 }
13657 /*-- END CSS-FLOAT --*/
13658
13659 /*-- CSS-IMAGE-FLOAT --*/
13660 $this->printfloatbuffer();
13661 /*-- END CSS-IMAGE-FLOAT --*/
13662
13663 //Create Internal Links, if needed
13664 if (!empty($this->internallink) ) {
13665 foreach($this->internallink as $k=>$v) {
13666 if (strpos($k,"#") !== false ) { continue; } //ignore
13667 $ypos = $v['Y'];
13668 $pagenum = $v['PAGE'];
13669 $sharp = "#";
13670 while (array_key_exists($sharp.$k,$this->internallink)) {
13671 $internallink = $this->internallink[$sharp.$k];
13672 $this->SetLink($internallink,$ypos,$pagenum);
13673 $sharp .= "#";
13674 }
13675 }
13676 }
13677
13678 $this->linemaxfontsize = '';
13679 $this->lineheight_correction = $this->default_lineheight_correction;
13680
13681 $this->bufferoutput = false;
13682
13683 /*-- CSS-POSITION --*/
13684 if (count($this->fixedPosBlockSave) && $sub != 4) {
13685 foreach($this->fixedPosBlockSave AS $fpbs) {
13686 $old_page = $this->page;
13687 $this->page = $fpbs[2];
13688 $this->WriteFixedPosHTML($fpbs[0], 0, 0, 100, 100,'auto', $fpbs[1]); // 0,0,10,10 are overwritten by bbox
13689 $this->page = $old_page;
13690 }
13691 }
13692 /*-- END CSS-POSITION --*/
13693
13694 }
13695 }
13696
13697 /*-- CSS-POSITION --*/
13698
13699 function WriteFixedPosHTML($html='',$x, $y, $w, $h, $overflow='visible', $bounding=array()) {
13700 // $overflow can be 'hidden', 'visible' or 'auto' - 'auto' causes autofit to size
13701 // Annotations disabled - enabled in mPDF 5.0
13702 // Links do work
13703 // Will always go on current page (or start Page 1 if required)
13704 // Probably INCOMPATIBLE WITH keep with table, columns etc.
13705 // Called externally or interally via <div style="position: [fixed|absolute]">
13706 // When used internally, $x $y $w $h and $overflow are all overridden by $bounding
13707
13708 $overflow = strtolower($overflow);
13709 if($this->state==0) {
13710 $this->AddPage($this->CurOrientation);
13711 }
13712 $save_y = $this->y;
13713 $save_x = $this->x;
13714 $this->fullImageHeight = $this->h;
13715 $save_cols = false;
13716 /*-- COLUMNS --*/
13717 if ($this->ColActive) {
13718 $save_cols = true;
13719 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
13720 $this->SetColumns(0);
13721 }
13722 /*-- END COLUMNS --*/
13723 $save_annots = $this->title2annots; // *ANNOTATIONS*
13724 $this->writingHTMLheader = true; // a FIX to stop pagebreaks etc.
13725 $this->writingHTMLfooter = true;
13726 $this->InFooter = true; // suppresses autopagebreaks
13727 $save_bgs = $this->pageBackgrounds;
13728 $checkinnerhtml = preg_replace('/\s/','',$html);
13729
13730 if ($w > $this->w) { $x = 0; $w = $this->w; }
13731 if ($h > $this->h) { $y = 0; $h = $this->h; }
13732 if ($x > $this->w) { $x = $this->w - $w; }
13733 if ($y > $this->h) { $y = $this->h - $h; }
13734
13735 if (!empty($bounding)) {
13736 // $cont_ containing block = full physical page (position: absolute) or page inside margins (position: fixed)
13737 // $bbox_ Bounding box is the <div> which is positioned absolutely/fixed
13738 // top/left/right/bottom/width/height/background*/border*/padding*/margin* are taken from bounding
13739 // font*[family/size/style/weight]/line-height/text*[align/decoration/transform/indent]/color are transferred to $inner
13740 // as an enclosing <div> (after having checked ID/CLASS)
13741 // $x, $y, $w, $h are inside of $bbox_ = containing box for $inner_
13742 // $inner_ InnerHTML is the contents of that block to be output
13743 $tag = $bounding[0];
13744 $attr = $bounding[1];
13745 $orig_x0 = $bounding[2];
13746 $orig_y0 = $bounding[3];
13747
13748 // As in WriteHTML() initialising
13749 $this->blklvl = 0;
13750 $this->lastblocklevelchange = 0;
13751 $this->blk = array();
13752 $this->initialiseBlock($this->blk[0]);
13753
13754 $this->blk[0]['width'] =& $this->pgwidth;
13755 $this->blk[0]['inner_width'] =& $this->pgwidth;
13756
13757 $this->blk[0]['blockContext'] = $this->blockContext;
13758
13759 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
13760 $this->setCSS($properties,'','BODY');
13761 $this->blklvl = 1;
13762 $this->initialiseBlock($this->blk[1]);
13763 $this->blk[1]['tag'] = $tag;
13764 $this->blk[1]['attr'] = $attr;
13765 $this->Reset();
13766 $p = $this->cssmgr->MergeCSS('BLOCK',$tag,$attr);
13767 if (isset($p['ROTATE']) && ($p['ROTATE']==90 || $p['ROTATE']==-90)) { $rotate = $p['ROTATE']; }
13768 else { $rotate = 0; }
13769 if (isset($p['OVERFLOW'])) { $overflow = strtolower($p['OVERFLOW']); }
13770 if (strtolower($p['POSITION']) == 'fixed') {
13771 $cont_w = $this->pgwidth; // $this->blk[0]['inner_width'];
13772 $cont_h = $this->h - $this->tMargin - $this->bMargin;
13773 $cont_x = $this->lMargin;
13774 $cont_y = $this->tMargin;
13775 }
13776 else {
13777 $cont_w = $this->w; // ABSOLUTE;
13778 $cont_h = $this->h;
13779 $cont_x = 0;
13780 $cont_y = 0;
13781 }
13782
13783 // Pass on in-line properties to the innerhtml
13784 $css = '';
13785 if (isset($p['TEXT-ALIGN'])) { $css .= 'text-align: '.strtolower($p['TEXT-ALIGN']).'; '; }
13786 if (isset($p['TEXT-TRANSFORM'])) { $css .= 'text-transform: '.strtolower($p['TEXT-TRANSFORM']).'; '; }
13787 if (isset($p['TEXT-INDENT'])) { $css .= 'text-indent: '.strtolower($p['TEXT-INDENT']).'; '; }
13788 if (isset($p['TEXT-DECORATION'])) { $css .= 'text-decoration: '.strtolower($p['TEXT-DECORATION']).'; '; }
13789 if (isset($p['FONT-FAMILY'])) { $css .= 'font-family: '.strtolower($p['FONT-FAMILY']).'; '; }
13790 if (isset($p['FONT-STYLE'])) { $css .= 'font-style: '.strtolower($p['FONT-STYLE']).'; '; }
13791 if (isset($p['FONT-WEIGHT'])) { $css .= 'font-weight: '.strtolower($p['FONT-WEIGHT']).'; '; }
13792 if (isset($p['FONT-SIZE'])) { $css .= 'font-size: '.strtolower($p['FONT-SIZE']).'; '; }
13793 if (isset($p['LINE-HEIGHT'])) { $css .= 'line-height: '.strtolower($p['LINE-HEIGHT']).'; '; }
13794 if (isset($p['TEXT-SHADOW'])) { $css .= 'text-shadow: '.strtolower($p['TEXT-SHADOW']).'; '; }
13795 if (isset($p['LETTER-SPACING'])) { $css .= 'letter-spacing: '.strtolower($p['LETTER-SPACING']).'; '; }
13796 if (isset($p['FONT-VARIANT'])) { $css .= 'font-variant: '.strtolower($p['FONT-VARIANT']).'; '; }
13797 if (isset($p['COLOR'])) { $css .= 'color: '.strtolower($p['COLOR']).'; '; }
13798 if (isset($p['Z-INDEX'])) { $css .= 'z-index: '.$p['Z-INDEX'].'; '; } // mPDF 5.6.01
13799 if ($css) {
13800 $html = '<div style="'.$css.'">'.$html.'</div>';
13801 }
13802 // Copy over (only) the properties to set for border and background
13803 $pb = array();
13804 $pb['MARGIN-TOP'] = $p['MARGIN-TOP'];
13805 $pb['MARGIN-RIGHT'] = $p['MARGIN-RIGHT'];
13806 $pb['MARGIN-BOTTOM'] = $p['MARGIN-BOTTOM'];
13807 $pb['MARGIN-LEFT'] = $p['MARGIN-LEFT'];
13808 $pb['PADDING-TOP'] = $p['PADDING-TOP'];
13809 $pb['PADDING-RIGHT'] = $p['PADDING-RIGHT'];
13810 $pb['PADDING-BOTTOM'] = $p['PADDING-BOTTOM'];
13811 $pb['PADDING-LEFT'] = $p['PADDING-LEFT'];
13812 $pb['BORDER-TOP'] = $p['BORDER-TOP'];
13813 $pb['BORDER-RIGHT'] = $p['BORDER-RIGHT'];
13814 $pb['BORDER-BOTTOM'] = $p['BORDER-BOTTOM'];
13815 $pb['BORDER-LEFT'] = $p['BORDER-LEFT'];
13816 $pb['BORDER-TOP-LEFT-RADIUS-H'] = $p['BORDER-TOP-LEFT-RADIUS-H'];
13817 $pb['BORDER-TOP-LEFT-RADIUS-V'] = $p['BORDER-TOP-LEFT-RADIUS-V'];
13818 $pb['BORDER-TOP-RIGHT-RADIUS-H'] = $p['BORDER-TOP-RIGHT-RADIUS-H'];
13819 $pb['BORDER-TOP-RIGHT-RADIUS-V'] = $p['BORDER-TOP-RIGHT-RADIUS-V'];
13820 $pb['BORDER-BOTTOM-LEFT-RADIUS-H'] = $p['BORDER-BOTTOM-LEFT-RADIUS-H'];
13821 $pb['BORDER-BOTTOM-LEFT-RADIUS-V'] = $p['BORDER-BOTTOM-LEFT-RADIUS-V'];
13822 $pb['BORDER-BOTTOM-RIGHT-RADIUS-H'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-H'];
13823 $pb['BORDER-BOTTOM-RIGHT-RADIUS-V'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-V'];
13824 if (isset($p['BACKGROUND-COLOR'])) { $pb['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR']; }
13825 if (isset($p['BOX-SHADOW'])) { $pb['BOX-SHADOW'] = $p['BOX-SHADOW']; }
13826 /*-- BACKGROUNDS --*/
13827 if (isset($p['BACKGROUND-IMAGE'])) { $pb['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE']; }
13828 if (isset($p['BACKGROUND-IMAGE-RESIZE'])) { $pb['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE']; }
13829 if (isset($p['BACKGROUND-IMAGE-OPACITY'])) { $pb['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY']; }
13830 if (isset($p['BACKGROUND-REPEAT'])) { $pb['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT']; }
13831 if (isset($p['BACKGROUND-POSITION'])) { $pb['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION']; }
13832 if (isset($p['BACKGROUND-GRADIENT'])) { $pb['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT']; }
13833 if (isset($p['BACKGROUND-SIZE'])) { $pb['BACKGROUND-SIZE'] = $p['BACKGROUND-SIZE']; } // mPDF 5.6.12
13834 if (isset($p['BACKGROUND-ORIGIN'])) { $pb['BACKGROUND-ORIGIN'] = $p['BACKGROUND-ORIGIN']; } // mPDF 5.6.12
13835 if (isset($p['BACKGROUND-CLIP'])) { $pb['BACKGROUND-CLIP'] = $p['BACKGROUND-CLIP']; } // mPDF 5.6.12
13836
13837 /*-- END BACKGROUNDS --*/
13838
13839 $this->setCSS($pb,'BLOCK',$tag);
13840
13841 //================================================================
13842 $bbox_br = $this->blk[1]['border_right']['w'];
13843 $bbox_bl = $this->blk[1]['border_left']['w'];
13844 $bbox_bt = $this->blk[1]['border_top']['w'];
13845 $bbox_bb = $this->blk[1]['border_bottom']['w'];
13846 $bbox_pr = $this->blk[1]['padding_right'];
13847 $bbox_pl = $this->blk[1]['padding_left'];
13848 $bbox_pt = $this->blk[1]['padding_top'];
13849 $bbox_pb = $this->blk[1]['padding_bottom'];
13850 $bbox_mr = $this->blk[1]['margin_right'];
13851 if (strtolower($p['MARGIN-RIGHT'])=='auto') { $bbox_mr = 'auto'; }
13852 $bbox_ml = $this->blk[1]['margin_left'];
13853 if (strtolower($p['MARGIN-LEFT'])=='auto') { $bbox_ml = 'auto'; }
13854 $bbox_mt = $this->blk[1]['margin_top'];
13855 if (strtolower($p['MARGIN-TOP'])=='auto') { $bbox_mt = 'auto'; }
13856 $bbox_mb = $this->blk[1]['margin_bottom'];
13857 if (strtolower($p['MARGIN-BOTTOM'])=='auto') { $bbox_mb = 'auto'; }
13858 if (isset($p['LEFT']) && strtolower($p['LEFT'])!='auto') { $bbox_left = $this->ConvertSize($p['LEFT'], $cont_w, $this->FontSize,false); }
13859 else { $bbox_left = 'auto'; }
13860 if (isset($p['TOP']) && strtolower($p['TOP'])!='auto') { $bbox_top = $this->ConvertSize($p['TOP'], $cont_h, $this->FontSize,false); }
13861 else { $bbox_top = 'auto'; }
13862 if (isset($p['RIGHT']) && strtolower($p['RIGHT'])!='auto') { $bbox_right = $this->ConvertSize($p['RIGHT'], $cont_w, $this->FontSize,false); }
13863 else { $bbox_right = 'auto'; }
13864 if (isset($p['BOTTOM']) && strtolower($p['BOTTOM'])!='auto') { $bbox_bottom = $this->ConvertSize($p['BOTTOM'], $cont_h, $this->FontSize,false); }
13865 else { $bbox_bottom = 'auto'; }
13866 if (isset($p['WIDTH']) && strtolower($p['WIDTH'])!='auto') { $inner_w = $this->ConvertSize($p['WIDTH'], $cont_w, $this->FontSize,false); }
13867 else { $inner_w = 'auto'; }
13868 if (isset($p['HEIGHT']) && strtolower($p['HEIGHT'])!='auto') { $inner_h = $this->ConvertSize($p['HEIGHT'], $cont_h, $this->FontSize,false); }
13869 else { $inner_h = 'auto'; }
13870
13871 // If bottom or right pos are set and not left / top - save this to adjust rotated block later
13872 if ($rotate) {
13873 if ($bbox_left === 'auto' && $bbox_right !== 'auto') { $rot_rpos = $bbox_right; }
13874 else { $rot_rpos = false; }
13875 if ($bbox_top === 'auto' && $bbox_bottom !== 'auto') { $rot_bpos = $bbox_bottom; }
13876 else { $rot_bpos = false; }
13877 }
13878
13879 //================================================================
13880 if ($checkinnerhtml=='' && $inner_h==='auto') { $inner_h = 0.0001; }
13881 if ($checkinnerhtml=='' && $inner_w==='auto') { $inner_w = 2*$this->GetCharWidth('W',false); }
13882 //================================================================
13883 // Algorithm from CSS2.1 See http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height
13884 // mPD 5.3.14
13885 // Special case (not CSS) if all not specified, centre vertically on page
13886 if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom==='auto' && $bbox_mt==='auto' && $bbox_mb==='auto') {
13887 $bbox_top_orig = $bbox_top;
13888 if ($bbox_mt==='auto') { $bbox_mt = 0; }
13889 if ($bbox_mb==='auto') { $bbox_mb = 0; }
13890 $bbox_top = $orig_y0 - $bbox_mt - $cont_y;
13891 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13892 }
13893 // mPD 5.3.14
13894 else if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom==='auto') {
13895 $bbox_top_orig = $bbox_top = $orig_y0 - $cont_y;
13896 if ($bbox_mt==='auto') { $bbox_mt = 0; }
13897 if ($bbox_mb==='auto') { $bbox_mb = 0; }
13898 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13899 }
13900 else if ($bbox_top!=='auto' && $inner_h!=='auto' && $bbox_bottom!=='auto') {
13901 if ($bbox_mt==='auto' && $bbox_mb==='auto') {
13902 $x = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
13903 $bbox_mt = $bbox_mb = ($x/2);
13904 }
13905 else if ($bbox_mt==='auto') {
13906 $bbox_mt = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
13907 }
13908 else if ($bbox_mb==='auto') {
13909 $bbox_mb = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
13910 }
13911 else {
13912 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13913 }
13914 }
13915 else {
13916 if ($bbox_mt==='auto') { $bbox_mt = 0; }
13917 if ($bbox_mb==='auto') { $bbox_mb = 0; }
13918 if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom!=='auto') {
13919 // solve for $bbox_top when content_h known - $inner_h=='auto' && $bbox_top =='auto'
13920 }
13921 else if ($bbox_top==='auto' && $bbox_bottom==='auto' && $inner_h!=='auto') {
13922 $bbox_top = $orig_y0 - $bbox_mt - $cont_y;
13923 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13924 }
13925 else if ($inner_h==='auto' && $bbox_bottom==='auto' && $bbox_top!=='auto') {
13926 // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
13927 }
13928 else if ($bbox_top==='auto' && $inner_h!=='auto' && $bbox_bottom!=='auto') {
13929 $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
13930 }
13931 else if ($inner_h==='auto' && $bbox_top!=='auto' && $bbox_bottom!=='auto') {
13932 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
13933 }
13934 else if ($bbox_bottom==='auto' && $bbox_top!=='auto' && $inner_h!=='auto') {
13935 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
13936 }
13937 }
13938
13939 // THEN DO SAME FOR WIDTH
13940 // http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
13941 if ($bbox_left==='auto' && $inner_w==='auto' && $bbox_right==='auto') {
13942 if ($bbox_ml==='auto') { $bbox_ml = 0; }
13943 if ($bbox_mr==='auto') { $bbox_mr = 0; }
13944 // IF containing element RTL, should set $bbox_right
13945 $bbox_left = $orig_x0 - $bbox_ml - $cont_x;
13946 // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
13947 }
13948 else if ($bbox_left!=='auto' && $inner_w!=='auto' && $bbox_right!=='auto') {
13949 if ($bbox_ml==='auto' && $bbox_mr==='auto') {
13950 $x = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
13951 $bbox_ml = $bbox_mr = ($x/2);
13952 }
13953 else if ($bbox_ml==='auto') {
13954 $bbox_ml = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
13955 }
13956 else if ($bbox_mr==='auto') {
13957 $bbox_mr = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
13958 }
13959 else {
13960 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13961 }
13962 }
13963 else {
13964 if ($bbox_ml==='auto') { $bbox_ml = 0; }
13965 if ($bbox_mr==='auto') { $bbox_mr = 0; }
13966 if ($bbox_left==='auto' && $inner_w==='auto' && $bbox_right!=='auto') {
13967 // solve for $bbox_left when content_w known - $inner_w=='auto' && $bbox_left =='auto'
13968 }
13969 else if ($bbox_left==='auto' && $bbox_right==='auto' && $inner_w!=='auto') {
13970 // IF containing element RTL, should set $bbox_right
13971 $bbox_left = $orig_x0 - $bbox_ml - $cont_x;
13972 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13973 }
13974 else if ($inner_w==='auto' && $bbox_right==='auto' && $bbox_left!=='auto') {
13975 // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
13976 }
13977 else if ($bbox_left==='auto' && $inner_w!=='auto' && $bbox_right!=='auto') {
13978 $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
13979 }
13980 else if ($inner_w==='auto' && $bbox_left!=='auto' && $bbox_right!=='auto') {
13981 $inner_w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
13982 }
13983 else if ($bbox_right==='auto' && $bbox_left!=='auto' && $inner_w!=='auto') {
13984 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
13985 }
13986 }
13987
13988 //================================================================
13989 //================================================================
13990 /*-- BACKGROUNDS --*/
13991 if (isset($pb['BACKGROUND-IMAGE']) && $pb['BACKGROUND-IMAGE']) {
13992 $ret = $this->SetBackground($pb, $this->blk[1]['inner_width']);
13993 if ($ret) { $this->blk[1]['background-image'] = $ret; }
13994 }
13995 /*-- END BACKGROUNDS --*/
13996
13997 //================================================================
13998 $y = $cont_y + $bbox_top + $bbox_mt + $bbox_bt + $bbox_pt;
13999 $h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
14000 $x = $cont_x + $bbox_left + $bbox_ml + $bbox_bl + $bbox_pl;
14001 $w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
14002 // Set (temporary) values for x y w h to do first paint, if values are auto
14003 if ($inner_h==='auto' && $bbox_top==='auto') {
14004 $y = $cont_y + $bbox_mt + $bbox_bt + $bbox_pt;
14005 $h = $cont_h - ($bbox_bottom + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb);
14006 }
14007 else if ($inner_h==='auto' && $bbox_bottom==='auto') {
14008 $y = $cont_y + $bbox_top + $bbox_mt + $bbox_bt + $bbox_pt;
14009 $h = $cont_h - ($bbox_top + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb);
14010 }
14011 if ($inner_w==='auto' && $bbox_left==='auto') {
14012 $x = $cont_x + $bbox_ml + $bbox_bl + $bbox_pl;
14013 $w = $cont_w - ($bbox_right + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr);
14014 }
14015 else if ($inner_w==='auto' && $bbox_right==='auto') {
14016 $x = $cont_x + $bbox_left + $bbox_ml + $bbox_bl + $bbox_pl;
14017 $w = $cont_w - ($bbox_left + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr);
14018 }
14019 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
14020 $bbox_x = $cont_x + $bbox_left + $bbox_ml;
14021 $saved_block1 = $this->blk[1];
14022 unset($p);
14023 unset($pb);
14024 //================================================================
14025 if ($inner_w==='auto') { // do a first write
14026 $this->lMargin=$x;
14027 $this->rMargin=$this->w - $w - $x;
14028 // SET POSITION & FONT VALUES
14029 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
14030 $this->pageoutput[$this->page]=array();
14031 $this->x = $x;
14032 $this->y = $y;
14033 $this->HTMLheaderPageLinks = array();
14034 $this->HTMLheaderPageAnnots = array();
14035 $this->HTMLheaderPageForms = array();
14036 $this->pageBackgrounds = array();
14037 $this->maxPosR = 0;
14038 $this->maxPosL = $this->w; // For RTL
14039 $this->WriteHTML($html , 4);
14040 $inner_w = $this->maxPosR - $this->lMargin;
14041 if ($bbox_right==='auto') {
14042 $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
14043 }
14044 else if ($bbox_left==='auto') {
14045 $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
14046 $bbox_x = $cont_x + $bbox_left + $bbox_ml ;
14047 $inner_x = $bbox_x + $bbox_bl + $bbox_pl;
14048 $x = $inner_x;
14049 }
14050 $w = $inner_w;
14051 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
14052 $bbox_x = $cont_x + $bbox_left + $bbox_ml;
14053 }
14054
14055 if ($inner_h==='auto') { // do a first write
14056 $this->lMargin=$x;
14057 $this->rMargin=$this->w - $w - $x;
14058 // SET POSITION & FONT VALUES
14059 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
14060 $this->pageoutput[$this->page]=array();
14061 $this->x = $x;
14062 $this->y = $y;
14063 $this->HTMLheaderPageLinks = array();
14064 $this->HTMLheaderPageAnnots = array();
14065 $this->HTMLheaderPageForms = array();
14066 $this->pageBackgrounds = array();
14067 $this->WriteHTML($html , 4);
14068 $inner_h = $this->y - $y;
14069 if ($overflow!='hidden' && $overflow!='visible') { // constrained
14070 if (($this->y + $bbox_pb + $bbox_bb) > ($cont_y + $cont_h)) {
14071 $adj = ($this->y + $bbox_pb + $bbox_bb) - ($cont_y + $cont_h);
14072 $inner_h -= $adj;
14073 }
14074 }
14075 if ($bbox_bottom==='auto' && $bbox_top_orig==='auto') {
14076 $bbox_bottom = $bbox_top = ($cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb)/2;
14077 if ($overflow!='hidden' && $overflow!='visible') { // constrained
14078 if ($bbox_top < 0) {
14079 $bbox_top = 0;
14080 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
14081 }
14082 }
14083 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
14084 $inner_y = $bbox_y + $bbox_bt + $bbox_pt;
14085 $y = $inner_y;
14086
14087 }
14088 else if ($bbox_bottom==='auto') {
14089 $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb;
14090 }
14091 else if ($bbox_top==='auto') {
14092 $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
14093 if ($overflow!='hidden' && $overflow!='visible') { // constrained
14094 if ($bbox_top < 0) {
14095 $bbox_top = 0;
14096 $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
14097 }
14098 }
14099 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
14100 $inner_y = $bbox_y + $bbox_bt + $bbox_pt;
14101 $y = $inner_y;
14102 }
14103 $h = $inner_h;
14104 $bbox_y = $cont_y + $bbox_top + $bbox_mt;
14105 $bbox_x = $cont_x + $bbox_left + $bbox_ml;
14106 }
14107 $inner_w = $w;
14108 $inner_h = $h;
14109
14110 }
14111 $this->lMargin=$x;
14112 $this->rMargin=$this->w - $w - $x;
14113 // SET POSITION & FONT VALUES
14114 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
14115 $this->pageoutput[$this->page]=array();
14116 $this->x = $x;
14117 $this->y = $y;
14118 $this->HTMLheaderPageLinks = array();
14119 $this->HTMLheaderPageAnnots = array();
14120 $this->HTMLheaderPageForms = array();
14121 $this->pageBackgrounds = array();
14122 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
14123 $actual_h = $this->y - $y;
14124 $use_w = $w;
14125 $use_h = $h;
14126 $ratio = $actual_h / $use_w;
14127
14128 if ($overflow!='hidden' && $overflow!='visible') {
14129 $target = $h/$w;
14130 if (($ratio / $target ) > 1) {
14131 $nl = CEIL($actual_h / $this->lineheight);
14132 $l = $use_w * $nl;
14133 $est_w = sqrt(($l * $this->lineheight) / $target) * 0.8;
14134 $use_w += ($est_w - $use_w) - ($w/100);
14135 }
14136 $bpcstart = ($ratio / $target);
14137 $bpcctr = 1;
14138 while(($ratio / $target ) > 1) {
14139
14140 if ($this->progressBar) { $this->UpdateProgressBar(4,intval(100/($ratio/$target)),('Auto-sizing fixed-position block: '.$bpcctr++)); } // *PROGRESS-BAR*
14141
14142 $this->x = $x;
14143 $this->y = $y;
14144
14145 if (($ratio / $target) > 1.5 || ($ratio / $target) < 0.6) {
14146 $use_w += ($w/$this->incrementFPR1);
14147 }
14148 else if (($ratio / $target) > 1.2 || ($ratio / $target) < 0.85) {
14149 $use_w += ($w/$this->incrementFPR2);
14150 }
14151 else if (($ratio / $target) > 1.1 || ($ratio / $target) < 0.91) {
14152 $use_w += ($w/$this->incrementFPR3);
14153 }
14154 else {
14155 $use_w += ($w/$this->incrementFPR4);
14156 }
14157
14158 $use_h = $use_w * $target ;
14159 $this->rMargin=$this->w - $use_w - $x;
14160 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
14161 $this->HTMLheaderPageLinks = array();
14162 $this->HTMLheaderPageAnnots = array();
14163 $this->HTMLheaderPageForms = array();
14164 $this->pageBackgrounds = array();
14165 $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
14166 $actual_h = $this->y - $y;
14167 $ratio = $actual_h / $use_w;
14168 }
14169 if ($this->progressBar) { $this->UpdateProgressBar(4,'100',' '); } // *PROGRESS-BAR*
14170 }
14171 $shrink_f = $w/$use_w;
14172
14173 //================================================================
14174
14175 $this->pages[$this->page] .= '___BEFORE_BORDERS___';
14176 $block_s = $this->PrintPageBackgrounds(); // Save to print later inside clipping path
14177 $this->pageBackgrounds = array();
14178
14179 //================================================================
14180
14181 if ($rotate) {
14182 $prerotw = $bbox_bl + $bbox_pl + $inner_w + $bbox_pr + $bbox_br;
14183 $preroth = $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb;
14184 $rot_start = " q\n";
14185 if ($rotate == 90) {
14186 if ($rot_rpos !== false) { $adjw = $prerotw; } // width before rotation
14187 else { $adjw = $preroth; } // height before rotation
14188 if ($rot_bpos !== false) { $adjh = -$prerotw + $preroth; }
14189 else { $adjh = 0; }
14190 }
14191 else {
14192 if ($rot_rpos !== false) { $adjw = $prerotw - $preroth; }
14193 else { $adjw = 0; }
14194 if ($rot_bpos !== false) { $adjh = $preroth; } // height before rotation
14195 else { $adjh = $prerotw; } // width before rotation
14196 }
14197 $rot_start .= $this->transformTranslate($adjw, $adjh, true)."\n";
14198 $rot_start .= $this->transformRotate($rotate, $bbox_x, $bbox_y, true)."\n";
14199 $rot_end = " Q\n";
14200 }
14201 else {
14202 $rot_start = '';
14203 $rot_end = '';
14204 }
14205
14206 //================================================================
14207 if (!empty($bounding)) {
14208 // WHEN HEIGHT // BOTTOM EDGE IS KNOWN and $this->y is set to the bottom
14209 // Re-instate saved $this->blk[1]
14210 $this->blk[1] = $saved_block1;
14211
14212 // These are only needed when painting border/background
14213 $this->blk[1]['width'] = $bbox_w = $cont_w - $bbox_left - $bbox_ml - $bbox_mr - $bbox_right;
14214 $this->blk[1]['x0'] = $bbox_x;
14215 $this->blk[1]['y0'] = $bbox_y;
14216 $this->blk[1]['startpage'] = $this->page;
14217 $this->blk[1]['y1'] = $bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb ;
14218 $this->_out($rot_start); // mPDF 5.0
14219 $this->PaintDivBB('',0,1); // Prints borders and sets backgrounds in $this->pageBackgrounds
14220 $this->_out($rot_end);
14221 }
14222
14223 $s = $this->PrintPageBackgrounds();
14224 $s = $rot_start.$s.$rot_end;
14225 $this->pages[$this->page] = preg_replace('/___BEFORE_BORDERS___/', "\n".$s."\n", $this->pages[$this->page]);
14226 $this->pageBackgrounds = array();
14227
14228 $this->_out($rot_start);
14229
14230 // Clipping Output
14231 if ($overflow=='hidden') {
14232 //Bounding rectangle to clip
14233 $clip_y1 = $this->y;
14234 if (!empty($bounding) && ($this->y + $bbox_pb + $bbox_bb) > ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb )) {
14235 $clip_y1 = ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb ) - ($bbox_pb + $bbox_bb);
14236 }
14237 //$op = 'W* n'; // Clipping
14238 $op = 'W n'; // Clipping alternative mode
14239 $this->_out("q");
14240 $ch = $clip_y1 - $y;
14241 $this->_out(sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$ch*_MPDFK,$op));
14242 if (!empty($block_s)) {
14243 $tmp = "q\n".sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$ch*_MPDFK,$op);
14244 $tmp .= "\n".$block_s."\nQ";
14245 $block_s = $tmp ;
14246 }
14247 }
14248
14249
14250 if (!empty($block_s)) {
14251 if ($shrink_f != 1) { // i.e. autofit has resized the box
14252 $tmp = "q\n".$this->transformScale(($shrink_f*100),($shrink_f*100), $x, $y, true);
14253 $tmp .= "\n".$block_s."\nQ";
14254 $block_s = $tmp ;
14255 }
14256 $this->_out($block_s);
14257 }
14258
14259
14260
14261 if ($shrink_f != 1) { // i.e. autofit has resized the box
14262 $this->StartTransform();
14263 $this->transformScale(($shrink_f*100),($shrink_f*100), $x, $y);
14264 }
14265
14266 $this->_out($this->headerbuffer);
14267
14268 if ($shrink_f != 1) { // i.e. autofit has resized the box
14269 $this->StopTransform();
14270 }
14271
14272 if ($overflow=='hidden') {
14273 //End clipping
14274 $this->_out("Q");
14275 }
14276
14277 $this->_out($rot_end);
14278
14279
14280 // Page Links
14281 foreach($this->HTMLheaderPageLinks AS $lk) {
14282 if ($rotate) {
14283 $tmp = $lk[2]; // Switch h - w
14284 $lk[2] = $lk[3];
14285 $lk[3] = $tmp;
14286
14287 $lx1 = (($lk[0]/_MPDFK));
14288 $ly1 = (($this->h-($lk[1]/_MPDFK)));
14289 if ($rotate == 90) {
14290 $adjx = -($lx1-$bbox_x) + ($preroth - ($ly1-$bbox_y));
14291 $adjy = -($ly1-$bbox_y) + ($lx1-$bbox_x);
14292 $lk[2] = -$lk[2];
14293 }
14294 else if ($rotate == -90) {
14295 $adjx = -($lx1-$bbox_x) + ($ly1-$bbox_y);
14296 $adjy = -($ly1-$bbox_y) - ($lx1-$bbox_x) + $prerotw;
14297 $lk[3] = -$lk[3];
14298 }
14299 if ($rot_rpos !== false) { $adjx += $prerotw - $preroth; }
14300 if ($rot_bpos !== false) { $adjy += $preroth - $prerotw; }
14301 $lx1 += $adjx;
14302 $ly1 += $adjy;
14303
14304 $lk[0] = $lx1*_MPDFK;
14305 $lk[1] = ($this->h-$ly1)*_MPDFK;
14306 }
14307 if ($shrink_f != 1) { // i.e. autofit has resized the box
14308 $lx1 = (($lk[0]/_MPDFK)-$x);
14309 $lx2 = $x + ($lx1 * $shrink_f);
14310 $lk[0] = $lx2*_MPDFK;
14311 $ly1 = (($this->h-($lk[1]/_MPDFK))-$y);
14312 $ly2 = $y + ($ly1 * $shrink_f);
14313 $lk[1] = ($this->h-$ly2)*_MPDFK;
14314 $lk[2] *= $shrink_f; // width
14315 $lk[3] *= $shrink_f; // height
14316 }
14317 $this->PageLinks[$this->page][]=$lk;
14318 }
14319
14320 foreach($this->HTMLheaderPageForms AS $n=>$f) {
14321 if ($shrink_f != 1) { // i.e. autofit has resized the box
14322 $f['x'] = $x + (($f['x'] -$x) * $shrink_f);
14323 $f['y'] = $y + (($f['y'] -$y) * $shrink_f);
14324 $f['w'] *= $shrink_f;
14325 $f['h'] *= $shrink_f;
14326 $f['style']['fontsize'] *= $shrink_f;
14327 }
14328 $this->form->forms[$f['n']] = $f;
14329 }
14330 // Page Annotations
14331 foreach($this->HTMLheaderPageAnnots AS $lk) {
14332 if ($rotate) {
14333 if ($rotate == 90) {
14334 $adjx = -($lk['x']-$bbox_x) + ($preroth - ($lk['y']-$bbox_y));
14335 $adjy = -($lk['y']-$bbox_y) + ($lk['x']-$bbox_x);
14336 }
14337 else if ($rotate == -90) {
14338 $adjx = -($lk['x']-$bbox_x) + ($lk['y']-$bbox_y);
14339 $adjy = -($lk['y']-$bbox_y) - ($lk['x']-$bbox_x) + $prerotw;
14340 }
14341 if ($rot_rpos !== false) { $adjx += $prerotw - $preroth; }
14342 if ($rot_bpos !== false) { $adjy += $preroth - $prerotw; }
14343 $lk['x'] += $adjx;
14344 $lk['y'] += $adjy;
14345 }
14346 if ($shrink_f != 1) { // i.e. autofit has resized the box
14347 $lk['x'] = $x + (($lk['x']-$x) * $shrink_f);
14348 $lk['y'] = $y + (($lk['y']-$y) * $shrink_f);
14349 }
14350 $this->PageAnnots[$this->page][]=$lk;
14351 }
14352
14353 // Restore
14354 $this->headerbuffer = '';
14355 $this->HTMLheaderPageLinks = array();
14356 $this->HTMLheaderPageAnnots = array();
14357 $this->HTMLheaderPageForms = array();
14358 $this->pageBackgrounds = $save_bgs;
14359 $this->writingHTMLheader = false;
14360
14361 $this->writingHTMLfooter = false;
14362 $this->fullImageHeight = false;
14363 $this->ResetMargins();
14364 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
14365 $this->SetXY($save_x,$save_y) ;
14366 $this->title2annots = $save_annots; // *ANNOTATIONS*
14367 $this->InFooter = false; // turns back on autopagebreaks
14368 $this->pageoutput[$this->page]=array();
14369 $this->pageoutput[$this->page]['Font']='';
14370 /*-- COLUMNS --*/
14371 if ($save_cols) {
14372 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
14373 }
14374 /*-- END COLUMNS --*/
14375 }
14376 /*-- END CSS-POSITION --*/
14377
14378
14379
14380 function initialiseBlock(&$blk) {
14381 $blk['margin_top'] = 0;
14382 $blk['margin_left'] = 0;
14383 $blk['margin_bottom'] = 0;
14384 $blk['margin_right'] = 0;
14385 $blk['padding_top'] = 0;
14386 $blk['padding_left'] = 0;
14387 $blk['padding_bottom'] = 0;
14388 $blk['padding_right'] = 0;
14389 $blk['border_top']['w'] = 0;
14390 $blk['border_left']['w'] = 0;
14391 $blk['border_bottom']['w'] = 0;
14392 $blk['border_right']['w'] = 0;
14393 $blk['hide'] = false;
14394 $blk['outer_left_margin'] = 0;
14395 $blk['outer_right_margin'] = 0;
14396 $blk['cascadeCSS'] = array();
14397 $blk['block-align'] = false;
14398 $blk['bgcolor'] = false;
14399 $blk['page_break_after_avoid'] = false;
14400 $blk['keep_block_together'] = false;
14401 $blk['float'] = false;
14402 $blk['line_height'] = '';
14403 $blk['margin_collapse'] = false;
14404 }
14405
14406
14407 function border_details($bd) {
14408 $prop = preg_split('/\s+/',trim($bd));
14409
14410 if (isset($this->blk[$this->blklvl]['inner_width'])) { $refw = $this->blk[$this->blklvl]['inner_width']; }
14411 else if (isset($this->blk[$this->blklvl-1]['inner_width'])) { $refw = $this->blk[$this->blklvl-1]['inner_width']; }
14412 else { $refw = $this->w; }
14413 if ( count($prop) == 1 ) {
14414 $bsize = $this->ConvertSize($prop[0],$refw,$this->FontSize,false);
14415 if ($bsize > 0) {
14416 return array('s' => 1, 'w' => $bsize, 'c' => $this->ConvertColor(0), 'style'=>'solid');
14417 }
14418 else { return array('w' => 0, 's' => 0); }
14419 }
14420
14421 else if (count($prop) == 2 ) {
14422 // 1px solid
14423 if (in_array($prop[1],$this->borderstyles) || $prop[1] == 'none' || $prop[1] == 'hidden' ) { $prop[2] = ''; }
14424 // solid #000000
14425 else if (in_array($prop[0],$this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden' ) { $prop[0] = ''; $prop[1] = $prop[0]; $prop[2] = $prop[1]; }
14426 // 1px #000000
14427 else { $prop[1] = ''; $prop[2] = $prop[1]; }
14428 }
14429 else if ( count($prop) == 3 ) {
14430 // Change #000000 1px solid to 1px solid #000000 (proper)
14431 if (substr($prop[0],0,1) == '#') { $tmp = $prop[0]; $prop[0] = $prop[1]; $prop[1] = $prop[2]; $prop[2] = $tmp; }
14432 // Change solid #000000 1px to 1px solid #000000 (proper)
14433 else if (substr($prop[0],1,1) == '#') { $tmp = $prop[1]; $prop[0] = $prop[2]; $prop[1] = $prop[0]; $prop[2] = $tmp; }
14434 // Change solid 1px #000000 to 1px solid #000000 (proper)
14435 else if (in_array($prop[0],$this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden' ) {
14436 $tmp = $prop[0]; $prop[0] = $prop[1]; $prop[1] = $tmp;
14437 }
14438 }
14439 else { return array(); }
14440 // Size
14441 $bsize = $this->ConvertSize($prop[0],$refw,$this->FontSize,false);
14442 //color
14443 $coul = $this->ConvertColor($prop[2]); // returns array
14444 // Style
14445 $prop[1] = strtolower($prop[1]);
14446 if (in_array($prop[1],$this->borderstyles) && $bsize > 0) { $on = 1; }
14447 else if ($prop[1] == 'hidden') { $on = 1; $bsize = 0; $coul = ''; }
14448 else if ($prop[1] == 'none') { $on = 0; $bsize = 0; $coul = ''; }
14449 else { $on = 0; $bsize = 0; $coul = ''; $prop[1] = ''; }
14450 return array('s' => $on, 'w' => $bsize, 'c' => $coul, 'style'=> $prop[1] );
14451 }
14452
14453
14454
14455 /*-- END HTML-CSS --*/
14456
14457
14458 // Return either a number (factor) - based on current set fontsize (if % or em) - or exact lineheight (with 'mm' after it)
14459 function fixLineheight($v) {
14460 $lh = false;
14461 if (preg_match('/^[0-9\.,]*$/',$v) && $v >= 0) { return ($v + 0); }
14462 else if (strtoupper($v) == 'NORMAL') {
14463 return $this->normalLineheight;
14464 }
14465 else {
14466 $tlh = $this->ConvertSize($v,$this->FontSize,$this->FontSize,true);
14467 if ($tlh) { return ($tlh.'mm'); }
14468 }
14469 return $this->normalLineheight;
14470 }
14471
14472
14473 /*-- BORDER-RADIUS --*/
14474 function _borderPadding($a, $b, &$px, &$py) {
14475 // $px and py are padding long axis (x) and short axis (y)
14476 $added = 0; // extra padding
14477
14478 $x = $a-$px;
14479 $y = $b-$py;
14480 // Check if Falls within ellipse of border radius
14481 if ( ( (($x+$added)*($x+$added))/($a*$a) + (($y+$added)*($y+$added))/($b*$b) ) <=1 ) { return false; }
14482
14483 $t = atan2($y,$x);
14484
14485 $newx = $b / sqrt((($b*$b)/($a*$a)) + ( tan($t) * tan($t) ) );
14486 $newy = $a / sqrt((($a*$a)/($b*$b)) + ( (1/tan($t)) * (1/tan($t)) ) );
14487 $px = max($px, $a - $newx + $added);
14488 $py = max($py, $b - $newy + $added);
14489 }
14490 /*-- END BORDER-RADIUS --*/
14491
14492
14493
14494 /*-- HTML-CSS --*/
14495
14496
14497 /*-- CSS-PAGE --*/
14498 function SetPagedMediaCSS($name='', $first, $oddEven) {
14499 if ($oddEven == 'E') {
14500 if ($this->directionality=='rtl') { $side = 'R'; }
14501 else { $side = 'L'; }
14502 }
14503 else {
14504 if ($this->directionality=='rtl') { $side = 'L'; }
14505 else { $side = 'R'; }
14506 }
14507 $name = strtoupper($name);
14508 $p = array();
14509 $p['SIZE'] = 'AUTO';
14510
14511 // Uses mPDF original margins as default
14512 $p['MARGIN-RIGHT'] = strval($this->orig_rMargin).'mm';
14513 $p['MARGIN-LEFT'] = strval($this->orig_lMargin).'mm';
14514 $p['MARGIN-TOP'] = strval($this->orig_tMargin).'mm';
14515 $p['MARGIN-BOTTOM'] = strval($this->orig_bMargin).'mm';
14516 $p['MARGIN-HEADER'] = strval($this->orig_hMargin).'mm';
14517 $p['MARGIN-FOOTER'] = strval($this->orig_fMargin).'mm';
14518
14519 // Basic page + selector
14520 if (isset($this->cssmgr->CSS['@PAGE'])) { $zp = $this->cssmgr->CSS['@PAGE']; }
14521 else { $zp = array(); }
14522 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14523
14524 if (isset($p['EVEN-HEADER-NAME']) && $oddEven=='E') {
14525 $p['HEADER'] = $p['EVEN-HEADER-NAME']; unset($p['EVEN-HEADER-NAME']);
14526 }
14527 if (isset($p['ODD-HEADER-NAME']) && $oddEven!='E') {
14528 $p['HEADER'] = $p['ODD-HEADER-NAME']; unset($p['ODD-HEADER-NAME']);
14529 }
14530 if (isset($p['EVEN-FOOTER-NAME']) && $oddEven=='E') {
14531 $p['FOOTER'] = $p['EVEN-FOOTER-NAME']; unset($p['EVEN-FOOTER-NAME']);
14532 }
14533 if (isset($p['ODD-FOOTER-NAME']) && $oddEven!='E') {
14534 $p['FOOTER'] = $p['ODD-FOOTER-NAME']; unset($p['ODD-FOOTER-NAME']);
14535 }
14536
14537 // If right/Odd page
14538 if (isset($this->cssmgr->CSS['@PAGE>>PSEUDO>>RIGHT']) && $side=='R') {
14539 $zp = $this->cssmgr->CSS['@PAGE>>PSEUDO>>RIGHT'];
14540 }
14541 else { $zp = array(); }
14542 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14543 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14544 // Disallow margin-left or -right on :LEFT or :RIGHT
14545 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14546 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14547 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14548
14549 // If left/Even page
14550 if (isset($this->cssmgr->CSS['@PAGE>>PSEUDO>>LEFT']) && $side=='L') {
14551 $zp = $this->cssmgr->CSS['@PAGE>>PSEUDO>>LEFT'];
14552 }
14553 else { $zp = array(); }
14554 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14555 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14556 // Disallow margin-left or -right on :LEFT or :RIGHT
14557 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14558 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14559 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14560
14561 // If first page
14562 if (isset($this->cssmgr->CSS['@PAGE>>PSEUDO>>FIRST']) && $first) { $zp = $this->cssmgr->CSS['@PAGE>>PSEUDO>>FIRST']; }
14563 else { $zp = array(); }
14564 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14565 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14566 // Disallow margin-left or -right on :FIRST // mPDF 5.7.3
14567 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14568 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14569 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14570
14571 // If named page
14572 if ($name) {
14573 if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name])) { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name]; }
14574 else { $zp = array(); }
14575 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14576
14577 if (isset($p['EVEN-HEADER-NAME']) && $oddEven=='E') {
14578 $p['HEADER'] = $p['EVEN-HEADER-NAME']; unset($p['EVEN-HEADER-NAME']);
14579 }
14580 if (isset($p['ODD-HEADER-NAME']) && $oddEven!='E') {
14581 $p['HEADER'] = $p['ODD-HEADER-NAME']; unset($p['ODD-HEADER-NAME']);
14582 }
14583 if (isset($p['EVEN-FOOTER-NAME']) && $oddEven=='E') {
14584 $p['FOOTER'] = $p['EVEN-FOOTER-NAME']; unset($p['EVEN-FOOTER-NAME']);
14585 }
14586 if (isset($p['ODD-FOOTER-NAME']) && $oddEven!='E') {
14587 $p['FOOTER'] = $p['ODD-FOOTER-NAME']; unset($p['ODD-FOOTER-NAME']);
14588 }
14589
14590 // If named right/Odd page
14591 if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>RIGHT']) && $side=='R') { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>RIGHT']; }
14592 else { $zp = array(); }
14593 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14594 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14595 // Disallow margin-left or -right on :LEFT or :RIGHT
14596 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14597 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14598 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14599
14600 // If named left/Even page
14601 if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>LEFT']) && $side=='L') { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>LEFT']; }
14602 else { $zp = array(); }
14603 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14604 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14605 // Disallow margin-left or -right on :LEFT or :RIGHT
14606 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14607 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14608 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14609
14610 // If named first page
14611 if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>FIRST']) && $first) { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>FIRST']; }
14612 else { $zp = array(); }
14613 if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
14614 if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
14615 // Disallow margin-left or -right on :FIRST // mPDF 5.7.3
14616 if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
14617 if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
14618 if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
14619 }
14620
14621 $orientation = $mgl = $mgr = $mgt = $mgb = $mgh = $mgf = '';
14622 $header = $footer = '';
14623 $resetpagenum = $pagenumstyle = $suppress = '';
14624 $marks = '';
14625 $bg = array();
14626
14627 $newformat = '';
14628
14629
14630 if (isset($p['SHEET-SIZE']) && is_array($p['SHEET-SIZE'])) {
14631 $newformat = $p['SHEET-SIZE'];
14632 if ($newformat[0] > $newformat[1]) { // landscape
14633 $newformat = array_reverse($newformat);
14634 $p['ORIENTATION'] = 'L';
14635 }
14636 else { $p['ORIENTATION'] = 'P'; }
14637 $this->_setPageSize($newformat, $p['ORIENTATION']);
14638 }
14639
14640 if (isset($p['SIZE']) && is_array($p['SIZE']) && !$newformat) {
14641 if ($p['SIZE']['W'] > $p['SIZE']['H']) { $p['ORIENTATION'] = 'L'; }
14642 else { $p['ORIENTATION'] = 'P'; }
14643 }
14644
14645 if (is_array($p['SIZE'])) {
14646 if ($p['SIZE']['W'] > $this->fw) { $p['SIZE']['W'] = $this->fw; } // mPD 4.2 use fw not fPt
14647 if ($p['SIZE']['H'] > $this->fh) { $p['SIZE']['H'] = $this->fh; }
14648 if (($p['ORIENTATION']==$this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION']=='P')) {
14649 $outer_width_LR = ($this->fw - $p['SIZE']['W'])/2;
14650 $outer_width_TB = ($this->fh - $p['SIZE']['H'])/2;
14651 }
14652 else {
14653 $outer_width_LR = ($this->fh - $p['SIZE']['W'])/2;
14654 $outer_width_TB = ($this->fw - $p['SIZE']['H'])/2;
14655 }
14656 $pgw = $p['SIZE']['W'];
14657 $pgh = $p['SIZE']['H'];
14658 }
14659 else { // AUTO LANDSCAPE PORTRAIT
14660 $outer_width_LR = 0;
14661 $outer_width_TB = 0;
14662 if (!$newformat) {
14663 if (strtoupper($p['SIZE']) == 'AUTO') { $p['ORIENTATION']=$this->DefOrientation; }
14664 else if (strtoupper($p['SIZE']) == 'LANDSCAPE') { $p['ORIENTATION']='L'; }
14665 else { $p['ORIENTATION']='P'; }
14666 }
14667 if (($p['ORIENTATION']==$this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION']=='P')) {
14668 $pgw = $this->fw;
14669 $pgh = $this->fh;
14670 }
14671 else {
14672 $pgw = $this->fh;
14673 $pgh = $this->fw;
14674 }
14675 }
14676
14677 if (isset($p['HEADER']) && $p['HEADER']) { $header = $p['HEADER']; }
14678 if (isset($p['FOOTER']) && $p['FOOTER']) { $footer = $p['FOOTER']; }
14679 if (isset($p['RESETPAGENUM']) && $p['RESETPAGENUM']) { $resetpagenum = $p['RESETPAGENUM']; }
14680 if (isset($p['PAGENUMSTYLE']) && $p['PAGENUMSTYLE']) { $pagenumstyle = $p['PAGENUMSTYLE']; }
14681 if (isset($p['SUPPRESS']) && $p['SUPPRESS']) { $suppress = $p['SUPPRESS']; }
14682
14683 if (preg_match('/cross/i', $p['MARKS']) && preg_match('/crop/i', $p['MARKS'])) { $marks = 'CROPCROSS'; }
14684 else if (strtoupper($p['MARKS']) == 'CROP') { $marks = 'CROP'; }
14685 else if (strtoupper($p['MARKS']) == 'CROSS') { $marks = 'CROSS'; }
14686
14687
14688 if (isset($p['BACKGROUND-COLOR']) && $p['BACKGROUND-COLOR']) { $bg['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR']; }
14689 /*-- BACKGROUNDS --*/
14690 if (isset($p['BACKGROUND-GRADIENT']) && $p['BACKGROUND-GRADIENT']) { $bg['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT']; }
14691 if (isset($p['BACKGROUND-IMAGE']) && $p['BACKGROUND-IMAGE']) { $bg['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE']; }
14692 if (isset($p['BACKGROUND-REPEAT']) && $p['BACKGROUND-REPEAT']) { $bg['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT']; }
14693 if (isset($p['BACKGROUND-POSITION']) && $p['BACKGROUND-POSITION']) { $bg['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION']; }
14694 if (isset($p['BACKGROUND-IMAGE-RESIZE']) && $p['BACKGROUND-IMAGE-RESIZE']) { $bg['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE']; }
14695 if (isset($p['BACKGROUND-IMAGE-OPACITY'])) { $bg['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY']; }
14696 /*-- END BACKGROUNDS --*/
14697
14698 if (isset($p['MARGIN-LEFT'])) { $mgl = $this->ConvertSize($p['MARGIN-LEFT'],$pgw) + $outer_width_LR; }
14699 if (isset($p['MARGIN-RIGHT'])) { $mgr = $this->ConvertSize($p['MARGIN-RIGHT'],$pgw) + $outer_width_LR; }
14700 if (isset($p['MARGIN-BOTTOM'])) { $mgb = $this->ConvertSize($p['MARGIN-BOTTOM'],$pgh) + $outer_width_TB; }
14701 if (isset($p['MARGIN-TOP'])) { $mgt = $this->ConvertSize($p['MARGIN-TOP'],$pgh) + $outer_width_TB; }
14702 if (isset($p['MARGIN-HEADER'])) { $mgh = $this->ConvertSize($p['MARGIN-HEADER'],$pgh) + $outer_width_TB; }
14703 if (isset($p['MARGIN-FOOTER'])) { $mgf = $this->ConvertSize($p['MARGIN-FOOTER'],$pgh) + $outer_width_TB; }
14704
14705 if (isset($p['ORIENTATION']) && $p['ORIENTATION']) { $orientation = $p['ORIENTATION']; }
14706 $this->page_box['outer_width_LR'] = $outer_width_LR; // Used in MARKS:crop etc.
14707 $this->page_box['outer_width_TB'] = $outer_width_TB;
14708
14709 return array($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$header,$footer,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat);
14710 }
14711 /*-- END CSS-PAGE --*/
14712
14713
14714
14715 /*-- CSS-FLOAT --*/
14716 // Added mPDF 3.0 Float DIV - CLEAR
14717 function ClearFloats($clear, $blklvl=0) {
14718 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($blklvl,true);
14719 $end = $currpos = ($this->page*1000 + $this->y);
14720 if ($clear == 'BOTH' && ($l_exists || $r_exists)) {
14721 $this->pageoutput[$this->page] = array();
14722 $end = max($l_max, $r_max, $currpos);
14723 }
14724 else if ($clear == 'RIGHT' && $r_exists) {
14725 $this->pageoutput[$this->page] = array();
14726 $end = max($r_max, $currpos);
14727 }
14728 else if ($clear == 'LEFT' && $l_exists ) {
14729 $this->pageoutput[$this->page] = array();
14730 $end = max($l_max, $currpos);
14731 }
14732 else { return; }
14733 $old_page = $this->page;
14734 $new_page = intval($end/1000);
14735 if ($old_page != $new_page) {
14736 $s = $this->PrintPageBackgrounds();
14737 // Writes after the marker so not overwritten later by page background etc.
14738 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
14739 $this->pageBackgrounds = array();
14740 $this->page = $new_page;
14741 }
14742 $this->ResetMargins();
14743 $this->pageoutput[$this->page] = array();
14744 $this->y = (($end*1000) % 1000000)/1000; // mod changes operands to integers before processing
14745 }
14746
14747
14748 // Added mPDF 3.0 Float DIV
14749 function GetFloatDivInfo($blklvl=0,$clear=false) {
14750 // If blklvl specified, only returns floats at that level - for ClearFloats
14751 $l_exists = false;
14752 $r_exists = false;
14753 $l_max = 0;
14754 $r_max = 0;
14755 $l_width = 0;
14756 $r_width = 0;
14757 if (count($this->floatDivs)) {
14758 $currpos = ($this->page*1000 + $this->y);
14759 foreach($this->floatDivs AS $f) {
14760 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'])) {
14761 if ($f['side']=='L') {
14762 $l_exists= true;
14763 $l_max = max($l_max, $f['endpos']);
14764 $l_width = max($l_width , $f['w']);
14765 }
14766 if ($f['side']=='R') {
14767 $r_exists= true;
14768 $r_max = max($r_max, $f['endpos']);
14769 $r_width = max($r_width , $f['w']);
14770 }
14771 }
14772 }
14773 }
14774 return array($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width);
14775 }
14776 /*-- END CSS-FLOAT --*/
14777
14778
14779
14780
14781 function OpenTag($tag,$attr)
14782 {
14783
14784 // What this gets: < $tag $attr['WIDTH']="90px" > does not get content here </closeTag here>
14785 // Correct tags where HTML specifies optional end tags,
14786 // and/or does not allow nesting e.g. P inside P, or
14787 if ($this->allow_html_optional_endtags) {
14788 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' || $tag=='ARTICLE' || $tag=='ASIDE' || $tag=='FIELDSET' || $tag=='HGROUP' || $tag=='MAIN' || $tag=='NAV' || $tag=='SECTION' ) && $this->lastoptionaltag == 'P') { $this->CloseTag($this->lastoptionaltag ); } // mPDF 5.7.3
14789 if ($tag == 'DD' && $this->lastoptionaltag == 'DD') { $this->CloseTag($this->lastoptionaltag ); }
14790 if ($tag == 'DD' && $this->lastoptionaltag == 'DT') { $this->CloseTag($this->lastoptionaltag ); }
14791 if ($tag == 'DT' && $this->lastoptionaltag == 'DD') { $this->CloseTag($this->lastoptionaltag ); }
14792 if ($tag == 'DT' && $this->lastoptionaltag == 'DT') { $this->CloseTag($this->lastoptionaltag ); }
14793 if ($tag == 'LI' && $this->lastoptionaltag == 'LI') { $this->CloseTag($this->lastoptionaltag ); }
14794 if (($tag == 'TD' || $tag == 'TH') && $this->lastoptionaltag == 'TD') { $this->CloseTag($this->lastoptionaltag ); } // *TABLES*
14795 if (($tag == 'TD' || $tag == 'TH') && $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); } // *TABLES*
14796 if ($tag == 'TR' && $this->lastoptionaltag == 'TR') { $this->CloseTag($this->lastoptionaltag ); } // *TABLES*
14797 if ($tag == 'TR' && $this->lastoptionaltag == 'TD') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); $this->CloseTag('THEAD'); } // *TABLES*
14798 if ($tag == 'TR' && $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag ); $this->CloseTag('TR'); $this->CloseTag('THEAD'); } // *TABLES*
14799 if ($tag == 'OPTION' && $this->lastoptionaltag == 'OPTION') { $this->CloseTag($this->lastoptionaltag ); }
14800 }
14801
14802 $align = array('left'=>'L','center'=>'C','right'=>'R','top'=>'T','text-top'=>'TT','middle'=>'M','baseline'=>'BS','bottom'=>'B','text-bottom'=>'TB','justify'=>'J');
14803
14804 $this->ignorefollowingspaces=false;
14805
14806 //Opening tag
14807 switch($tag){
14808
14809 case 'DOTTAB':
14810 $objattr = array();
14811 $objattr['type'] = 'dottab';
14812 $dots=str_repeat('.', 3)." "; // minimum number of dots
14813 $objattr['width'] = $this->GetStringWidth($dots);
14814 $objattr['margin_top'] = 0;
14815 $objattr['margin_bottom'] = 0;
14816 $objattr['margin_left'] = 0;
14817 $objattr['margin_right'] = 0;
14818 $objattr['height'] = 0;
14819 $objattr['colorarray'] = $this->colorarray;
14820 $objattr['border_top']['w'] = 0;
14821 $objattr['border_bottom']['w'] = 0;
14822 $objattr['border_left']['w'] = 0;
14823 $objattr['border_right']['w'] = 0;
14824
14825 // mPDF 5.6.19
14826 $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr); // mPDF 5.6.33
14827 if (isset($properties['OUTDENT'])) { // mPDF 5.6.33
14828 $objattr['outdent'] = $this->ConvertSize($properties['OUTDENT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
14829 }
14830 else if (isset($attr['OUTDENT'])) {
14831 $objattr['outdent'] = $this->ConvertSize($attr['OUTDENT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
14832 }
14833 else { $objattr['outdent'] = 0; }
14834
14835 $objattr['fontfamily'] = $this->FontFamily;
14836 $objattr['fontsize'] = $this->FontSizePt;
14837
14838 $e = "\xbb\xa4\xactype=dottab,objattr=".serialize($objattr)."\xbb\xa4\xac";
14839 /*-- TABLES --*/
14840 // Output it to buffers
14841 if ($this->tableLevel) {
14842 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
14843 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
14844 }
14845 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
14846 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
14847 }
14848 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
14849 $this->_saveCellTextBuffer($e);
14850 }
14851 else {
14852 /*-- END TABLES --*/
14853 $this->_saveTextBuffer($e);
14854 } // *TABLES*
14855 break;
14856
14857 case 'PAGEHEADER':
14858 case 'PAGEFOOTER':
14859 $this->ignorefollowingspaces = true;
14860 if ($attr['NAME']) { $pname = $attr['NAME']; }
14861 else { $pname = '_default'; }
14862
14863 if ($tag=='PAGEHEADER') { $p = &$this->pageheaders[$pname]; }
14864 else { $p = &$this->pagefooters[$pname]; }
14865
14866 $p['L']=array();
14867 $p['C']=array();
14868 $p['R']=array();
14869 $p['L']['font-style'] = '';
14870 $p['C']['font-style'] = '';
14871 $p['R']['font-style'] = '';
14872
14873 if (isset($attr['CONTENT-LEFT'])) {
14874 $p['L']['content'] = $attr['CONTENT-LEFT'];
14875 }
14876 if (isset($attr['CONTENT-CENTER'])) {
14877 $p['C']['content'] = $attr['CONTENT-CENTER'];
14878 }
14879 if (isset($attr['CONTENT-RIGHT'])) {
14880 $p['R']['content'] = $attr['CONTENT-RIGHT'];
14881 }
14882
14883 if (isset($attr['HEADER-STYLE']) || isset($attr['FOOTER-STYLE'])) { // font-family,size,weight,style,color
14884 if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE']); }
14885 else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE']); }
14886 if (isset($properties['FONT-FAMILY'])) {
14887 $p['L']['font-family'] = $properties['FONT-FAMILY'];
14888 $p['C']['font-family'] = $properties['FONT-FAMILY'];
14889 $p['R']['font-family'] = $properties['FONT-FAMILY'];
14890 }
14891 if (isset($properties['FONT-SIZE'])) {
14892 $p['L']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
14893 $p['C']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
14894 $p['R']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
14895 }
14896 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') {
14897 $p['L']['font-style'] = 'B';
14898 $p['C']['font-style'] = 'B';
14899 $p['R']['font-style'] = 'B';
14900 }
14901 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') {
14902 $p['L']['font-style'] .= 'I';
14903 $p['C']['font-style'] .= 'I';
14904 $p['R']['font-style'] .= 'I';
14905 }
14906 if (isset($properties['COLOR'])) {
14907 $p['L']['color'] = $properties['COLOR'];
14908 $p['C']['color'] = $properties['COLOR'];
14909 $p['R']['color'] = $properties['COLOR'];
14910 }
14911 }
14912 if (isset($attr['HEADER-STYLE-LEFT']) || isset($attr['FOOTER-STYLE-LEFT'])) {
14913 if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE-LEFT']); }
14914 else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE-LEFT']); }
14915 if (isset($properties['FONT-FAMILY'])) { $p['L']['font-family'] = $properties['FONT-FAMILY']; }
14916 if (isset($properties['FONT-SIZE'])) { $p['L']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
14917 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['L']['font-style'] ='B'; }
14918 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['L']['font-style'] .='I'; }
14919 if (isset($properties['COLOR'])) { $p['L']['color'] = $properties['COLOR']; }
14920 }
14921 if (isset($attr['HEADER-STYLE-CENTER']) || isset($attr['FOOTER-STYLE-CENTER'])) {
14922 if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE-CENTER']); }
14923 else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE-CENTER']); }
14924 if (isset($properties['FONT-FAMILY'])) { $p['C']['font-family'] = $properties['FONT-FAMILY']; }
14925 if (isset($properties['FONT-SIZE'])) { $p['C']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
14926 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['C']['font-style'] = 'B'; }
14927 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['C']['font-style'] .= 'I'; }
14928 if (isset($properties['COLOR'])) { $p['C']['color'] = $properties['COLOR']; }
14929 }
14930 if (isset($attr['HEADER-STYLE-RIGHT']) || isset($attr['FOOTER-STYLE-RIGHT'])) {
14931 if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE-RIGHT']); }
14932 else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE-RIGHT']); }
14933 if (isset($properties['FONT-FAMILY'])) { $p['R']['font-family'] = $properties['FONT-FAMILY']; }
14934 if (isset($properties['FONT-SIZE'])) { $p['R']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
14935 if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['R']['font-style'] = 'B'; }
14936 if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['R']['font-style'] .= 'I'; }
14937 if (isset($properties['COLOR'])) { $p['R']['color'] = $properties['COLOR']; }
14938 }
14939 if (isset($attr['LINE']) && $attr['LINE']) { // 0|1|on|off
14940 if ($attr['LINE']=='1' || strtoupper($attr['LINE'])=='ON') { $lineset=1; }
14941 else { $lineset=0; }
14942 $p['line'] = $lineset;
14943 }
14944 break;
14945
14946
14947 /*-- HTMLHEADERS-FOOTERS --*/
14948 case 'SETHTMLPAGEHEADER':
14949 case 'SETHTMLPAGEFOOTER':
14950 $this->ignorefollowingspaces = true;
14951 if (isset($attr['NAME']) && $attr['NAME']) { $pname = $attr['NAME']; }
14952 else { $pname = '_default'; }
14953 if (isset($attr['PAGE']) && $attr['PAGE']) { // O|odd|even|E|ALL|[blank]
14954 if (strtoupper($attr['PAGE'])=='O' || strtoupper($attr['PAGE'])=='ODD') { $side='odd'; }
14955 else if (strtoupper($attr['PAGE'])=='E' || strtoupper($attr['PAGE'])=='EVEN') { $side='even'; }
14956 else if (strtoupper($attr['PAGE'])=='ALL') { $side='both'; }
14957 else { $side='odd'; }
14958 }
14959 else { $side='odd'; }
14960 if (isset($attr['VALUE']) && $attr['VALUE']) { // -1|1|on|off
14961 if ($attr['VALUE']=='1' || strtoupper($attr['VALUE'])=='ON') { $set=1; }
14962 else if ($attr['VALUE']=='-1' || strtoupper($attr['VALUE'])=='OFF') { $set=0; }
14963 else { $set=1; }
14964 }
14965 else { $set=1; }
14966 if (isset($attr['SHOW-THIS-PAGE']) && $attr['SHOW-THIS-PAGE'] && $tag=='SETHTMLPAGEHEADER') { $write = 1; }
14967 else { $write = 0; }
14968 if ($side=='odd' || $side=='both') {
14969 if ($set && $tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader($this->pageHTMLheaders[$pname],'O',$write); }
14970 else if ($set && $tag=='SETHTMLPAGEFOOTER') { $this->SetHTMLFooter($this->pageHTMLfooters[$pname],'O'); }
14971 else if ($tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader('','O'); }
14972 else { $this->SetHTMLFooter('','O'); }
14973 }
14974 if ($side=='even' || $side=='both') {
14975 if ($set && $tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader($this->pageHTMLheaders[$pname],'E',$write); }
14976 else if ($set && $tag=='SETHTMLPAGEFOOTER') { $this->SetHTMLFooter($this->pageHTMLfooters[$pname],'E'); }
14977 else if ($tag=='SETHTMLPAGEHEADER') { $this->SetHTMLHeader('','E'); }
14978 else { $this->SetHTMLFooter('','E'); }
14979 }
14980 break;
14981 /*-- END HTMLHEADERS-FOOTERS --*/
14982
14983 case 'SETPAGEHEADER':
14984 case 'SETPAGEFOOTER':
14985 $this->ignorefollowingspaces = true;
14986 if (isset($attr['NAME']) && $attr['NAME']) { $pname = $attr['NAME']; }
14987 else { $pname = '_default'; }
14988 if (isset($attr['PAGE']) && $attr['PAGE']) { // O|odd|even|E|ALL|[blank]
14989 if (strtoupper($attr['PAGE'])=='O' || strtoupper($attr['PAGE'])=='ODD') { $side='odd'; }
14990 else if (strtoupper($attr['PAGE'])=='E' || strtoupper($attr['PAGE'])=='EVEN') { $side='even'; }
14991 else if (strtoupper($attr['PAGE'])=='ALL') { $side='both'; }
14992 else { $side='odd'; }
14993 }
14994 else { $side='odd'; }
14995 if (isset($attr['VALUE']) && $attr['VALUE']) { // -1|1|on|off
14996 if ($attr['VALUE']=='1' || strtoupper($attr['VALUE'])=='ON') { $set=1; }
14997 else if ($attr['VALUE']=='-1' || strtoupper($attr['VALUE'])=='OFF') { $set=0; }
14998 else { $set=1; }
14999 }
15000 else { $set=1; }
15001 if ($side=='odd' || $side=='both') {
15002 if ($set && $tag=='SETPAGEHEADER') { $this->headerDetails['odd'] = $this->pageheaders[$pname]; }
15003 else if ($set && $tag=='SETPAGEFOOTER') { $this->footerDetails['odd'] = $this->pagefooters[$pname]; }
15004 else if ($tag=='SETPAGEHEADER') { $this->headerDetails['odd'] = array(); }
15005 else { $this->footerDetails['odd'] = array(); }
15006 if (!$this->mirrorMargins || ($this->page)%2!=0) { // ODD
15007 if ($tag=='SETPAGEHEADER') { $this->_setAutoHeaderHeight($this->headerDetails['odd'],$this->HTMLHeader); }
15008 if ($tag=='SETPAGEFOOTER') { $this->_setAutoFooterHeight($this->footerDetails['odd'],$this->HTMLFooter); }
15009 }
15010 }
15011 if ($side=='even' || $side=='both') {
15012 if ($set && $tag=='SETPAGEHEADER') { $this->headerDetails['even'] = $this->pageheaders[$pname]; }
15013 else if ($set && $tag=='SETPAGEFOOTER') { $this->footerDetails['even'] = $this->pagefooters[$pname]; }
15014 else if ($tag=='SETPAGEHEADER') { $this->headerDetails['even'] = array(); }
15015 else { $this->footerDetails['even'] = array(); }
15016 if ($this->mirrorMargins && ($this->page)%2==0) { // EVEN
15017 if ($tag=='SETPAGEHEADER') { $this->_setAutoHeaderHeight($this->headerDetails['even'],$this->HTMLHeaderE); }
15018 if ($tag=='SETPAGEFOOTER') { $this->_setAutoFooterHeight($this->footerDetails['even'],$this->HTMLFooterE); }
15019 }
15020 }
15021 if (isset($attr['SHOW-THIS-PAGE']) && $attr['SHOW-THIS-PAGE'] && $tag=='SETPAGEHEADER') {
15022 $this->Header();
15023 }
15024 break;
15025
15026
15027 /*-- TOC --*/
15028 case 'TOC': //added custom-tag - set Marker for insertion later of ToC
15029 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
15030 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
15031 $this->tocontents->openTagTOC($attr);
15032 break;
15033
15034
15035
15036 case 'TOCPAGEBREAK': // custom-tag - set Marker for insertion later of ToC AND adds PAGEBREAK
15037 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
15038 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
15039 list($isbreak,$toc_id) = $this->tocontents->openTagTOCPAGEBREAK($attr);
15040 if ($isbreak) break;
15041 // No break - continues as PAGEBREAK...
15042 /*-- END TOC --*/
15043
15044
15045 case 'PAGE_BREAK': //custom-tag
15046 case 'PAGEBREAK': //custom-tag
15047 case 'NEWPAGE': //custom-tag
15048 case 'FORMFEED': //custom-tag
15049
15050 $save_blklvl = $this->blklvl;
15051 $save_blk = $this->blk;
15052 $save_silp = $this->saveInlineProperties();
15053 $save_ilp = $this->InlineProperties;
15054
15055 // Close any open block tags
15056 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
15057 if(!empty($this->textbuffer)) { //Output previously buffered content
15058 $this->printbuffer($this->textbuffer);
15059 $this->textbuffer=array();
15060 }
15061 $this->ignorefollowingspaces = true;
15062 $save_cols = false;
15063 /*-- COLUMNS --*/
15064 if ($this->ColActive) {
15065 $save_cols = true;
15066 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
15067 $this->SetColumns(0);
15068 }
15069 /*-- END COLUMNS --*/
15070
15071
15072 if (isset($attr['SHEET-SIZE']) && $tag != 'FORMFEED' && !$this->restoreBlockPageBreaks) {
15073 // Convert to same types as accepted in initial mPDF() A4, A4-L, or array(w,h)
15074 $prop = preg_split('/\s+/',trim($attr['SHEET-SIZE']));
15075 if (count($prop) == 2 ) {
15076 $newformat = array($this->ConvertSize($prop[0]), $this->ConvertSize($prop[1]));
15077 }
15078 else { $newformat = $attr['SHEET-SIZE']; }
15079 }
15080 else { $newformat = ''; }
15081
15082 $mgr = $mgl = $mgt = $mgb = $mgh = $mgf = '';
15083 if (isset($attr['MARGIN-RIGHT'])) { $mgr = $this->ConvertSize($attr['MARGIN-RIGHT'],$this->w,$this->FontSize,false); }
15084 if (isset($attr['MARGIN-LEFT'])) { $mgl = $this->ConvertSize($attr['MARGIN-LEFT'],$this->w,$this->FontSize,false); }
15085 if (isset($attr['MARGIN-TOP'])) { $mgt = $this->ConvertSize($attr['MARGIN-TOP'],$this->w,$this->FontSize,false); }
15086 if (isset($attr['MARGIN-BOTTOM'])) { $mgb = $this->ConvertSize($attr['MARGIN-BOTTOM'],$this->w,$this->FontSize,false); }
15087 if (isset($attr['MARGIN-HEADER'])) { $mgh = $this->ConvertSize($attr['MARGIN-HEADER'],$this->w,$this->FontSize,false); }
15088 if (isset($attr['MARGIN-FOOTER'])) { $mgf = $this->ConvertSize($attr['MARGIN-FOOTER'],$this->w,$this->FontSize,false); }
15089 $ohname = $ehname = $ofname = $efname = '';
15090 if (isset($attr['ODD-HEADER-NAME'])) { $ohname = $attr['ODD-HEADER-NAME']; }
15091 if (isset($attr['EVEN-HEADER-NAME'])) { $ehname = $attr['EVEN-HEADER-NAME']; }
15092 if (isset($attr['ODD-FOOTER-NAME'])) { $ofname = $attr['ODD-FOOTER-NAME']; }
15093 if (isset($attr['EVEN-FOOTER-NAME'])) { $efname = $attr['EVEN-FOOTER-NAME']; }
15094 $ohvalue = $ehvalue = $ofvalue = $efvalue = 0;
15095 if (isset($attr['ODD-HEADER-VALUE']) && ($attr['ODD-HEADER-VALUE']=='1' || strtoupper($attr['ODD-HEADER-VALUE'])=='ON')) { $ohvalue = 1; }
15096 else if (isset($attr['ODD-HEADER-VALUE']) && ($attr['ODD-HEADER-VALUE']=='-1' || strtoupper($attr['ODD-HEADER-VALUE'])=='OFF')) { $ohvalue = -1; }
15097 if (isset($attr['EVEN-HEADER-VALUE']) && ($attr['EVEN-HEADER-VALUE']=='1' || strtoupper($attr['EVEN-HEADER-VALUE'])=='ON')) { $ehvalue = 1; }
15098 else if (isset($attr['EVEN-HEADER-VALUE']) && ($attr['EVEN-HEADER-VALUE']=='-1' || strtoupper($attr['EVEN-HEADER-VALUE'])=='OFF')) { $ehvalue = -1; }
15099 if (isset($attr['ODD-FOOTER-VALUE']) && ($attr['ODD-FOOTER-VALUE']=='1' || strtoupper($attr['ODD-FOOTER-VALUE'])=='ON')) { $ofvalue = 1; }
15100 else if (isset($attr['ODD-FOOTER-VALUE']) && ($attr['ODD-FOOTER-VALUE']=='-1' || strtoupper($attr['ODD-FOOTER-VALUE'])=='OFF')) { $ofvalue = -1; }
15101 if (isset($attr['EVEN-FOOTER-VALUE']) && ($attr['EVEN-FOOTER-VALUE']=='1' || strtoupper($attr['EVEN-FOOTER-VALUE'])=='ON')) { $efvalue = 1; }
15102 else if (isset($attr['EVEN-FOOTER-VALUE']) && ($attr['EVEN-FOOTER-VALUE']=='-1' || strtoupper($attr['EVEN-FOOTER-VALUE'])=='OFF')) { $efvalue = -1; }
15103
15104 if (isset($attr['ORIENTATION']) && (strtoupper($attr['ORIENTATION'])=='L' || strtoupper($attr['ORIENTATION'])=='LANDSCAPE')) { $orient = 'L'; }
15105 else if (isset($attr['ORIENTATION']) && (strtoupper($attr['ORIENTATION'])=='P' || strtoupper($attr['ORIENTATION'])=='PORTRAIT')) { $orient = 'P'; }
15106 else { $orient = $this->CurOrientation; }
15107
15108 if (isset($attr['PAGE-SELECTOR']) && $attr['PAGE-SELECTOR']) { $pagesel = $attr['PAGE-SELECTOR']; }
15109 else { $pagesel = ''; }
15110
15111 $resetpagenum = '';
15112 $pagenumstyle = '';
15113 $suppress = '';
15114 if (isset($attr['RESETPAGENUM'])) { $resetpagenum = $attr['RESETPAGENUM']; }
15115 if (isset($attr['PAGENUMSTYLE'])) { $pagenumstyle = $attr['PAGENUMSTYLE']; }
15116 if (isset($attr['SUPPRESS'])) { $suppress = $attr['SUPPRESS']; }
15117
15118 if ($tag == 'TOCPAGEBREAK') { $type = 'NEXT-ODD'; }
15119 else if(isset($attr['TYPE'])) { $type = strtoupper($attr['TYPE']); }
15120 else { $type = ''; }
15121
15122 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); }
15123 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); }
15124 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); }
15125 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); }
15126 else { $this->AddPage($orient,'', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat); }
15127
15128 /*-- TOC --*/
15129 if ($tag == 'TOCPAGEBREAK') {
15130 if ($toc_id) { $this->tocontents->m_TOC[$toc_id]['TOCmark'] = $this->page; }
15131 else { $this->tocontents->TOCmark = $this->page; }
15132 }
15133 /*-- END TOC --*/
15134
15135 /*-- COLUMNS --*/
15136 if ($save_cols) {
15137 // Restore columns
15138 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
15139 }
15140 /*-- END COLUMNS --*/
15141 if (($tag == 'FORMFEED' || $this->restoreBlockPagebreaks) && !$this->tableLevel && !$this->listlvl) {
15142 $this->blk = $save_blk;
15143 // Re-open block tags
15144 $t = $this->blk[0]['tag'];
15145 $a = $this->blk[0]['attr'];
15146 $this->blklvl = 0;
15147 for ($b=0; $b<=$save_blklvl;$b++) {
15148 $tc = $t;
15149 $ac = $a;
15150 $t = $this->blk[$b+1]['tag'];
15151 $a = $this->blk[$b+1]['attr'];
15152 unset($this->blk[$b+1]);
15153 $this->OpenTag($tc,$ac);
15154 }
15155 $this->InlineProperties = $save_ilp;
15156 $this->restoreInlineProperties($save_silp);
15157 }
15158
15159 break;
15160
15161
15162 /*-- TOC --*/
15163 case 'TOCENTRY':
15164 if (isset($attr['CONTENT']) && $attr['CONTENT']) {
15165 $objattr = array();
15166 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
15167 $objattr['type'] = 'toc';
15168 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['toclevel'] = $attr['LEVEL']; } else { $objattr['toclevel'] = 0; }
15169 if (isset($attr['NAME']) && $attr['NAME']) { $objattr['toc_id'] = $attr['NAME']; } else { $objattr['toc_id'] = 0; }
15170 $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
15171 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
15172 else { // *TABLES*
15173 $this->textbuffer[] = array($e);
15174 } // *TABLES*
15175 }
15176 break;
15177 /*-- END TOC --*/
15178
15179 /*-- INDEX --*/
15180 case 'INDEXENTRY':
15181 if (isset($attr['CONTENT']) && $attr['CONTENT']) {
15182 if (isset($attr['XREF']) && $attr['XREF']) {
15183 $this->IndexEntry(htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES),$attr['XREF']);
15184 break;
15185 }
15186 $objattr = array();
15187 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
15188 $objattr['type'] = 'indexentry';
15189 $e = "\xbb\xa4\xactype=indexentry,objattr=".serialize($objattr)."\xbb\xa4\xac";
15190 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
15191 else { // *TABLES*
15192 $this->textbuffer[] = array($e);
15193 } // *TABLES*
15194 }
15195 break;
15196
15197
15198 case 'INDEXINSERT':
15199 if (isset($attr['FONT-SIZE'])) { $reffontsize = $attr['FONT-SIZE']; } else { $reffontsize = ''; }
15200 if (isset($attr['LINE-SPACING']) && $attr['LINE-SPACING']) { $linespacing = $attr['LINE-SPACING']; } else { $linespacing = ''; }
15201 if (isset($attr['DIV-FONT-SIZE']) && $attr['DIV-FONT-SIZE']) { $divlettfontsize = $attr['DIV-FONT-SIZE']; } else { $divlettfontsize = ''; }
15202 if (isset($attr['FONT']) && $attr['FONT']) { $reffont = $attr['FONT']; } else { $reffont = ''; }
15203 if (isset($attr['DIV-FONT']) && $attr['DIV-FONT']) { $divlettfont = $attr['DIV-FONT']; } else { $divlettfont = ''; }
15204 if (isset($attr['COLS']) && $attr['COLS']) { $cols = $attr['COLS']; } else { $cols = 1; }
15205 if (isset($attr['OFFSET']) && $attr['OFFSET']) { $offset = $attr['OFFSET']; } else { $offset = 3; }
15206 if (isset($attr['GAP']) && $attr['GAP']) { $gap = $attr['GAP']; } else { $gap = 5; }
15207
15208 if (isset($attr['USEDIVLETTERS']) && (strtoupper($attr['USEDIVLETTERS'])=='OFF' || $attr['USEDIVLETTERS']==-1 || $attr['USEDIVLETTERS']==='0')) { $usedivletters = 0; }
15209 else { $usedivletters = 1; }
15210
15211 if (isset($attr['LINKS']) && (strtoupper($attr['LINKS'])=='ON' || $attr['LINKS']==1)) { $links = true; }
15212 else { $links = false; }
15213 $this->CreateIndex($cols, $reffontsize, $linespacing, $offset, $usedivletters, $divlettfontsize, $gap, $reffont,$divlettfont, $links);
15214 break;
15215 /*-- END INDEX --*/
15216
15217 /*-- WATERMARK --*/
15218
15219 case 'WATERMARKTEXT':
15220 if (isset($attr['CONTENT']) && $attr['CONTENT']) { $txt = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES); } else { $txt = ''; }
15221 if (isset($attr['ALPHA']) && $attr['ALPHA']>0) { $alpha = $attr['ALPHA']; } else { $alpha = -1; }
15222 $this->SetWatermarkText($txt, $alpha);
15223 break;
15224
15225
15226 case 'WATERMARKIMAGE':
15227 if (isset($attr['SRC'])) { $src = $attr['SRC']; } else { $src = ''; }
15228 if (isset($attr['ALPHA']) && $attr['ALPHA']>0) { $alpha = $attr['ALPHA']; } else { $alpha = -1; }
15229 if (isset($attr['SIZE']) && $attr['SIZE']) {
15230 $size = $attr['SIZE'];
15231 if (strpos($size,',')) { $size = explode(',',$size); }
15232 }
15233 else { $size = 'D'; }
15234 if (isset($attr['POSITION']) && $attr['POSITION']) { // mPDF 5.7.2
15235 $pos = $attr['POSITION'];
15236 if (strpos($pos,',')) { $pos = explode(',',$pos); }
15237 }
15238 else { $pos = 'P'; }
15239 $this->SetWatermarkImage($src, $alpha, $size, $pos);
15240 break;
15241 /*-- END WATERMARK --*/
15242
15243 /*-- BOOKMARKS --*/
15244 case 'BOOKMARK':
15245 if (isset($attr['CONTENT'])) {
15246 $objattr = array();
15247 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
15248 $objattr['type'] = 'bookmark';
15249 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['bklevel'] = $attr['LEVEL']; } else { $objattr['bklevel'] = 0; }
15250 $e = "\xbb\xa4\xactype=bookmark,objattr=".serialize($objattr)."\xbb\xa4\xac";
15251 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
15252 else { // *TABLES*
15253 $this->textbuffer[] = array($e);
15254 } // *TABLES*
15255 }
15256 break;
15257 /*-- END BOOKMARKS --*/
15258
15259 /*-- ANNOTATIONS --*/
15260 case 'ANNOTATION':
15261
15262 //if (isset($attr['CONTENT']) && !$this->writingHTMLheader && !$this->writingHTMLfooter) { // Stops annotations in FixedPos
15263 if (isset($attr['CONTENT'])) {
15264 $objattr = array();
15265 $objattr['margin_top'] = 0;
15266 $objattr['margin_bottom'] = 0;
15267 $objattr['margin_left'] = 0;
15268 $objattr['margin_right'] = 0;
15269 $objattr['width'] = 0;
15270 $objattr['height'] = 0;
15271 $objattr['border_top']['w'] = 0;
15272 $objattr['border_bottom']['w'] = 0;
15273 $objattr['border_left']['w'] = 0;
15274 $objattr['border_right']['w'] = 0;
15275 $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
15276 $objattr['type'] = 'annot';
15277 $objattr['POPUP'] = '';
15278 }
15279 else { break; }
15280 if (isset($attr['POS-X'])) { $objattr['POS-X'] = $attr['POS-X']; } else { $objattr['POS-X'] = 0; }
15281 if (isset($attr['POS-Y'])) { $objattr['POS-Y'] = $attr['POS-Y']; } else { $objattr['POS-Y'] = 0; }
15282 if (isset($attr['ICON'])) { $objattr['ICON'] = $attr['ICON']; } else { $objattr['ICON'] = 'Note'; }
15283 if (isset($attr['AUTHOR'])) { $objattr['AUTHOR'] = $attr['AUTHOR']; }
15284 else if (isset($attr['TITLE'])) { $objattr['AUTHOR'] = $attr['TITLE']; } else { $objattr['AUTHOR'] = ''; }
15285 if (isset($attr['FILE'])) { $objattr['FILE'] = $attr['FILE']; } else { $objattr['FILE'] = ''; }
15286 if (isset($attr['SUBJECT'])) { $objattr['SUBJECT'] = $attr['SUBJECT']; } else { $objattr['SUBJECT'] = ''; }
15287 if (isset($attr['OPACITY']) && $attr['OPACITY']>0 && $attr['OPACITY']<=1) { $objattr['OPACITY'] = $attr['OPACITY']; }
15288 else if ($this->annotMargin) { $objattr['OPACITY'] = 1; }
15289 else { $objattr['OPACITY'] = $this->annotOpacity; }
15290 if (isset($attr['COLOR'])) {
15291 $cor = $this->ConvertColor($attr['COLOR']);
15292 if ($cor) { $objattr['COLOR'] = $cor; }
15293 else { $objattr['COLOR'] = $this->ConvertColor('yellow'); }
15294 }
15295 else { $objattr['COLOR'] = $this->ConvertColor('yellow'); }
15296
15297 if (isset($attr['POPUP']) && !empty($attr['POPUP'])) {
15298 $pop = preg_split('/\s+/',trim($attr['POPUP']));
15299 if (count($pop)>1) { $objattr['POPUP'] = $pop; }
15300 else { $objattr['POPUP'] = true; }
15301 }
15302 $e = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
15303 if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
15304 else { // *TABLES*
15305 $this->textbuffer[] = array($e);
15306 } // *TABLES*
15307 break;
15308 /*-- END ANNOTATIONS --*/
15309
15310
15311 /*-- COLUMNS --*/
15312 case 'COLUMNS': //added custom-tag
15313 if (isset($attr['COLUMN-COUNT']) && ($attr['COLUMN-COUNT'] || $attr['COLUMN-COUNT']==='0')) {
15314 // Close any open block tags
15315 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
15316 if(!empty($this->textbuffer)) { //Output previously buffered content
15317 $this->printbuffer($this->textbuffer);
15318 $this->textbuffer=array();
15319 }
15320
15321 if (isset($attr['VALIGN']) && $attr['VALIGN']) {
15322 if ($attr['VALIGN'] == 'J') { $valign = 'J'; }
15323 else { $valign = $align[$attr['VALIGN']]; }
15324 }
15325 else { $valign = ''; }
15326 if (isset($attr['COLUMN-GAP']) && $attr['COLUMN-GAP']) { $this->SetColumns($attr['COLUMN-COUNT'],$valign,$attr['COLUMN-GAP']); }
15327 else { $this->SetColumns($attr['COLUMN-COUNT'],$valign); }
15328 }
15329 $this->ignorefollowingspaces = true;
15330 break;
15331
15332 case 'COLUMN_BREAK': //custom-tag
15333 case 'COLUMNBREAK': //custom-tag
15334 case 'NEWCOLUMN': //custom-tag
15335 $this->ignorefollowingspaces = true;
15336 $this->NewColumn();
15337 $this->ColumnAdjust = false; // disables all column height adjustment for the page.
15338 break;
15339
15340 /*-- END COLUMNS --*/
15341
15342
15343 case 'BDO':
15344 // $this->biDirectional = true;
15345 break;
15346
15347
15348 case 'TTZ':
15349 $this->ttz = true;
15350 $this->InlineProperties[$tag] = $this->saveInlineProperties();
15351 $this->setCSS(array('FONT-FAMILY'=>'czapfdingbats','FONT-WEIGHT'=>'normal','FONT-STYLE'=>'normal'),'INLINE');
15352 break;
15353
15354 case 'TTS':
15355 $this->tts = true;
15356 $this->InlineProperties[$tag] = $this->saveInlineProperties();
15357 $this->setCSS(array('FONT-FAMILY'=>'csymbol','FONT-WEIGHT'=>'normal','FONT-STYLE'=>'normal'),'INLINE');
15358 break;
15359
15360 case 'TTA':
15361 $this->tta = true;
15362 $this->InlineProperties[$tag] = $this->saveInlineProperties();
15363
15364 if (in_array($this->FontFamily,$this->mono_fonts)) {
15365 $this->setCSS(array('FONT-FAMILY'=>'ccourier'),'INLINE');
15366 }
15367 else if (in_array($this->FontFamily,$this->serif_fonts)) {
15368 $this->setCSS(array('FONT-FAMILY'=>'ctimes'),'INLINE');
15369 }
15370 else {
15371 $this->setCSS(array('FONT-FAMILY'=>'chelvetica'),'INLINE');
15372 }
15373 break;
15374
15375
15376
15377 // INLINE PHRASES OR STYLES
15378 case 'SUB':
15379 case 'SUP':
15380 case 'ACRONYM':
15381 case 'BIG':
15382 case 'SMALL':
15383 case 'INS':
15384 case 'S':
15385 case 'STRIKE':
15386 case 'DEL':
15387 case 'STRONG':
15388 case 'CITE':
15389 case 'Q':
15390 case 'EM':
15391 case 'B':
15392 case 'I':
15393 case 'U':
15394 case 'SAMP':
15395 case 'CODE':
15396 case 'KBD':
15397 case 'TT':
15398 case 'VAR':
15399 case 'FONT':
15400 case 'MARK': // mPDF 5.5.09
15401 case 'TIME':
15402
15403 case 'SPAN':
15404 /*-- ANNOTATIONS --*/
15405 if ($this->title2annots && isset($attr['TITLE'])) {
15406 $objattr = array();
15407 $objattr['margin_top'] = 0;
15408 $objattr['margin_bottom'] = 0;
15409 $objattr['margin_left'] = 0;
15410 $objattr['margin_right'] = 0;
15411 $objattr['width'] = 0;
15412 $objattr['height'] = 0;
15413 $objattr['border_top']['w'] = 0;
15414 $objattr['border_bottom']['w'] = 0;
15415 $objattr['border_left']['w'] = 0;
15416 $objattr['border_right']['w'] = 0;
15417
15418 $objattr['CONTENT'] = $attr['TITLE'];
15419 $objattr['type'] = 'annot';
15420 $objattr['POS-X'] = 0;
15421 $objattr['POS-Y'] = 0;
15422 $objattr['ICON'] = 'Comment';
15423 $objattr['AUTHOR'] = '';
15424 $objattr['SUBJECT'] = '';
15425 $objattr['OPACITY'] = $this->annotOpacity;
15426 $objattr['COLOR'] = $this->ConvertColor('yellow');
15427 $annot = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
15428 }
15429 /*-- END ANNOTATIONS --*/
15430
15431 // mPDF 5.7.3 Inline tags
15432 if (!isset($this->InlineProperties[$tag])) { $this->InlineProperties[$tag] = array($this->saveInlineProperties()); }
15433 else { $this->InlineProperties[$tag][] = $this->saveInlineProperties(); }
15434 if (isset($annot)) { // *ANNOTATIONS*
15435 if (!isset($this->InlineAnnots[$tag])) { $this->InlineAnnots[$tag] = array($annot); } // *ANNOTATIONS*
15436 else { $this->InlineAnnots[$tag][] = $annot; } // *ANNOTATIONS*
15437 } // *ANNOTATIONS*
15438
15439 $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
15440 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15441 break;
15442
15443
15444 case 'A':
15445 if (isset($attr['NAME']) and $attr['NAME'] != '') {
15446 $e = '';
15447 /*-- BOOKMARKS --*/
15448 if ($this->anchor2Bookmark) {
15449 $objattr = array();
15450 $objattr['CONTENT'] = htmlspecialchars_decode($attr['NAME'],ENT_QUOTES);
15451 $objattr['type'] = 'bookmark';
15452 if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['bklevel'] = $attr['LEVEL']; } else { $objattr['bklevel'] = 0; }
15453 $e = "\xbb\xa4\xactype=bookmark,objattr=".serialize($objattr)."\xbb\xa4\xac";
15454 }
15455 /*-- END BOOKMARKS --*/
15456 if($this->tableLevel) { // *TABLES*
15457 $this->_saveCellTextBuffer($e, '', $attr['NAME']); // *TABLES*
15458 } // *TABLES*
15459 else { // *TABLES*
15460 $this->_saveTextBuffer($e, '', $attr['NAME']); //an internal link (adds a space for recognition)
15461 } // *TABLES*
15462 }
15463 if (isset($attr['HREF'])) {
15464 $this->InlineProperties['A'] = $this->saveInlineProperties();
15465 $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
15466 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15467 $this->HREF=$attr['HREF']; // mPDF 5.7.4 URLs
15468 }
15469 break;
15470
15471 case 'LEGEND':
15472 $this->InlineProperties['LEGEND'] = $this->saveInlineProperties();
15473 $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
15474 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15475 break;
15476
15477
15478
15479 case 'PROGRESS':
15480 case 'METER':
15481 $this->inMeter = true;
15482
15483 if (isset($attr['MAX']) && $attr['MAX']) { $max = $attr['MAX']; }
15484 else { $max = 1; }
15485 if (isset($attr['MIN']) && $attr['MIN'] && $tag=='METER') { $min = $attr['MIN']; }
15486 else { $min = 0; }
15487 if ($max < $min) { $max = $min; }
15488
15489 if (isset($attr['VALUE']) && ($attr['VALUE'] || $attr['VALUE']==='0')) {
15490 $value = $attr['VALUE'];
15491 if ($value < $min) { $value = $min; }
15492 else if ($value > $max) { $value = $max; }
15493 }
15494 else { $value = ''; }
15495
15496 if (isset($attr['LOW']) && $attr['LOW']) { $low = $attr['LOW']; }
15497 else { $low = $min; }
15498 if ($low < $min) { $low = $min; }
15499 else if ($low > $max) { $low = $max; }
15500 if (isset($attr['HIGH']) && $attr['HIGH']) { $high = $attr['HIGH']; }
15501 else { $high = $max; }
15502 if ($high < $low) { $high = $low; }
15503 else if ($high > $max) { $high = $max; }
15504 if (isset($attr['OPTIMUM']) && $attr['OPTIMUM']) { $optimum = $attr['OPTIMUM']; }
15505 else { $optimum = $min + (($max-$min)/2); }
15506 if ($optimum < $min) { $optimum = $min; }
15507 else if ($optimum > $max) { $optimum = $max; }
15508 if (isset($attr['TYPE']) && $attr['TYPE']) { $type = $attr['TYPE']; }
15509 else { $type = ''; }
15510 $objattr = array();
15511 $objattr['margin_top'] = 0;
15512 $objattr['margin_bottom'] = 0;
15513 $objattr['margin_left'] = 0;
15514 $objattr['margin_right'] = 0;
15515 $objattr['padding_top'] = 0;
15516 $objattr['padding_bottom'] = 0;
15517 $objattr['padding_left'] = 0;
15518 $objattr['padding_right'] = 0;
15519 $objattr['width'] = 0;
15520 $objattr['height'] = 0;
15521 $objattr['border_top']['w'] = 0;
15522 $objattr['border_bottom']['w'] = 0;
15523 $objattr['border_left']['w'] = 0;
15524 $objattr['border_right']['w'] = 0;
15525
15526 $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
15527 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
15528 return;
15529 }
15530 $objattr['visibility'] = 'visible';
15531 if (isset($properties['VISIBILITY'])) {
15532 $v = strtolower($properties['VISIBILITY']);
15533 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible') {
15534 $objattr['visibility'] = $v;
15535 }
15536 }
15537
15538 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15539 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15540 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15541 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15542
15543 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15544 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15545 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15546 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
15547
15548 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
15549 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
15550 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
15551 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
15552
15553 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
15554 $w = 0;
15555 $h = 0;
15556 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
15557 else if(isset($attr['WIDTH'])) $w = $this->ConvertSize($attr['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
15558
15559 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
15560 else if(isset($attr['HEIGHT'])) $h = $this->ConvertSize($attr['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
15561
15562 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr['opacity'] = $properties['OPACITY']; }
15563 if ($this->HREF) {
15564 if (strpos($this->HREF,".") === false && strpos($this->HREF,"@") !== 0) {
15565 $href = $this->HREF;
15566 while(array_key_exists($href,$this->internallink)) $href="#".$href;
15567 $this->internallink[$href] = $this->AddLink();
15568 $objattr['link'] = $this->internallink[$href];
15569 }
15570 else { $objattr['link'] = $this->HREF; }
15571 }
15572 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
15573 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
15574
15575 // Image file
15576 if (!class_exists('meter', false)) {
15577 include(_MPDF_PATH.'classes/meter.php');
15578 }
15579 $this->meter = new meter();
15580 $svg = $this->meter->makeSVG(strtolower($tag), $type, $value, $max, $min, $optimum, $low, $high);
15581 //Save to local file
15582 $srcpath= _MPDF_TEMP_PATH.'_tempSVG'.uniqid(rand(1,100000),true).'_'.strtolower($tag).'.svg';
15583 file_put_contents($srcpath, $svg);
15584 $orig_srcpath = $srcpath;
15585 $this->GetFullPath($srcpath);
15586
15587 $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
15588 if(!$info) {
15589 $info = $this->_getImage($this->noImageFile);
15590 if ($info) {
15591 $srcpath = $this->noImageFile;
15592 $w = ($info['w'] * (25.4/$this->dpi));
15593 $h = ($info['h'] * (25.4/$this->dpi));
15594 }
15595 }
15596 if(!$info) break;
15597
15598 $objattr['file'] = $srcpath;
15599 //Default width and height calculation if needed
15600 if($w==0 and $h==0) {
15601 // SVG units are pixels
15602 $w = $this->FontSize/(10/_MPDFK) * abs($info['w'])/_MPDFK; // mPDF 5.5.21
15603 $h = $this->FontSize/(10/_MPDFK) * abs($info['h'])/_MPDFK;
15604 }
15605 // IF WIDTH OR HEIGHT SPECIFIED
15606 if($w==0) $w=abs($h*$info['w']/$info['h']);
15607 if($h==0) $h=abs($w*$info['h']/$info['w']);
15608
15609 // Resize to maximum dimensions of page
15610 $maxWidth = $this->blk[$this->blklvl]['inner_width'];
15611 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 1) ;
15612 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
15613 if (($w + $extrawidth) > ($maxWidth + 0.0001) ) { // mPDF 5.7.4 0.0001 to allow for rounding errors when w==maxWidth
15614 $w = $maxWidth - $extrawidth;
15615 $h=abs($w*$info['h']/$info['w']);
15616 }
15617
15618 if ($h + $extraheight > $maxHeight ) {
15619 $h = $maxHeight - $extraheight;
15620 $w=abs($h*$info['w']/$info['h']);
15621 }
15622 $objattr['type'] = 'image';
15623 $objattr['itype'] = $info['type'];
15624
15625 $objattr['orig_h'] = $info['h'];
15626 $objattr['orig_w'] = $info['w'];
15627 $objattr['wmf_x'] = $info['x'];
15628 $objattr['wmf_y'] = $info['y'];
15629 $objattr['height'] = $h + $extraheight;
15630 $objattr['width'] = $w + $extrawidth;
15631 $objattr['image_height'] = $h;
15632 $objattr['image_width'] = $w;
15633 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
15634 $properties = array();
15635 if ($this->tableLevel) {
15636 $this->_saveCellTextBuffer($e, $this->HREF);
15637 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
15638 }
15639 else {
15640 $this->_saveTextBuffer($e, $this->HREF);
15641 }
15642
15643 break;
15644
15645
15646 case 'BR':
15647 // Added mPDF 3.0 Float DIV - CLEAR
15648 if (isset($attr['STYLE'])) {
15649 $properties = $this->cssmgr->readInlineCSS($attr['STYLE']);
15650 if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']),$this->blklvl); } // *CSS-FLOAT*
15651 }
15652
15653
15654 /*-- TABLES --*/
15655 if($this->tableLevel) {
15656
15657 if ($this->blockjustfinished || $this->listjustfinished) {
15658 $this->_saveCellTextBuffer("\n");
15659 }
15660
15661 $this->_saveCellTextBuffer("\n");
15662 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
15663 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15664 }
15665 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
15666 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15667 }
15668 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
15669 }
15670 else {
15671 /*-- END TABLES --*/
15672 if (count($this->textbuffer)) {
15673 $this->textbuffer[count($this->textbuffer)-1][0] = preg_replace('/ $/','',$this->textbuffer[count($this->textbuffer)-1][0]);
15674 }
15675 $this->_saveTextBuffer("\n");
15676 } // *TABLES*
15677 $this->ignorefollowingspaces = true;
15678 $this->blockjustfinished=false;
15679 $this->listjustfinished=false;
15680
15681 $this->linebreakjustfinished=true;
15682 break;
15683
15684
15685 // *********** BLOCKS ********************
15686
15687
15688 case 'PRE':
15689 $this->ispre=true; // ADDED - Prevents left trim of textbuffer in printbuffer()
15690
15691 case 'DIV':
15692 case 'FORM':
15693 case 'CENTER':
15694
15695 case 'BLOCKQUOTE':
15696 case 'ADDRESS':
15697
15698 case 'CAPTION':
15699 case 'P':
15700 case 'H1':
15701 case 'H2':
15702 case 'H3':
15703 case 'H4':
15704 case 'H5':
15705 case 'H6':
15706 case 'DL':
15707 case 'DT':
15708 case 'DD':
15709 case 'FIELDSET':
15710 case 'DETAILS':
15711 case 'SUMMARY':
15712 case 'ARTICLE':
15713 case 'ASIDE':
15714 case 'FIGURE':
15715 case 'FIGCAPTION':
15716 case 'FOOTER':
15717 case 'HEADER':
15718 case 'HGROUP':
15719 case 'NAV':
15720 case 'SECTION':
15721 case 'MAIN': // mPDF 5.7.3
15722 $p = $this->cssmgr->PreviewBlockCSS($tag,$attr);
15723 if(isset($p['DISPLAY']) && strtolower($p['DISPLAY'])=='none') {
15724 $this->blklvl++;
15725 $this->blk[$this->blklvl]['hide'] = true;
15726 return;
15727 }
15728 if($tag == 'CAPTION') {
15729 // position is written in AdjstHTML
15730 if (isset($attr['POSITION']) && strtolower($attr['POSITION'])=='bottom') { $divpos = 'B'; }
15731 else { $divpos = 'T'; }
15732 if (isset($attr['ALIGN']) && strtolower($attr['ALIGN'])=='bottom') { $cappos = 'B'; }
15733 else if (isset($p['CAPTION-SIDE']) && strtolower($p['CAPTION-SIDE'])=='bottom') { $cappos = 'B'; }
15734 else { $cappos = 'T'; }
15735 if (isset($attr['ALIGN'])) { unset($attr['ALIGN']); }
15736 if ($cappos != $divpos) {
15737 $this->blklvl++;
15738 $this->blk[$this->blklvl]['hide'] = true;
15739 return;
15740 }
15741 }
15742
15743 /*-- FORMS --*/
15744 if($tag == 'FORM') {
15745 if (isset($attr['METHOD']) && strtolower($attr['METHOD'])=='get') { $this->form->formMethod = 'GET'; }
15746 else { $this->form->formMethod = 'POST'; }
15747 if (isset($attr['ACTION'])) { $this->form->formAction = $attr['ACTION']; }
15748 else { $this->form->formAction = ''; }
15749 }
15750 /*-- END FORMS --*/
15751
15752
15753 /*-- CSS-POSITION --*/
15754 if ((isset($p['POSITION']) && (strtolower($p['POSITION'])=='fixed' || strtolower($p['POSITION'])=='absolute')) && $this->blklvl==0) {
15755 if ($this->inFixedPosBlock) {
15756 $this->Error("Cannot nest block with position:fixed or position:absolute");
15757 }
15758 $this->inFixedPosBlock = true;
15759 return;
15760 }
15761 /*-- END CSS-POSITION --*/
15762 // Start Block
15763 $this->ignorefollowingspaces = true;
15764
15765 if ($this->blockjustfinished && !count($this->textbuffer) && $this->y != $this->tMargin && $this->collapseBlockMargins) { $lastbottommargin = $this->lastblockbottommargin; }
15766 else { $lastbottommargin = 0; }
15767 $this->lastblockbottommargin = 0;
15768 $this->blockjustfinished=false;
15769
15770 /*-- LISTS --*/
15771 if ($this->listlvl>0) { return; }
15772 /*-- END LISTS --*/
15773
15774 $this->InlineProperties = array();
15775 $this->listjustfinished=false;
15776 $this->divbegin=true;
15777
15778 $this->linebreakjustfinished=false;
15779
15780 /*-- TABLES --*/
15781 if ($this->tableLevel) {
15782
15783 // If already something on the line
15784 if ($this->cell[$this->row][$this->col]['s'] > 0 && !$this->nestedtablejustfinished ) {
15785 $this->_saveCellTextBuffer("\n");
15786 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
15787 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15788 }
15789 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
15790 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
15791 }
15792 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
15793 }
15794 // Cannot set block properties inside table - use Bold to indicate h1-h6
15795 if ($tag == 'CENTER' && $this->tdbegin) { $this->cell[$this->row][$this->col]['a'] = $align['center']; }
15796
15797 $this->InlineProperties['BLOCKINTABLE'] = $this->saveInlineProperties();
15798 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
15799 if (!empty($properties)) $this->setCSS($properties,'INLINE');
15800
15801
15802 break;
15803 }
15804 /*-- END TABLES --*/
15805
15806 if ($tag == 'P' || $tag == 'DT' || $tag == 'DD') { $this->lastoptionaltag = $tag; } // Save current HTML specified optional endtag
15807 else { $this->lastoptionaltag = ''; }
15808
15809 if ($this->lastblocklevelchange == 1) { $blockstate = 1; } // Top margins/padding only
15810 else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
15811 $this->printbuffer($this->textbuffer,$blockstate);
15812 $this->textbuffer=array();
15813
15814 $save_blklvl = $this->blklvl;
15815 $save_blk = $this->blk;
15816 $save_silp = $this->saveInlineProperties();
15817 $save_ilp = $this->InlineProperties;
15818
15819 $this->blklvl++;
15820
15821 $currblk =& $this->blk[$this->blklvl];
15822 $this->initialiseBlock($currblk);
15823 $prevblk =& $this->blk[$this->blklvl-1];
15824
15825 $currblk['tag'] = $tag;
15826 $currblk['attr'] = $attr;
15827
15828 $this->Reset();
15829 $properties = $this->cssmgr->MergeCSS('BLOCK',$tag,$attr);
15830 $pagesel = '';
15831 /*-- CSS-PAGE --*/
15832
15833 if (isset($properties['PAGE'])) { $pagesel = $properties['PAGE']; }
15834 /*-- END CSS-PAGE --*/
15835
15836 // If page-box has changed AND/OR PAGE-BREAK-BEFORE
15837 $save_cols = false;
15838 if (($pagesel && $pagesel != $this->page_box['current']) || (isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE'])) {
15839 if ($this->blklvl>1) {
15840 // Close any open block tags
15841 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
15842 // Output any text left in buffer
15843 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); $this->textbuffer=array(); }
15844 }
15845 /*-- COLUMNS --*/
15846 if ($this->ColActive) {
15847 $save_cols = true;
15848 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
15849 $this->SetColumns(0);
15850 }
15851 /*-- END COLUMNS --*/
15852
15853 // Must Add new page if changed page properties
15854 if (isset($properties['PAGE-BREAK-BEFORE'])) {
15855 if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15856 else if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15857 else if (strtoupper($properties['PAGE-BREAK-BEFORE']) == 'ALWAYS') { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15858 else if ($this->page_box['current'] != $pagesel) { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); } // *CSS-PAGE*
15859 }
15860 /*-- CSS-PAGE --*/
15861 else if ($pagesel != $this->page_box['current']) { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
15862 /*-- END CSS-PAGE --*/
15863
15864 // if using htmlheaders, the headers need to be rewritten when new page
15865 // done by calling WriteHTML() within resethtmlheaders
15866 // so block is reset to 0 - now we need to resurrect it
15867 // As in WriteHTML() initialising
15868 if (!($this->restoreBlockPagebreaks && isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE'])) {
15869 $this->blklvl = 0;
15870 $this->lastblocklevelchange = 0;
15871 $this->blk = array();
15872 $this->initialiseBlock($this->blk[0]);
15873 $this->blk[0]['width'] =& $this->pgwidth;
15874 $this->blk[0]['inner_width'] =& $this->pgwidth;
15875 $this->blk[0]['blockContext'] = $this->blockContext;
15876 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
15877 $this->setCSS($properties,'','BODY');
15878 $this->blklvl++;
15879 $currblk =& $this->blk[$this->blklvl];
15880 $prevblk =& $this->blk[$this->blklvl-1];
15881
15882 $this->initialiseBlock($currblk);
15883 $currblk['tag'] = $tag;
15884 $currblk['attr'] = $attr;
15885
15886 $this->Reset();
15887 $properties = $this->cssmgr->MergeCSS('BLOCK',$tag,$attr);
15888 }
15889 /*-- COLUMNS --*/
15890 if ($save_cols) {
15891 // Restore columns
15892 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
15893 }
15894 /*-- END COLUMNS --*/
15895 if ($this->restoreBlockPagebreaks && isset($properties['PAGE-BREAK-BEFORE']) && $properties['PAGE-BREAK-BEFORE']) {
15896 $this->blk = $save_blk;
15897 // Re-open block tags
15898 $t = $this->blk[0]['tag'];
15899 $a = $this->blk[0]['attr'];
15900 $this->blklvl = 0;
15901 for ($b=0; $b<=$save_blklvl;$b++) {
15902 $tc = $t;
15903 $ac = $a;
15904 $t = $this->blk[$b+1]['tag'];
15905 $a = $this->blk[$b+1]['attr'];
15906 unset($this->blk[$b+1]);
15907 $this->OpenTag($tc,$ac);
15908 }
15909 $this->InlineProperties = $save_ilp;
15910 $this->restoreInlineProperties($save_silp);
15911 }
15912 }
15913
15914 if (isset($properties['PAGE-BREAK-INSIDE']) && strtoupper($properties['PAGE-BREAK-INSIDE']) == 'AVOID' && !$this->ColActive && !$this->keep_block_together) {
15915 $currblk['keep_block_together'] = 1;
15916 $this->kt_y00 = $this->y;
15917 $this->kt_p00 = $this->page;
15918 $this->keep_block_together = 1;
15919 $this->divbuffer = array();
15920 $this->ktLinks = array();
15921 $this->ktAnnots = array();
15922 $this->ktForms = array();
15923 $this->ktBlock = array();
15924 $this->ktReference = array();
15925 $this->ktBMoutlines = array();
15926 $this->_kttoc = array();
15927 }
15928 if ($lastbottommargin && isset($properties['MARGIN-TOP']) && $properties['MARGIN-TOP'] && empty($properties['FLOAT'])) { $currblk['lastbottommargin'] = $lastbottommargin; }
15929
15930 // mPDF 5.6.01 - LAYERS
15931 if (isset($properties['Z-INDEX']) && $this->currentlayer==0) {
15932 $v = intval($properties['Z-INDEX']);
15933 if ($v > 0) {
15934 $currblk['z-index'] = $v;
15935 $this->BeginLayer($v);
15936 }
15937 }
15938
15939 $this->setCSS($properties,'BLOCK',$tag); //name(id/class/style) found in the CSS array!
15940 $currblk['InlineProperties'] = $this->saveInlineProperties();
15941
15942 if (isset($properties['VISIBILITY'])) {
15943 $v = strtolower($properties['VISIBILITY']);
15944 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible' && !$this->tableLevel) {
15945 $currblk['visibility'] = $v;
15946 $this->SetVisibility($v);
15947 }
15948 }
15949
15950 if(isset($attr['DIR']) && $attr['DIR']) { $currblk['direction'] = strtolower($attr['DIR']); }
15951 if(isset($attr['ALIGN']) && $attr['ALIGN']) { $currblk['block-align'] = $align[strtolower($attr['ALIGN'])]; }
15952
15953 if (isset($properties['HEIGHT'])) {
15954 $currblk['css_set_height'] = $this->ConvertSize($properties['HEIGHT'],($this->h - $this->tMargin - $this->bMargin),$this->FontSize,false);
15955 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); }
15956 }
15957 else { $currblk['css_set_height'] = false; }
15958
15959
15960 // Added mPDF 3.0 Float DIV
15961 if (isset($prevblk['blockContext'])) { $currblk['blockContext'] = $prevblk['blockContext'] ; } // *CSS-FLOAT*
15962
15963 if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']), $this->blklvl-1); } // *CSS-FLOAT*
15964
15965 $container_w = $prevblk['inner_width'];
15966 $bdr = $currblk['border_right']['w'];
15967 $bdl = $currblk['border_left']['w'];
15968 $pdr = $currblk['padding_right'];
15969 $pdl = $currblk['padding_left'];
15970
15971 if (isset($currblk['css_set_width'])) { $setwidth = $currblk['css_set_width']; }
15972 else { $setwidth = 0; }
15973
15974 /*-- CSS-FLOAT --*/
15975 if (isset($properties['FLOAT']) && strtoupper($properties['FLOAT']) == 'RIGHT' && !$this->ColActive) {
15976 // Cancel Keep-Block-together
15977 $currblk['keep_block_together'] = false;
15978 $this->kt_y00 = '';
15979 $this->keep_block_together = 0;
15980
15981 $this->blockContext++;
15982 $currblk['blockContext'] = $this->blockContext;
15983
15984 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
15985
15986 // DIV is too narrow for text to fit!
15987 $maxw = $container_w - $l_width - $r_width;
15988 if (($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) > $maxw || ($maxw - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) < (2*$this->GetCharWidth('W',false))) {
15989 // Too narrow to fit - try to move down past L or R float
15990 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))) {
15991 $this->ClearFloats('LEFT', $this->blklvl-1);
15992 }
15993 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))) {
15994 $this->ClearFloats('RIGHT', $this->blklvl-1);
15995 }
15996 else { $this->ClearFloats('BOTH', $this->blklvl-1); }
15997 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
15998 }
15999
16000 if ($r_exists) { $currblk['margin_right'] += $r_width; }
16001
16002 $currblk['float'] = 'R';
16003 $currblk['float_start_y'] = $this->y;
16004 if ($currblk['css_set_width']) {
16005 $currblk['margin_left'] = $container_w - ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
16006 $currblk['float_width'] = ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
16007 }
16008 else {
16009 // *** If no width set - would need to buffer and keep track of max width, then Right-align if not full width
16010 // and do borders and backgrounds - For now - just set to maximum width left
16011
16012 if ($l_exists) { $currblk['margin_left'] += $l_width; }
16013 $currblk['css_set_width'] = $container_w - ($currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr);
16014
16015 $currblk['float_width'] = ($currblk['css_set_width'] + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
16016 }
16017 }
16018 else if (isset($properties['FLOAT']) && strtoupper($properties['FLOAT']) == 'LEFT' && !$this->ColActive) {
16019 // Cancel Keep-Block-together
16020 $currblk['keep_block_together'] = false;
16021 $this->kt_y00 = '';
16022 $this->keep_block_together = 0;
16023
16024 $this->blockContext++;
16025 $currblk['blockContext'] = $this->blockContext;
16026
16027 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
16028
16029 // DIV is too narrow for text to fit!
16030 $maxw = $container_w - $l_width - $r_width;
16031 if (($setwidth + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr) > $maxw || ($maxw - ($currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr)) < (2*$this->GetCharWidth('W',false))) {
16032 // Too narrow to fit - try to move down past L or R float
16033 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))) {
16034 $this->ClearFloats('LEFT', $this->blklvl-1);
16035 }
16036 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))) {
16037 $this->ClearFloats('RIGHT', $this->blklvl-1);
16038 }
16039 else { $this->ClearFloats('BOTH', $this->blklvl-1); }
16040 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
16041 }
16042
16043 if ($l_exists) { $currblk['margin_left'] += $l_width; }
16044
16045 $currblk['float'] = 'L';
16046 $currblk['float_start_y'] = $this->y;
16047 if ($setwidth) {
16048 $currblk['margin_right'] = $container_w - ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
16049 $currblk['float_width'] = ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
16050 }
16051 else {
16052 // *** If no width set - would need to buffer and keep track of max width, then Right-align if not full width
16053 // and do borders and backgrounds - For now - just set to maximum width left
16054
16055 if ($r_exists) { $currblk['margin_right'] += $r_width; }
16056 $currblk['css_set_width'] = $container_w - ($currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr);
16057
16058 $currblk['float_width'] = ($currblk['css_set_width'] + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
16059 }
16060 }
16061
16062 else {
16063 // Don't allow overlap - if floats present - adjust padding to avoid overlap with Floats
16064 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
16065 $maxw = $container_w - $l_width - $r_width;
16066 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))) {
16067 // Too narrow to fit - try to move down past L or R float
16068 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))) {
16069 $this->ClearFloats('LEFT', $this->blklvl-1);
16070 }
16071 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))) {
16072 $this->ClearFloats('RIGHT', $this->blklvl-1);
16073 }
16074 else { $this->ClearFloats('BOTH', $this->blklvl-1); }
16075 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
16076 }
16077 if ($r_exists) { $currblk['padding_right'] = max(($r_width-$currblk['margin_right']-$bdr), $pdr); }
16078 if ($l_exists) { $currblk['padding_left'] = max(($l_width-$currblk['margin_left']-$bdl), $pdl); }
16079 }
16080 /*-- END CSS-FLOAT --*/
16081
16082
16083 /*-- BORDER-RADIUS --*/
16084 // Automatically increase padding if required for border-radius
16085 if ($this->autoPadding && !$this->ColActive && !$this->keep_block_together) {
16086 if ($currblk['border_radius_TL_H']>$currblk['padding_left'] && $currblk['border_radius_TL_V']>$currblk['padding_top']) {
16087 if ($currblk['border_radius_TL_H']>$currblk['border_radius_TL_V']) {
16088 $this->_borderPadding($currblk['border_radius_TL_H'],$currblk['border_radius_TL_V'], $currblk['padding_left'], $currblk['padding_top']);
16089 }
16090 else {
16091 $this->_borderPadding($currblk['border_radius_TL_V'],$currblk['border_radius_TL_H'], $currblk['padding_top'], $currblk['padding_left']);
16092 }
16093 }
16094 if ($currblk['border_radius_TR_H']>$currblk['padding_right'] && $currblk['border_radius_TR_V']>$currblk['padding_top']) {
16095 if ($currblk['border_radius_TR_H']>$currblk['border_radius_TR_V']) {
16096 $this->_borderPadding($currblk['border_radius_TR_H'],$currblk['border_radius_TR_V'], $currblk['padding_right'], $currblk['padding_top']);
16097 }
16098 else {
16099 $this->_borderPadding($currblk['border_radius_TR_V'],$currblk['border_radius_TR_H'], $currblk['padding_top'], $currblk['padding_right']);
16100 }
16101 }
16102 if ($currblk['border_radius_BL_H']>$currblk['padding_left'] && $currblk['border_radius_BL_V']>$currblk['padding_bottom']) {
16103 if ($currblk['border_radius_BL_H']>$currblk['border_radius_BL_V']) {
16104 $this->_borderPadding($currblk['border_radius_BL_H'],$currblk['border_radius_BL_V'], $currblk['padding_left'], $currblk['padding_bottom']);
16105 }
16106 else {
16107 $this->_borderPadding($currblk['border_radius_BL_V'],$currblk['border_radius_BL_H'], $currblk['padding_bottom'], $currblk['padding_left']);
16108 }
16109 }
16110 if ($currblk['border_radius_BR_H']>$currblk['padding_right'] && $currblk['border_radius_BR_V']>$currblk['padding_bottom']) {
16111 if ($currblk['border_radius_BR_H']>$currblk['border_radius_BR_V']) {
16112 $this->_borderPadding($currblk['border_radius_BR_H'],$currblk['border_radius_BR_V'], $currblk['padding_right'], $currblk['padding_bottom']);
16113 }
16114 else {
16115 $this->_borderPadding($currblk['border_radius_BR_V'],$currblk['border_radius_BR_H'], $currblk['padding_bottom'], $currblk['padding_right']);
16116 }
16117 }
16118 }
16119 /*-- END BORDER-RADIUS --*/
16120
16121
16122 // Hanging indent - if negative indent: ensure padding is >= indent
16123 if(!isset($currblk['text_indent'])) { $currblk['text_indent'] = null; }
16124 if(!isset($currblk['inner_width'])) { $currblk['inner_width'] = null; }
16125 $cbti = $this->ConvertSize($currblk['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16126 if ($cbti < 0) {
16127 $hangind = -($cbti);
16128 if ($currblk['direction'] == 'rtl') { // *RTL*
16129 $currblk['padding_right'] = max($currblk['padding_right'],$hangind); // *RTL*
16130 } // *RTL*
16131 else { // *RTL*
16132 $currblk['padding_left'] = max($currblk['padding_left'],$hangind);
16133 } // *RTL*
16134 }
16135
16136 if (isset($currblk['css_set_width'])) {
16137 if (isset($properties['MARGIN-LEFT']) && isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-LEFT'])=='auto' && strtolower($properties['MARGIN-RIGHT'])=='auto') {
16138 // Try to reduce margins to accomodate - if still too wide, set margin-right/left=0 (reduces width)
16139 $anyextra = $prevblk['inner_width'] - ($currblk['css_set_width'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right']);
16140 if ($anyextra>0) {
16141 $currblk['margin_left'] = $currblk['margin_right'] = $anyextra /2;
16142 }
16143 else {
16144 $currblk['margin_left'] = $currblk['margin_right'] = 0;
16145 }
16146 }
16147 else if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
16148 // Try to reduce margin-left to accomodate - if still too wide, set margin-left=0 (reduces width)
16149 $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']);
16150 if ($currblk['margin_left'] < 0) {
16151 $currblk['margin_left'] = 0;
16152 }
16153 }
16154 else if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
16155 // Try to reduce margin-right to accomodate - if still too wide, set margin-right=0 (reduces width)
16156 $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']);
16157 if ($currblk['margin_right'] < 0) {
16158 $currblk['margin_right'] = 0;
16159 }
16160 }
16161 else {
16162 if ($currblk['direction'] == 'rtl') { // *RTL*
16163 // Try to reduce margin-left to accomodate - if still too wide, set margin-left=0 (reduces width)
16164 $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*
16165 if ($currblk['margin_left'] < 0) { // *RTL*
16166 $currblk['margin_left'] = 0; // *RTL*
16167 } // *RTL*
16168 } // *RTL*
16169 else { // *RTL*
16170 // Try to reduce margin-right to accomodate - if still too wide, set margin-right=0 (reduces width)
16171 $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']);
16172 if ($currblk['margin_right'] < 0) {
16173 $currblk['margin_right'] = 0;
16174 }
16175 } // *RTL*
16176 }
16177 }
16178
16179 $currblk['outer_left_margin'] = $prevblk['outer_left_margin'] + $currblk['margin_left'] + $prevblk['border_left']['w'] + $prevblk['padding_left'];
16180 $currblk['outer_right_margin'] = $prevblk['outer_right_margin'] + $currblk['margin_right'] + $prevblk['border_right']['w'] + $prevblk['padding_right'];
16181
16182 $currblk['width'] = $this->pgwidth - ($currblk['outer_right_margin'] + $currblk['outer_left_margin']);
16183 $currblk['inner_width'] = $currblk['width'] - ($currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right']);
16184
16185 // Check DIV is not now too narrow to fit text
16186 $mw = 2*$this->GetCharWidth('W',false);
16187 if ($currblk['inner_width'] < $mw) {
16188 $currblk['padding_left'] = 0;
16189 $currblk['padding_right'] = 0;
16190 $currblk['border_left']['w'] = 0.2;
16191 $currblk['border_right']['w'] = 0.2;
16192 $currblk['margin_left'] = 0;
16193 $currblk['margin_right'] = 0;
16194 $currblk['outer_left_margin'] = $prevblk['outer_left_margin'] + $currblk['margin_left'] + $prevblk['border_left']['w'] + $prevblk['padding_left'];
16195 $currblk['outer_right_margin'] = $prevblk['outer_right_margin'] + $currblk['margin_right'] + $prevblk['border_right']['w'] + $prevblk['padding_right'];
16196 $currblk['width'] = $this->pgwidth - ($currblk['outer_right_margin'] + $currblk['outer_left_margin']);
16197 $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']);
16198 // if ($currblk['inner_width'] < $mw) { $this->Error("DIV is too narrow for text to fit!"); }
16199 }
16200
16201 $this->x = $this->lMargin + $currblk['outer_left_margin'];
16202
16203 /*-- BACKGROUNDS --*/
16204 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive && !$this->keep_block_together) {
16205 $ret = $this->SetBackground($properties, $currblk['inner_width']);
16206 if ($ret) { $currblk['background-image'] = $ret; }
16207 }
16208 /*-- END BACKGROUNDS --*/
16209
16210 /*-- TABLES --*/
16211 if ($this->use_kwt && isset($attr['KEEP-WITH-TABLE']) && !$this->ColActive && !$this->keep_block_together) {
16212 $this->kwt = true;
16213 $this->kwt_y0 = $this->y;
16214 $this->kwt_x0 = $this->x;
16215 $this->kwt_height = 0;
16216 $this->kwt_buffer = array();
16217 $this->kwt_Links = array();
16218 $this->kwt_Annots = array();
16219 $this->kwt_moved = false;
16220 $this->kwt_saved = false;
16221 $this->kwt_Reference = array();
16222 $this->kwt_BMoutlines = array();
16223 $this->kwt_toc = array();
16224 }
16225 else {
16226 /*-- END TABLES --*/
16227 $this->kwt = false;
16228 } // *TABLES*
16229
16230 //Save x,y coords in case we need to print borders...
16231 $currblk['y0'] = $this->y;
16232 $currblk['x0'] = $this->x;
16233 $currblk['startpage'] = $this->page;
16234 $this->oldy = $this->y;
16235
16236 $this->lastblocklevelchange = 1 ;
16237
16238 break;
16239
16240 case 'HR':
16241 // Added mPDF 3.0 Float DIV - CLEAR
16242 if (isset($attr['STYLE'])) {
16243 $properties = $this->cssmgr->readInlineCSS($attr['STYLE']);
16244 if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']),$this->blklvl); } // *CSS-FLOAT*
16245 }
16246
16247 $this->ignorefollowingspaces = true;
16248
16249 $objattr = array();
16250 $objattr['margin_top'] = 0;
16251 $objattr['margin_bottom'] = 0;
16252 $objattr['margin_left'] = 0;
16253 $objattr['margin_right'] = 0;
16254 $objattr['width'] = 0;
16255 $objattr['height'] = 0;
16256 $objattr['border_top']['w'] = 0;
16257 $objattr['border_bottom']['w'] = 0;
16258 $objattr['border_left']['w'] = 0;
16259 $objattr['border_right']['w'] = 0;
16260 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16261 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top'] = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16262 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16263 if (isset($properties['WIDTH'])) { $objattr['width'] = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']); }
16264 else if(isset($attr['WIDTH']) && $attr['WIDTH'] != '') $objattr['width'] = $this->ConvertSize($attr['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
16265 if (isset($properties['TEXT-ALIGN'])) { $objattr['align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
16266 else if(isset($attr['ALIGN']) && $attr['ALIGN'] != '') $objattr['align'] = $align[strtolower($attr['ALIGN'])];
16267
16268 if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
16269 $objattr['align'] = 'R';
16270 }
16271 if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
16272 $objattr['align'] = 'L';
16273 if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto' && isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
16274 $objattr['align'] = 'C';
16275 }
16276 }
16277 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16278 else if(isset($attr['COLOR']) && $attr['COLOR'] != '') $objattr['color'] = $this->ConvertColor($attr['COLOR']);
16279 if (isset($properties['HEIGHT'])) { $objattr['linewidth'] = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16280
16281
16282 /*-- TABLES --*/
16283 if ($this->tableLevel) {
16284 $objattr['W-PERCENT'] = 100;
16285 if (isset($properties['WIDTH']) && stristr($properties['WIDTH'],'%')) {
16286 $properties['WIDTH'] += 0; //make "90%" become simply "90"
16287 $objattr['W-PERCENT'] = $properties['WIDTH'];
16288 }
16289 if (isset($attr['WIDTH']) && stristr($attr['WIDTH'],'%')) {
16290 $attr['WIDTH'] += 0; //make "90%" become simply "90"
16291 $objattr['W-PERCENT'] = $attr['WIDTH'];
16292 }
16293 }
16294 /*-- END TABLES --*/
16295
16296 $objattr['type'] = 'hr';
16297 $objattr['height'] = $objattr['linewidth'] + $objattr['margin_top'] + $objattr['margin_bottom'];
16298 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
16299
16300 // Clear properties - tidy up
16301 $properties = array();
16302
16303 /*-- TABLES --*/
16304 // Output it to buffers
16305 if ($this->tableLevel) {
16306 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
16307 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
16308 }
16309 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
16310 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
16311 }
16312 $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
16313 $this->_saveCellTextBuffer($e, $this->HREF);
16314 }
16315 else {
16316 /*-- END TABLES --*/
16317 $this->_saveTextBuffer($e, $this->HREF);
16318 } // *TABLES*
16319
16320 break;
16321
16322
16323 /*-- BARCODES --*/
16324
16325 case 'BARCODE':
16326 if(isset($attr['CODE']) && $attr['CODE']) {
16327 $objattr = array();
16328 $objattr['margin_top'] = 0;
16329 $objattr['margin_bottom'] = 0;
16330 $objattr['margin_left'] = 0;
16331 $objattr['margin_right'] = 0;
16332 $objattr['padding_top'] = 0;
16333 $objattr['padding_bottom'] = 0;
16334 $objattr['padding_left'] = 0;
16335 $objattr['padding_right'] = 0;
16336 $objattr['width'] = 0;
16337 $objattr['height'] = 0;
16338 $objattr['border_top']['w'] = 0;
16339 $objattr['border_bottom']['w'] = 0;
16340 $objattr['border_left']['w'] = 0;
16341 $objattr['border_right']['w'] = 0;
16342 $objattr['code'] = $attr['CODE'];
16343
16344 if(isset($attr['TYPE'])) {
16345 $objattr['btype'] = trim(strtoupper($attr['TYPE']));
16346 }
16347 else { $objattr['btype'] = 'EAN13'; } // default
16348 if (preg_match('/^(EAN13|ISBN|ISSN|EAN8|UPCA|UPCE)P([25])$/',$objattr['btype'],$m)) {
16349 $objattr['btype'] = $m[1];
16350 $objattr['bsupp'] = $m[2];
16351 if (preg_match('/^(\S+)\s+(.*)$/',$objattr['code'],$mm)) {
16352 $objattr['code'] = $mm[1];
16353 $objattr['bsupp_code'] = $mm[2];
16354 }
16355 }
16356 else { $objattr['bsupp'] = 0; }
16357
16358 if(isset($attr['TEXT']) && $attr['TEXT']==1) { $objattr['showtext'] = 1; }
16359 else { $objattr['showtext'] = 0; }
16360 if(isset($attr['SIZE']) && $attr['SIZE']>0) { $objattr['bsize'] = $attr['SIZE']; }
16361 else { $objattr['bsize'] = 1; }
16362 if(isset($attr['HEIGHT']) && $attr['HEIGHT']>0) { $objattr['bheight'] = $attr['HEIGHT']; }
16363 else { $objattr['bheight'] = 1; }
16364 if(isset($attr['PR']) && $attr['PR']>0) { $objattr['pr_ratio'] = $attr['PR']; }
16365 else { $objattr['pr_ratio'] = ''; }
16366 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16367 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
16368 return;
16369 }
16370 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16371 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16372 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16373 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16374
16375 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16376 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16377 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16378 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16379
16380 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
16381 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
16382 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
16383 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
16384
16385 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16386 if (isset($properties['COLOR']) && $properties['COLOR'] != '') { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16387 else { $objattr['color'] = false; }
16388 if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { $objattr['bgcolor'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
16389 else { $objattr['bgcolor'] = false; }
16390
16391 if (!class_exists('PDFBarcode', false)) {
16392 include(_MPDF_PATH.'classes/barcode.php');
16393 }
16394 $this->barcode = new PDFBarcode();
16395
16396 if ($objattr['btype'] == 'EAN13' || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN' || $objattr['btype'] == 'UPCA' || $objattr['btype'] == 'UPCE' || $objattr['btype'] == 'EAN8') {
16397 $code = preg_replace('/\-/','',$objattr['code']);
16398 if ($objattr['btype'] == 'ISSN' || $objattr['btype'] == 'ISBN') {
16399 $arrcode = $this->barcode->getBarcodeArray($code, 'EAN13');
16400 }
16401 else { $arrcode = $this->barcode->getBarcodeArray($code, $objattr['btype'] ); }
16402 if ($arrcode === false) { $this->Error('Error in barcode string.'); }
16403
16404 if ($objattr['bsupp'] == 2 || $objattr['bsupp'] == 5) { // EAN-2 or -5 Supplement
16405 $supparrcode = $this->barcode->getBarcodeArray($objattr['bsupp_code'], 'EAN'.$objattr['bsupp'] );
16406 $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR'] + $supparrcode["maxw"] + $supparrcode['sepM']) * $arrcode['nom-X'] * $objattr['bsize'];
16407 }
16408 else {
16409 $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR']) * $arrcode['nom-X'] * $objattr['bsize'];
16410 }
16411 $h = $arrcode['nom-H'] * $objattr['bsize'] * $objattr['bheight'];
16412 // Add height for ISBN string + margin from top of bars
16413 if (($objattr['showtext'] && $objattr['btype'] == 'EAN13') || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN') {
16414 $tisbnm = 1.5 * $objattr['bsize']; // Top margin between TOP TEXT (isbn - if shown) & bars
16415 $isbn_fontsize = 2.1 * $objattr['bsize'];
16416 $h += $isbn_fontsize + $tisbnm ;
16417 }
16418 }
16419 // QR-code
16420 else if ($objattr['btype'] == 'QR') {
16421 $w = $h = $objattr['bsize']*25; // Factor of 25mm (default)
16422 $objattr['errorlevel'] = 'L';
16423 if (isset($attr['ERROR'])) { $objattr['errorlevel'] = $attr['ERROR']; }
16424 }
16425 else if ($objattr['btype'] == 'IMB' || $objattr['btype'] == 'RM4SCC' || $objattr['btype'] == 'KIX' || $objattr['btype'] == 'POSTNET' || $objattr['btype'] == 'PLANET') {
16426 $arrcode = $this->barcode->getBarcodeArray($objattr['code'], $objattr['btype'] );
16427 if ($arrcode === false) { $this->Error('Error in barcode string.'); }
16428 $w = ($arrcode["maxw"] * $arrcode['nom-X'] * $objattr['bsize']) + $arrcode['quietL'] + $arrcode['quietR'];
16429 $h = ($arrcode['nom-H'] * $objattr['bsize']) + (2*$arrcode['quietTB']);
16430 }
16431 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'))) {
16432 $arrcode = $this->barcode->getBarcodeArray($objattr['code'], $objattr['btype'], $objattr['pr_ratio'] );
16433 if ($arrcode === false) { $this->Error('Error in barcode string.'); }
16434 $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR']) * $arrcode['nom-X'] * $objattr['bsize'];
16435 $h = ((2*$arrcode['lightTB'] * $arrcode['nom-X']) + $arrcode['nom-H']) * $objattr['bsize'] * $objattr['bheight'];
16436 }
16437 else { break; }
16438
16439 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
16440 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
16441
16442 $objattr['type'] = 'barcode';
16443 $objattr['height'] = $h + $extraheight;
16444 $objattr['width'] = $w + $extrawidth;
16445 $objattr['barcode_height'] = $h;
16446 $objattr['barcode_width'] = $w;
16447 /*-- CSS-IMAGE-FLOAT --*/
16448 if (!$this->ColActive && !$this->tableLevel && !$this->listlvl && !$this->kwt && !$this->keep_block_together) {
16449 if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) == 'RIGHT' || strtoupper($properties['FLOAT']) == 'LEFT')) {
16450 $objattr['float'] = substr(strtoupper($properties['FLOAT']),0,1);
16451 }
16452 }
16453 /*-- END CSS-IMAGE-FLOAT --*/
16454
16455 $e = "\xbb\xa4\xactype=barcode,objattr=".serialize($objattr)."\xbb\xa4\xac";
16456
16457 // Clear properties - tidy up
16458 $properties = array();
16459
16460 /*-- TABLES --*/
16461 // Output it to buffers
16462 if ($this->tableLevel) {
16463 $this->_saveCellTextBuffer($e, $this->HREF);
16464 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
16465 }
16466 else {
16467 /*-- END TABLES --*/
16468 $this->_saveTextBuffer($e, $this->HREF);
16469
16470 } // *TABLES*
16471 }
16472 break;
16473 /*-- END BARCODES --*/
16474
16475
16476 // *********** FORM ELEMENTS ********************
16477
16478 /*-- FORMS --*/
16479 case 'SELECT':
16480 $this->lastoptionaltag = ''; // Save current HTML specified optional endtag
16481 $this->InlineProperties[$tag] = $this->saveInlineProperties();
16482 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16483 if (isset($properties['FONT-FAMILY'])) {
16484 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
16485 }
16486 if (isset($properties['FONT-SIZE'])) {
16487 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
16488 $this->SetFontSize($mmsize*_MPDFK,false);
16489 }
16490 if (isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') {
16491 $this->selectoption['SPELLCHECK'] = true;
16492 }
16493
16494 if (isset($properties['COLOR'])) { $this->selectoption['COLOR'] = $this->ConvertColor($properties['COLOR']); }
16495 $this->specialcontent = "type=select";
16496 if(isset($attr['DISABLED'])) { $this->selectoption['DISABLED'] = $attr['DISABLED']; }
16497 if(isset($attr['READONLY'])) { $this->selectoption['READONLY'] = $attr['READONLY']; }
16498 if(isset($attr['REQUIRED'])) { $this->selectoption['REQUIRED'] = $attr['REQUIRED']; }
16499 if(isset($attr['EDITABLE'])) { $this->selectoption['EDITABLE'] = $attr['EDITABLE']; }
16500 if(isset($attr['TITLE'])) { $this->selectoption['TITLE'] = $attr['TITLE']; }
16501 if(isset($attr['MULTIPLE'])) { $this->selectoption['MULTIPLE'] = $attr['MULTIPLE']; }
16502 if(isset($attr['SIZE']) && $attr['SIZE']>1) { $this->selectoption['SIZE'] = $attr['SIZE']; }
16503 if ($this->useActiveForms) {
16504 if(isset($attr['NAME'])) { $this->selectoption['NAME'] = $attr['NAME']; }
16505 if (isset($attr['ONCHANGE'])) { $this->selectoption['ONCHANGE'] = $attr['ONCHANGE']; }
16506 }
16507
16508 $properties = array();
16509 break;
16510
16511 case 'OPTION':
16512 $this->lastoptionaltag = 'OPTION'; // Save current HTML specified optional endtag
16513 $this->selectoption['ACTIVE'] = true;
16514 $this->selectoption['currentSEL'] = false;
16515 if (empty($this->selectoption)) {
16516 $this->selectoption['MAXWIDTH'] = '';
16517 $this->selectoption['SELECTED'] = '';
16518 }
16519 if (isset($attr['SELECTED'])) {
16520 $this->selectoption['SELECTED'] = '';
16521 $this->selectoption['currentSEL'] = true;
16522 }
16523 if(isset($attr['VALUE'])) {
16524 $attr['VALUE'] = strcode2utf($attr['VALUE']);
16525 $attr['VALUE'] = $this->lesser_entity_decode($attr['VALUE']);
16526 if ($this->onlyCoreFonts)
16527 $attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mb_enc,'UTF-8');
16528 }
16529 $this->selectoption['currentVAL'] = $attr['VALUE'];
16530 break;
16531
16532 case 'TEXTAREA':
16533 $objattr = array();
16534 $objattr['margin_top'] = 0;
16535 $objattr['margin_bottom'] = 0;
16536 $objattr['margin_left'] = 0;
16537 $objattr['margin_right'] = 0;
16538 $objattr['width'] = 0;
16539 $objattr['height'] = 0;
16540 $objattr['border_top']['w'] = 0;
16541 $objattr['border_bottom']['w'] = 0;
16542 $objattr['border_left']['w'] = 0;
16543 $objattr['border_right']['w'] = 0;
16544 if(isset($attr['DISABLED'])) { $objattr['disabled'] = true; }
16545 if(isset($attr['READONLY'])) { $objattr['readonly'] = true; }
16546 if(isset($attr['REQUIRED'])) { $objattr['required'] = true; }
16547 if(isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') { $objattr['spellcheck'] = true; }
16548 if(isset($attr['TITLE'])) { $objattr['title'] = $attr['TITLE']; }
16549 if ($this->onlyCoreFonts)
16550 $objattr['title'] = mb_convert_encoding($objattr['title'], $this->mb_enc,'UTF-8');
16551 if ($this->useActiveForms) {
16552 if(isset($attr['NAME'])) { $objattr['fieldname'] = $attr['NAME']; }
16553 $this->form->form_element_spacing['textarea']['outer']['v'] = 0;
16554 $this->form->form_element_spacing['textarea']['inner']['v'] = 0;
16555 if (isset($attr['ONCALCULATE'])) { $objattr['onCalculate'] = $attr['ONCALCULATE']; }
16556 else if (isset($attr['ONCHANGE'])) { $objattr['onCalculate'] = $attr['ONCHANGE']; }
16557 if (isset($attr['ONVALIDATE'])) { $objattr['onValidate'] = $attr['ONVALIDATE']; }
16558 if (isset($attr['ONKEYSTROKE'])) { $objattr['onKeystroke'] = $attr['ONKEYSTROKE']; }
16559 if (isset($attr['ONFORMAT'])) { $objattr['onFormat'] = $attr['ONFORMAT']; }
16560 }
16561 $this->InlineProperties[$tag] = $this->saveInlineProperties();
16562 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16563 if (isset($properties['FONT-FAMILY'])) {
16564 $this->SetFont($properties['FONT-FAMILY'],'',0,false);
16565 }
16566 if (isset($properties['FONT-SIZE'])) {
16567 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
16568 $this->SetFontSize($mmsize*_MPDFK,false);
16569 }
16570 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16571 $objattr['fontfamily'] = $this->FontFamily;
16572 $objattr['fontsize'] = $this->FontSizePt;
16573 if ($this->useActiveForms) {
16574 if(isset($properties['TEXT-ALIGN'])) { $objattr['text_align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
16575 else if(isset($attr['ALIGN'])) { $objattr['text_align'] = $align[strtolower($attr['ALIGN'])]; }
16576 if (isset($properties['OVERFLOW']) && strtolower($properties['OVERFLOW'])=='hidden') { $objattr['donotscroll'] = true; }
16577 if (isset($properties['BORDER-TOP-COLOR'])) { $objattr['border-col'] = $this->ConvertColor($properties['BORDER-TOP-COLOR']); }
16578 if (isset($properties['BACKGROUND-COLOR'])) { $objattr['background-col'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
16579 }
16580 $this->SetLineHeight('',$this->form->textarea_lineheight);
16581 $formLineHeight = $this->lineheight;
16582
16583 $w = 0;
16584 $h = 0;
16585 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16586 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
16587 if ($properties['VERTICAL-ALIGN']) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16588
16589 $colsize = 20; //HTML default value
16590 $rowsize = 2; //HTML default value
16591 if (isset($attr['COLS'])) $colsize = intval($attr['COLS']);
16592 if (isset($attr['ROWS'])) $rowsize = intval($attr['ROWS']);
16593
16594 $charsize = $this->GetCharWidth('w',false);
16595 if ($w) { $colsize = round(($w-($this->form->form_element_spacing['textarea']['outer']['h']*2)-($this->form->form_element_spacing['textarea']['inner']['h']*2))/$charsize); }
16596 if ($h) { $rowsize = round(($h-($this->form->form_element_spacing['textarea']['outer']['v']*2)-($this->form->form_element_spacing['textarea']['inner']['v']*2))/$formLineHeight); }
16597
16598 $objattr['type'] = 'textarea';
16599 $objattr['width'] = ($colsize * $charsize) + ($this->form->form_element_spacing['textarea']['outer']['h']*2)+($this->form->form_element_spacing['textarea']['inner']['h']*2);
16600 $objattr['height'] = ($rowsize * $formLineHeight) + ($this->form->form_element_spacing['textarea']['outer']['v']*2)+($this->form->form_element_spacing['textarea']['inner']['v']*2);
16601 $objattr['rows'] = $rowsize;
16602 $objattr['cols'] = $colsize;
16603
16604 $this->specialcontent = serialize($objattr);
16605
16606 if ($this->tableLevel) { // *TABLES*
16607 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ; // *TABLES*
16608 } // *TABLES*
16609
16610 // Clear properties - tidy up
16611 $properties = array();
16612 break;
16613
16614
16615
16616 // *********** FORM - INPUT ********************
16617
16618 case 'INPUT':
16619 if (!isset($attr['TYPE'])) $attr['TYPE'] == 'TEXT';
16620 $objattr = array();
16621 $objattr['margin_top'] = 0;
16622 $objattr['margin_bottom'] = 0;
16623 $objattr['margin_left'] = 0;
16624 $objattr['margin_right'] = 0;
16625 $objattr['width'] = 0;
16626 $objattr['height'] = 0;
16627 $objattr['border_top']['w'] = 0;
16628 $objattr['border_bottom']['w'] = 0;
16629 $objattr['border_left']['w'] = 0;
16630 $objattr['border_right']['w'] = 0;
16631 $objattr['type'] = 'input';
16632 if(isset($attr['DISABLED'])) { $objattr['disabled'] = true; }
16633 if(isset($attr['READONLY'])) { $objattr['readonly'] = true; }
16634 if(isset($attr['REQUIRED'])) { $objattr['required'] = true; }
16635 if(isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') { $objattr['spellcheck'] = true; }
16636 if(isset($attr['TITLE'])) { $objattr['title'] = $attr['TITLE']; }
16637 else if(isset($attr['ALT'])) { $objattr['title'] = $attr['ALT']; }
16638 else $objattr['title'] = '';
16639 $objattr['title'] = strcode2utf($objattr['title']);
16640 $objattr['title'] = $this->lesser_entity_decode($objattr['title']);
16641 if ($this->onlyCoreFonts)
16642 $objattr['title'] = mb_convert_encoding($objattr['title'], $this->mb_enc,'UTF-8');
16643 if ($this->useActiveForms) {
16644 if(isset($attr['NAME'])) { $objattr['fieldname'] = $attr['NAME']; }
16645 }
16646 if(isset($attr['VALUE'])) {
16647 $attr['VALUE'] = strcode2utf($attr['VALUE']);
16648 $attr['VALUE'] = $this->lesser_entity_decode($attr['VALUE']);
16649 if ($this->onlyCoreFonts)
16650 $attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mb_enc,'UTF-8');
16651 $objattr['value'] = $attr['VALUE'];
16652 }
16653
16654 $this->InlineProperties[$tag] = $this->saveInlineProperties();
16655 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16656 $objattr['vertical-align'] = '';
16657
16658 if (isset($properties['FONT-FAMILY'])) {
16659 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
16660 }
16661 if (isset($properties['FONT-SIZE'])) {
16662 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],($this->default_font_size/_MPDFK));
16663 $this->SetFontSize($mmsize*_MPDFK,false);
16664 }
16665 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
16666 $objattr['fontfamily'] = $this->FontFamily;
16667 $objattr['fontsize'] = $this->FontSizePt;
16668 if ($this->useActiveForms) {
16669 if(isset($attr['ALIGN'])) { $objattr['text_align'] = $align[strtolower($attr['ALIGN'])]; }
16670 else if(isset($properties['TEXT-ALIGN'])) { $objattr['text_align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
16671 if (isset($properties['BORDER-TOP-COLOR'])) { $objattr['border-col'] = $this->ConvertColor($properties['BORDER-TOP-COLOR']); }
16672 if (isset($properties['BACKGROUND-COLOR'])) { $objattr['background-col'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
16673 }
16674
16675 $type = '';
16676 $texto='';
16677 $height = $this->FontSize;
16678 $width = 0;
16679 $spacesize = $this->GetCharWidth(' ',false);
16680
16681 $w = 0;
16682 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
16683
16684 if ($properties['VERTICAL-ALIGN']) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16685
16686 switch(strtoupper($attr['TYPE'])){
16687 case 'HIDDEN':
16688 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
16689 if ($this->useActiveForms) {
16690 $this->form->SetFormText( 0, 0, $objattr['fieldname'], $objattr['value'], $objattr['value'], '', 0, '', true );
16691 }
16692 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
16693 unset($this->InlineProperties[$tag]);
16694 break 2;
16695 case 'CHECKBOX': //Draw Checkbox
16696 $type = 'CHECKBOX';
16697 if (isset($attr['CHECKED'])) { $objattr['checked'] = true; }
16698 else { $objattr['checked'] = false; }
16699 $width = $this->FontSize;
16700 $height = $this->FontSize;
16701 break;
16702
16703 case 'RADIO': //Draw Radio button
16704 $type = 'RADIO';
16705 if (isset($attr['CHECKED'])) $objattr['checked'] = true;
16706 $width = $this->FontSize;
16707 $height = $this->FontSize;
16708 break;
16709
16710 /*-- IMAGES-CORE --*/
16711 case 'IMAGE': // Draw an Image button
16712 if(isset($attr['SRC'])) {
16713 $type = 'IMAGE';
16714 $srcpath = $attr['SRC'];
16715 $orig_srcpath = $attr['ORIG_SRC'];
16716 // VSPACE and HSPACE converted to margins in MergeCSS
16717 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16718 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16719 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16720 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16721
16722
16723 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
16724 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
16725 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
16726 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
16727
16728 $objattr['padding_top'] = 0;
16729 $objattr['padding_bottom'] = 0;
16730 $objattr['padding_left'] = 0;
16731 $objattr['padding_right'] = 0;
16732
16733 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
16734
16735 $w = 0;
16736 $h = 0;
16737 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
16738 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width']);
16739
16740 $extraheight = $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
16741 $extrawidth = $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
16742
16743 // Image file
16744 $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
16745 if(!$info) {
16746 $info = $this->_getImage($this->noImageFile);
16747 if ($info) {
16748 $srcpath = $this->noImageFile;
16749 $w = ($info['w'] * (25.4/$this->dpi));
16750 $h = ($info['h'] * (25.4/$this->dpi));
16751 }
16752 }
16753 if(!$info) break;
16754 if ($info['cs']=='Indexed') { $objattr['Indexed'] = true; }
16755 $objattr['file'] = $srcpath;
16756 //Default width and height calculation if needed
16757 if($w==0 and $h==0) {
16758 /*-- IMAGES-WMF --*/
16759 if ($info['type']=='wmf') {
16760 // WMF units are twips (1/20pt)
16761 // divide by 20 to get points
16762 // divide by k to get user units
16763 $w = abs($info['w'])/(20*_MPDFK);
16764 $h = abs($info['h']) / (20*_MPDFK);
16765 }
16766 else
16767 /*-- END IMAGES-WMF --*/
16768 if ($info['type']=='svg') {
16769 // SVG units are pixels
16770 $w = abs($info['w'])/_MPDFK;
16771 $h = abs($info['h'])/_MPDFK;
16772 }
16773 else {
16774 //Put image at default image dpi
16775 $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
16776 $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
16777 }
16778 if (isset($properties['IMAGE-RESOLUTION'])) {
16779 if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi']>0) {
16780 $w *= $this->img_dpi / $info['set-dpi'];
16781 $h *= $this->img_dpi / $info['set-dpi'];
16782 }
16783 else if (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) {
16784 $dpi = $m[1];
16785 if ($dpi > 0) {
16786 $w *= $this->img_dpi / $dpi;
16787 $h *= $this->img_dpi / $dpi;
16788 }
16789 }
16790 }
16791 }
16792 // IF WIDTH OR HEIGHT SPECIFIED
16793 if($w==0) $w=$h*$info['w']/$info['h'];
16794 if($h==0) $h=$w*$info['h']/$info['w'];
16795 // Resize to maximum dimensions of page
16796 $maxWidth = $this->blk[$this->blklvl]['inner_width'];
16797 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 10) ;
16798 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
16799 if (($w + $extrawidth) > ($maxWidth + 0.0001) ) { // mPDF 5.7.4 0.0001 to allow for rounding errors when w==maxWidth
16800 $w = $maxWidth - $extrawidth;
16801 $h=$w*$info['h']/$info['w'];
16802 }
16803 if ($h + $extraheight > $maxHeight ) {
16804 $h = $maxHeight - $extraheight;
16805 $w=$h*$info['w']/$info['h'];
16806 }
16807 $height = $h + $extraheight;
16808 $width = $w + $extrawidth;
16809 $objattr['type'] = 'image';
16810 $objattr['itype'] = $info['type'];
16811 $objattr['orig_h'] = $info['h'];
16812 $objattr['orig_w'] = $info['w'];
16813 /*-- IMAGES-WMF --*/
16814 if ($info['type']=='wmf') {
16815 $objattr['wmf_x'] = $info['x'];
16816 $objattr['wmf_y'] = $info['y'];
16817 }
16818 else
16819 /*-- END IMAGES-WMF --*/
16820 if ($info['type']=='svg') {
16821 $objattr['wmf_x'] = $info['x'];
16822 $objattr['wmf_y'] = $info['y'];
16823 }
16824 $objattr['height'] = $h + $extraheight;
16825 $objattr['width'] = $w + $extrawidth;
16826
16827 $objattr['image_height'] = $h;
16828 $objattr['image_width'] = $w;
16829 $objattr['ID'] = $info['i'];
16830 $texto = 'X';
16831 if ($this->useActiveForms) {
16832 if (isset($attr['ONCLICK'])) { $objattr['onClick'] = $attr['ONCLICK']; }
16833 $objattr['type'] = 'input';
16834 $type = 'IMAGE';
16835 }
16836 break;
16837 }
16838 /*-- END IMAGES-CORE --*/
16839
16840 case 'BUTTON': // Draw a button
16841 case 'SUBMIT':
16842 case 'RESET':
16843 $type = strtoupper($attr['TYPE']);
16844 if ($type=='IMAGE') { $type = 'BUTTON'; } // src path not found
16845 if(isset($attr['NOPRINT'])) { $objattr['noprint'] = true; }
16846 if (!isset($attr['VALUE'])) {
16847 $objattr['value'] = ucfirst(strtolower($type));
16848 }
16849
16850 $texto = " " . $objattr['value'] . " ";
16851 $width = $this->GetStringWidth($texto) + ($this->form->form_element_spacing['button']['outer']['h']*2)+($this->form->form_element_spacing['button']['inner']['h']*2);
16852 $height = $this->FontSize + ($this->form->form_element_spacing['button']['outer']['v']*2)+($this->form->form_element_spacing['button']['inner']['v']*2);
16853 if ($this->useActiveForms) {
16854 if (isset($attr['ONCLICK'])) { $objattr['onClick'] = $attr['ONCLICK']; }
16855 }
16856 break;
16857
16858 case 'PASSWORD':
16859 case 'TEXT':
16860 default:
16861 if ($type == '') { $type = 'TEXT'; }
16862 if(strtoupper($attr['TYPE'])=='PASSWORD') { $type = 'PASSWORD'; }
16863 if (isset($attr['VALUE'])) {
16864 if ($type == 'PASSWORD') {
16865 $num_stars = mb_strlen($attr['VALUE'],$this->mb_enc );
16866 $texto = str_repeat('*',$num_stars);
16867 }
16868 else { $texto = $attr['VALUE']; }
16869 }
16870 $xw = ($this->form->form_element_spacing['input']['outer']['h']*2)+($this->form->form_element_spacing['input']['inner']['h']*2);
16871 $xh = ($this->form->form_element_spacing['input']['outer']['v']*2)+($this->form->form_element_spacing['input']['inner']['v']*2);
16872 if ($w) { $width = $w + $xw; }
16873 else { $width = (20 * $spacesize) + $xw; } // Default width in chars
16874 if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $width = ($attr['SIZE'] * $spacesize) + $xw;
16875 $height = $this->FontSize + $xh;
16876 if (isset($attr['MAXLENGTH']) and ctype_digit($attr['MAXLENGTH']) ) $objattr['maxlength'] = $attr['MAXLENGTH'];
16877 if ($this->useActiveForms) {
16878 if (isset($attr['ONCALCULATE'])) { $objattr['onCalculate'] = $attr['ONCALCULATE']; }
16879 else if (isset($attr['ONCHANGE'])) { $objattr['onCalculate'] = $attr['ONCHANGE']; }
16880 if (isset($attr['ONVALIDATE'])) { $objattr['onValidate'] = $attr['ONVALIDATE']; }
16881 if (isset($attr['ONKEYSTROKE'])) { $objattr['onKeystroke'] = $attr['ONKEYSTROKE']; }
16882 if (isset($attr['ONFORMAT'])) { $objattr['onFormat'] = $attr['ONFORMAT']; }
16883 }
16884 break;
16885 }
16886
16887 $objattr['subtype'] = $type;
16888 $objattr['text'] = $texto;
16889 $objattr['width'] = $width;
16890 $objattr['height'] = $height;
16891 $e = "\xbb\xa4\xactype=input,objattr=".serialize($objattr)."\xbb\xa4\xac";
16892
16893 // Clear properties - tidy up
16894 $properties = array();
16895
16896 /*-- TABLES --*/
16897 // Output it to buffers
16898 if ($this->tableLevel) {
16899 $this->_saveCellTextBuffer($e, $this->HREF);
16900 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
16901
16902 }
16903 else {
16904 /*-- END TABLES --*/
16905 $this->_saveTextBuffer($e, $this->HREF);
16906 } // *TABLES*
16907
16908 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
16909 unset($this->InlineProperties[$tag]);
16910
16911 break; // END of INPUT
16912 /*-- END FORMS --*/
16913
16914
16915 // *********** GRAPH ********************
16916 case 'JPGRAPH':
16917 if (!$this->useGraphs) { break; }
16918 if ($attr['TABLE']) { $gid = strtoupper($attr['TABLE']); }
16919 else { $gid = '0'; }
16920 if (!is_array($this->graphs[$gid]) || count($this->graphs[$gid])==0 ) { break; }
16921 include_once(_MPDF_PATH.'graph.php');
16922 $this->graphs[$gid]['attr'] = $attr;
16923
16924
16925 if (isset($this->graphs[$gid]['attr']['WIDTH']) && $this->graphs[$gid]['attr']['WIDTH']) {
16926 $this->graphs[$gid]['attr']['cWIDTH']=$this->ConvertSize($this->graphs[$gid]['attr']['WIDTH'],$pgwidth);
16927 } // mm
16928 if (isset($this->graphs[$gid]['attr']['HEIGHT']) && $this->graphs[$gid]['attr']['HEIGHT']) {
16929 $this->graphs[$gid]['attr']['cHEIGHT']=$this->ConvertSize($this->graphs[$gid]['attr']['HEIGHT'],$pgwidth);
16930 }
16931
16932 $graph_img = print_graph($this->graphs[$gid],$this->blk[$this->blklvl]['inner_width']);
16933 if ($graph_img) {
16934 if(isset($attr['ROTATE'])) {
16935 if ($attr['ROTATE']==90 || $attr['ROTATE']==-90) {
16936 $tmpw = $graph_img['w'];
16937 $graph_img['w']= $graph_img['h'];
16938 $graph_img['h']= $tmpw;
16939 }
16940 }
16941 $attr['SRC'] = $graph_img['file'];
16942 $attr['WIDTH'] = $graph_img['w'];
16943 $attr['HEIGHT'] = $graph_img['h'];
16944 }
16945 else { break; }
16946
16947 // *********** IMAGE ********************
16948 /*-- IMAGES-CORE --*/
16949 case 'IMG':
16950 if ($this->progressBar) { $this->UpdateProgressBar(1,'','IMG'); } // *PROGRESS-BAR*
16951 $objattr = array();
16952 $objattr['margin_top'] = 0;
16953 $objattr['margin_bottom'] = 0;
16954 $objattr['margin_left'] = 0;
16955 $objattr['margin_right'] = 0;
16956 $objattr['padding_top'] = 0;
16957 $objattr['padding_bottom'] = 0;
16958 $objattr['padding_left'] = 0;
16959 $objattr['padding_right'] = 0;
16960 $objattr['width'] = 0;
16961 $objattr['height'] = 0;
16962 $objattr['border_top']['w'] = 0;
16963 $objattr['border_bottom']['w'] = 0;
16964 $objattr['border_left']['w'] = 0;
16965 $objattr['border_right']['w'] = 0;
16966 if(isset($attr['SRC'])) {
16967 $srcpath = $attr['SRC'];
16968 $orig_srcpath = $attr['ORIG_SRC'];
16969 $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
16970 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
16971 return;
16972 }
16973 // mPDF 5.6.01 - LAYERS
16974 if (isset($properties['Z-INDEX']) && $this->currentlayer==0) {
16975 $v = intval($properties['Z-INDEX']);
16976 if ($v > 0) {
16977 $objattr['z-index'] = $v;
16978 }
16979 }
16980
16981 $objattr['visibility'] = 'visible';
16982 if (isset($properties['VISIBILITY'])) {
16983 $v = strtolower($properties['VISIBILITY']);
16984 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible') {
16985 $objattr['visibility'] = $v;
16986 }
16987 }
16988
16989 // VSPACE and HSPACE converted to margins in MergeCSS
16990 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16991 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16992 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16993 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16994
16995 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16996 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16997 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16998 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
16999
17000 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
17001 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
17002 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
17003 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
17004
17005 if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
17006 $w = 0;
17007 $h = 0;
17008 if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17009 else if(isset($attr['WIDTH'])) $w = $this->ConvertSize($attr['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17010 if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17011 else if(isset($attr['HEIGHT'])) $h = $this->ConvertSize($attr['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17012 // mPDF 5.5.15 // mPDF 5.6.60
17013 $maxw=$maxh=$minw=$minh=false;
17014 if(isset($properties['MAX-WIDTH'])) $maxw = $this->ConvertSize($properties['MAX-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17015 else if(isset($attr['MAX-WIDTH'])) $maxw = $this->ConvertSize($attr['MAX-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17016 if(isset($properties['MAX-HEIGHT'])) $maxh = $this->ConvertSize($properties['MAX-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17017 else if(isset($attr['MAX-HEIGHT'])) $maxh = $this->ConvertSize($attr['MAX-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17018 if(isset($properties['MIN-WIDTH'])) $minw = $this->ConvertSize($properties['MIN-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17019 else if(isset($attr['MIN-WIDTH'])) $minw = $this->ConvertSize($attr['MIN-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17020 if(isset($properties['MIN-HEIGHT'])) $minh = $this->ConvertSize($properties['MIN-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17021 else if(isset($attr['MIN-HEIGHT'])) $minh = $this->ConvertSize($attr['MIN-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17022
17023 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr['opacity'] = $properties['OPACITY']; }
17024 if ($this->HREF) {
17025 if (strpos($this->HREF,".") === false && strpos($this->HREF,"@") !== 0) {
17026 $href = $this->HREF;
17027 while(array_key_exists($href,$this->internallink)) $href="#".$href;
17028 $this->internallink[$href] = $this->AddLink();
17029 $objattr['link'] = $this->internallink[$href];
17030 }
17031 else { $objattr['link'] = $this->HREF; }
17032 }
17033 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
17034 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
17035
17036 // mPDF 5.7.3 TRANSFORMS
17037 if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { $objattr['bgcolor'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
17038
17039 /*-- BACKGROUNDS --*/
17040 if(isset($properties['GRADIENT-MASK']) && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/',$properties['GRADIENT-MASK'])) {
17041 $objattr['GRADIENT-MASK'] = $properties['GRADIENT-MASK'];
17042 }
17043 /*-- END BACKGROUNDS --*/
17044
17045 // Image file
17046 $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
17047 if(!$info) {
17048 $info = $this->_getImage($this->noImageFile);
17049 if ($info) {
17050 $srcpath = $this->noImageFile;
17051 $w = ($info['w'] * (25.4/$this->dpi));
17052 $h = ($info['h'] * (25.4/$this->dpi));
17053 }
17054 }
17055 if(!$info) break;
17056
17057 if(isset($attr['ROTATE'])) { $image_orientation = $attr['ROTATE']; }
17058 else if(isset($properties['IMAGE-ORIENTATION'])) { $image_orientation = $properties['IMAGE-ORIENTATION']; }
17059 else { $image_orientation = 0; }
17060 if($image_orientation) {
17061 if ($image_orientation==90 || $image_orientation==-90 || $image_orientation==270) {
17062 $tmpw = $info['w'];
17063 $info['w'] = $info['h'];
17064 $info['h'] = $tmpw;
17065 }
17066 $objattr['ROTATE'] = $image_orientation;
17067 }
17068
17069 $objattr['file'] = $srcpath;
17070 //Default width and height calculation if needed
17071 if($w==0 and $h==0) {
17072 /*-- IMAGES-WMF --*/
17073 if ($info['type']=='wmf') {
17074 // WMF units are twips (1/20pt)
17075 // divide by 20 to get points
17076 // divide by k to get user units
17077 $w = abs($info['w'])/(20*_MPDFK);
17078 $h = abs($info['h']) / (20*_MPDFK);
17079 }
17080 else
17081 /*-- END IMAGES-WMF --*/
17082 if ($info['type']=='svg') {
17083 // SVG units are pixels
17084 $w = abs($info['w'])/_MPDFK;
17085 $h = abs($info['h'])/_MPDFK;
17086 }
17087 else {
17088 //Put image at default image dpi
17089 $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
17090 $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
17091 }
17092 if (isset($properties['IMAGE-RESOLUTION'])) {
17093 if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi']>0) {
17094 $w *= $this->img_dpi / $info['set-dpi'];
17095 $h *= $this->img_dpi / $info['set-dpi'];
17096 }
17097 else if (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) {
17098 $dpi = $m[1];
17099 if ($dpi > 0) {
17100 $w *= $this->img_dpi / $dpi;
17101 $h *= $this->img_dpi / $dpi;
17102 }
17103 }
17104 }
17105 }
17106 // IF WIDTH OR HEIGHT SPECIFIED
17107 if($w==0) $w=abs($h*$info['w']/$info['h']);
17108 if($h==0) $h=abs($w*$info['h']/$info['w']);
17109
17110 // mPDF 5.5.15
17111 if ($minw && $w<$minw) { $w = $minw; $h=abs($w*$info['h']/$info['w']); }
17112 if ($maxw && $w>$maxw) { $w = $maxw; $h=abs($w*$info['h']/$info['w']); }
17113 if ($minh && $h<$minh) { $h = $minh; $w=abs($h*$info['w']/$info['h']); }
17114 if ($maxh && $h>$maxh) { $h = $maxh; $w=abs($h*$info['w']/$info['h']); }
17115
17116 // Resize to maximum dimensions of page
17117 $maxWidth = $this->blk[$this->blklvl]['inner_width'];
17118 $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 1) ;
17119 if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
17120 if (($w + $extrawidth) > ($maxWidth + 0.0001) ) { // mPDF 5.7.4 0.0001 to allow for rounding errors when w==maxWidth
17121 $w = $maxWidth - $extrawidth;
17122 $h=abs($w*$info['h']/$info['w']);
17123 }
17124
17125 if ($h + $extraheight > $maxHeight ) {
17126 $h = $maxHeight - $extraheight;
17127 $w=abs($h*$info['w']/$info['h']);
17128 }
17129 $objattr['type'] = 'image';
17130 $objattr['itype'] = $info['type'];
17131
17132 $objattr['orig_h'] = $info['h'];
17133 $objattr['orig_w'] = $info['w'];
17134 /*-- IMAGES-WMF --*/
17135 if ($info['type']=='wmf') {
17136 $objattr['wmf_x'] = $info['x'];
17137 $objattr['wmf_y'] = $info['y'];
17138 }
17139 else
17140 /*-- END IMAGES-WMF --*/
17141 if ($info['type']=='svg') {
17142 $objattr['wmf_x'] = $info['x'];
17143 $objattr['wmf_y'] = $info['y'];
17144 }
17145 $objattr['height'] = $h + $extraheight;
17146 $objattr['width'] = $w + $extrawidth;
17147 $objattr['image_height'] = $h;
17148 $objattr['image_width'] = $w;
17149 /*-- CSS-IMAGE-FLOAT --*/
17150 if (!$this->ColActive && !$this->tableLevel && !$this->listlvl && !$this->kwt && !$this->keep_block_together) {
17151 if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) == 'RIGHT' || strtoupper($properties['FLOAT']) == 'LEFT')) {
17152 $objattr['float'] = substr(strtoupper($properties['FLOAT']),0,1);
17153 }
17154 }
17155 /*-- END CSS-IMAGE-FLOAT --*/
17156 // mPDF 5.7.3 TRANSFORMS
17157 if (isset($properties['TRANSFORM']) && !$this->ColActive && !$this->kwt) {
17158 $objattr['transform'] = $properties['TRANSFORM'];
17159 }
17160
17161 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
17162
17163 // Clear properties - tidy up
17164 $properties = array();
17165
17166 /*-- TABLES --*/
17167 // Output it to buffers
17168 if ($this->tableLevel) {
17169 $this->_saveCellTextBuffer($e, $this->HREF);
17170 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
17171 }
17172 else {
17173 /*-- END TABLES --*/
17174 $this->_saveTextBuffer($e, $this->HREF);
17175 } // *TABLES*
17176 /*-- ANNOTATIONS --*/
17177 if ($this->title2annots && isset($attr['TITLE'])) {
17178 $objattr = array();
17179 $objattr['margin_top'] = 0;
17180 $objattr['margin_bottom'] = 0;
17181 $objattr['margin_left'] = 0;
17182 $objattr['margin_right'] = 0;
17183 $objattr['width'] = 0;
17184 $objattr['height'] = 0;
17185 $objattr['border_top']['w'] = 0;
17186 $objattr['border_bottom']['w'] = 0;
17187 $objattr['border_left']['w'] = 0;
17188 $objattr['border_right']['w'] = 0;
17189 $objattr['CONTENT'] = $attr['TITLE'];
17190 $objattr['type'] = 'annot';
17191 $objattr['POS-X'] = 0;
17192 $objattr['POS-Y'] = 0;
17193 $objattr['ICON'] = 'Comment';
17194 $objattr['AUTHOR'] = '';
17195 $objattr['SUBJECT'] = '';
17196 $objattr['OPACITY'] = $this->annotOpacity;
17197 $objattr['COLOR'] = $this->ConvertColor('yellow');
17198 $e = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
17199 if($this->tableLevel) { // *TABLES*
17200 $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); // *TABLES*
17201 } // *TABLES*
17202 else { // *TABLES*
17203 $this->textbuffer[] = array($e);
17204 } // *TABLES*
17205 }
17206 /*-- END ANNOTATIONS --*/
17207 }
17208 break;
17209 /*-- END IMAGES-CORE --*/
17210
17211
17212 // *********** CIRCULAR TEXT = TEXTCIRCLE ********************
17213 case 'TEXTCIRCLE':
17214 $objattr = array();
17215 $objattr['margin_top'] = 0;
17216 $objattr['margin_bottom'] = 0;
17217 $objattr['margin_left'] = 0;
17218 $objattr['margin_right'] = 0;
17219 $objattr['padding_top'] = 0;
17220 $objattr['padding_bottom'] = 0;
17221 $objattr['padding_left'] = 0;
17222 $objattr['padding_right'] = 0;
17223 $objattr['width'] = 0;
17224 $objattr['height'] = 0;
17225 $objattr['border_top']['w'] = 0;
17226 $objattr['border_bottom']['w'] = 0;
17227 $objattr['border_left']['w'] = 0;
17228 $objattr['border_right']['w'] = 0;
17229 $objattr['top-text'] = '';
17230 $objattr['bottom-text'] = '';
17231 $objattr['r'] = 20; // radius (default value here for safety)
17232 $objattr['space-width'] = 120;
17233 $objattr['char-width'] = 100;
17234
17235 $this->InlineProperties[$tag] = $this->saveInlineProperties();
17236 $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
17237
17238 if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
17239 return;
17240 }
17241 if (isset($attr['R'])) { $objattr['r']=$this->ConvertSize($attr['R'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17242 if(isset($attr['TOP-TEXT'])) {
17243 $objattr['top-text'] = strcode2utf($attr['TOP-TEXT']);
17244 $objattr['top-text'] = $this->lesser_entity_decode($objattr['top-text']);
17245 if ($this->onlyCoreFonts)
17246 $objattr['top-text'] = mb_convert_encoding($objattr['top-text'], $this->mb_enc,'UTF-8');
17247 }
17248 if(isset($attr['BOTTOM-TEXT'])) {
17249 $objattr['bottom-text'] = strcode2utf($attr['BOTTOM-TEXT']);
17250 $objattr['bottom-text'] = $this->lesser_entity_decode($objattr['bottom-text']);
17251 if ($this->onlyCoreFonts)
17252 $objattr['bottom-text'] = mb_convert_encoding($objattr['bottom-text'], $this->mb_enc,'UTF-8');
17253 }
17254 if(isset($attr['SPACE-WIDTH']) && $attr['SPACE-WIDTH']) { $objattr['space-width'] = $attr['SPACE-WIDTH']; }
17255 if(isset($attr['CHAR-WIDTH']) && $attr['CHAR-WIDTH']) { $objattr['char-width'] = $attr['CHAR-WIDTH']; }
17256
17257 // VISIBILITY
17258 $objattr['visibility'] = 'visible';
17259 if (isset($properties['VISIBILITY'])) {
17260 $v = strtolower($properties['VISIBILITY']);
17261 if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible') {
17262 $objattr['visibility'] = $v;
17263 }
17264 }
17265 // mPDF 5.5.23
17266 if (isset($properties['FONT-SIZE'])) {
17267 if (strtolower($properties['FONT-SIZE'])=='auto') {
17268 if ($objattr['top-text'] && $objattr['bottom-text']) {
17269 $objattr['fontsize'] = -2;
17270 }
17271 else {
17272 $objattr['fontsize'] = -1;
17273 }
17274 }
17275 else {
17276 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],($this->default_font_size/_MPDFK));
17277 $this->SetFontSize($mmsize*_MPDFK,false);
17278 $objattr['fontsize'] = $this->FontSizePt;
17279 }
17280 }
17281 // mPDF 5.5.23
17282 if(isset($attr['DIVIDER'])) {
17283 $objattr['divider'] = strcode2utf($attr['DIVIDER']);
17284 $objattr['divider'] = $this->lesser_entity_decode($objattr['divider']);
17285 if ($this->onlyCoreFonts)
17286 $objattr['divider'] = mb_convert_encoding($objattr['divider'], $this->mb_enc,'UTF-8');
17287
17288 }
17289
17290 if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
17291
17292 $objattr['fontstyle'] = '';
17293 if (isset($properties['FONT-WEIGHT'])) {
17294 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $objattr['fontstyle'] .= 'B'; }
17295 }
17296 if (isset($properties['FONT-STYLE'])) {
17297 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $objattr['fontstyle'] .= 'I'; }
17298 }
17299
17300 if (isset($properties['FONT-FAMILY'])) {
17301 $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
17302 }
17303 $objattr['fontfamily'] = $this->FontFamily;
17304
17305 // VSPACE and HSPACE converted to margins in MergeCSS
17306 if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17307 if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17308 if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17309 if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17310
17311 if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17312 if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17313 if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17314 if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
17315
17316 if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
17317 if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
17318 if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
17319 if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
17320
17321 if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr['opacity'] = $properties['OPACITY']; }
17322 if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { $objattr['bgcolor'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
17323 else { $objattr['bgcolor'] = false; }
17324 if ($this->HREF) {
17325 if (strpos($this->HREF,".") === false && strpos($this->HREF,"@") !== 0) {
17326 $href = $this->HREF;
17327 while(array_key_exists($href,$this->internallink)) $href="#".$href;
17328 $this->internallink[$href] = $this->AddLink();
17329 $objattr['link'] = $this->internallink[$href];
17330 }
17331 else { $objattr['link'] = $this->HREF; }
17332 }
17333 $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
17334 $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
17335
17336
17337 $w = $objattr['r']*2;
17338 $h = $w;
17339 $objattr['height'] = $h + $extraheight;
17340 $objattr['width'] = $w + $extrawidth;
17341 $objattr['type'] = 'textcircle';
17342
17343 $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
17344
17345 // Clear properties - tidy up
17346 $properties = array();
17347
17348 /*-- TABLES --*/
17349 // Output it to buffers
17350 if ($this->tableLevel) {
17351 $this->_saveCellTextBuffer($e, $this->HREF);
17352 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
17353 }
17354 else {
17355 /*-- END TABLES --*/
17356 $this->_saveTextBuffer($e, $this->HREF);
17357 } // *TABLES*
17358
17359 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
17360 unset($this->InlineProperties[$tag]);
17361
17362 break;
17363
17364
17365 /*-- TABLES --*/
17366
17367 case 'TABLE': // TABLE-BEGIN
17368 $this->tdbegin = false;
17369 $this->lastoptionaltag = '';
17370 // Disable vertical justification in columns
17371 if ($this->ColActive) { $this->colvAlign = ''; } // *COLUMNS*
17372 if ($this->lastblocklevelchange == 1) { $blockstate = 1; } // Top margins/padding only
17373 else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
17374 // called from block after new div e.g. <div> ... <table> ... Outputs block top margin/border and padding
17375 if (count($this->textbuffer) == 0 && $this->lastblocklevelchange == 1 && !$this->tableLevel && !$this->kwt) {
17376 $this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,1,true, $this->blk[$this->blklvl]['direction']);
17377 $this->finishFlowingBlock(true); // true = END of flowing block
17378 }
17379 else if (!$this->tableLevel && count($this->textbuffer)) { $this->printbuffer($this->textbuffer,$blockstate); }
17380
17381 $this->textbuffer=array();
17382 $this->lastblocklevelchange = -1;
17383 if ($this->tableLevel) { // i.e. now a nested table coming...
17384 // Save current level table
17385 // mPDF 5.4.10
17386 $this->cell['PARENTCELL'] = $this->saveInlineProperties();
17387 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['baseProperties']= $this->base_table_properties;
17388 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = $this->cell;
17389 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currrow'] = $this->row;
17390 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currcol'] = $this->col;
17391 }
17392 $this->tableLevel++;
17393 $this->cssmgr->tbCSSlvl++;
17394
17395 if ($this->tableLevel>1) { // inherit table properties from cell in which nested
17396 $this->base_table_properties['FONT-KERNING'] = $this->kerning ;
17397 $this->base_table_properties['LETTER-SPACING'] = $this->lSpacingCSS ;
17398 $this->base_table_properties['WORD-SPACING'] = $this->wSpacingCSS ;
17399 }
17400
17401 if (isset($this->tbctr[$this->tableLevel])) { $this->tbctr[$this->tableLevel]++; }
17402 else { $this->tbctr[$this->tableLevel] = 1; }
17403
17404 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['level'] = $this->tableLevel;
17405 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['levelid'] = $this->tbctr[$this->tableLevel];
17406
17407 if ($this->tableLevel > $this->innermostTableLevel) { $this->innermostTableLevel = $this->tableLevel; }
17408 if ($this->tableLevel > 1) {
17409 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nestedpos'] = array($this->row,$this->col,$this->tbctr[($this->tableLevel-1)]);
17410 }
17411 //++++++++++++++++++++++++++++
17412
17413 $this->cell = array();
17414 $this->col=-1; //int
17415 $this->row=-1; //int
17416 $table = &$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]];
17417
17418 // New table - any level
17419 if ($this->cacheTables) {
17420 $this->packTableData = true; // required for cacheTables
17421 $this->simpleTables = false; // Cannot co-exist with cacheTables
17422 $table['cache'] = _MPDF_TEMP_PATH.'_tempTblCache'.uniqid(rand(1,100000),true).'.dat';
17423 $fh = fopen($table['cache'] , "wb") or $this->Error("When using cacheTables, you must have read/write access to cache files (".$table['cache'] .")");
17424 fwrite($fh, "\x00");
17425 fclose($fh);
17426 $table['ptr'] = 1 ; // Must not be 0
17427 }
17428
17429 $table['direction'] = $this->directionality;
17430 $table['bgcolor'] = false;
17431 $table['va'] = false;
17432 $table['txta'] = false;
17433 $table['topntail'] = false;
17434 $table['thead-underline'] = false;
17435 $table['border'] = false;
17436 $table['border_details']['R']['w'] = 0;
17437 $table['border_details']['L']['w'] = 0;
17438 $table['border_details']['T']['w'] = 0;
17439 $table['border_details']['B']['w'] = 0;
17440 $table['border_details']['R']['style'] = '';
17441 $table['border_details']['L']['style'] = '';
17442 $table['border_details']['T']['style'] = '';
17443 $table['border_details']['B']['style'] = '';
17444 $table['max_cell_border_width']['R'] = 0;
17445 $table['max_cell_border_width']['L'] = 0;
17446 $table['max_cell_border_width']['T'] = 0;
17447 $table['max_cell_border_width']['B'] = 0;
17448 $table['padding']['L'] = false;
17449 $table['padding']['R'] = false;
17450 $table['padding']['T'] = false;
17451 $table['padding']['B'] = false;
17452 $table['margin']['L'] = false;
17453 $table['margin']['R'] = false;
17454 $table['margin']['T'] = false;
17455 $table['margin']['B'] = false;
17456 $table['a'] = false;
17457 $table['border_spacing_H'] = false;
17458 $table['border_spacing_V'] = false;
17459 $table['decimal_align'] = false; // mPDF 5.6.13
17460 $this->Reset();
17461 $this->InlineProperties = array();
17462 $table['nc'] = $table['nr'] = 0;
17463 $this->tablethead = 0;
17464 $this->tabletfoot = 0;
17465 $this->tabletheadjustfinished = false;
17466
17467
17468 if ($this->blockjustfinished && !count($this->textbuffer) && $this->y != $this->tMargin && $this->collapseBlockMargins && $this->tableLevel==1) { $lastbottommargin = $this->lastblockbottommargin; }
17469 else { $lastbottommargin = 0; }
17470 $this->lastblockbottommargin = 0;
17471 $this->blockjustfinished=false;
17472
17473 if ($this->tableLevel==1) {
17474 $this->tableCJK = false;
17475 $this->table_lineheight = $this->normalLineheight;
17476 $table['headernrows'] = 0;
17477 $table['footernrows'] = 0;
17478 $this->base_table_properties = array();
17479 }
17480
17481 // ADDED CSS FUNCIONS FOR TABLE
17482 if ($this->cssmgr->tbCSSlvl==1) {
17483 $properties = $this->cssmgr->MergeCSS('TOPTABLE',$tag,$attr);
17484 }
17485 else {
17486 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17487 }
17488 $w = '';
17489 if (isset($properties['WIDTH'])) { $w = $properties['WIDTH']; }
17490 else if (isset($attr['WIDTH']) && $attr['WIDTH']) { $w = $attr['WIDTH']; }
17491
17492
17493 if(isset($properties['DIRECTION']) && $properties['DIRECTION']) { $table['direction'] = strtolower($properties['DIRECTION']); }
17494 else if(isset($attr['DIR']) && $attr['DIR']) { $table['direction'] = strtolower($attr['DIR']); }
17495 else if (!isset($table['direction'])){ $table['direction'] = $this->blk[$this->blklvl]['direction']; }
17496
17497 if (isset($properties['BACKGROUND-COLOR'])) { $table['bgcolor'][-1] = $properties['BACKGROUND-COLOR']; }
17498 else if (isset($properties['BACKGROUND'])) { $table['bgcolor'][-1] = $properties['BACKGROUND']; }
17499 else if (isset($attr['BGCOLOR'])) { $table['bgcolor'][-1] = $attr['BGCOLOR']; }
17500 if (isset($properties['VERTICAL-ALIGN'])) { $table['va'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
17501 if (isset($properties['TEXT-ALIGN'])) { $table['txta'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
17502 if (isset($attr['ALIGN'])) { $table['a'] = $align[strtolower($attr['ALIGN'])]; }
17503 if (!$table['a']) {
17504 if ($table['direction'] == 'rtl' ) { $table['a'] = 'R'; }
17505 else { $table['a'] = 'L'; }
17506 }
17507
17508 if (isset($properties['AUTOSIZE']) && $properties['AUTOSIZE'] && $this->tableLevel ==1) {
17509 $this->shrink_this_table_to_fit = $properties['AUTOSIZE'];
17510 if ($this->shrink_this_table_to_fit < 1) { $this->shrink_this_table_to_fit = 0; }
17511 }
17512 if (isset($properties['ROTATE']) && $properties['ROTATE'] && $this->tableLevel ==1) {
17513 $this->table_rotate = $properties['ROTATE'];
17514 }
17515 if (isset($properties['TOPNTAIL'])) { $table['topntail'] = $properties['TOPNTAIL']; }
17516 if (isset($properties['THEAD-UNDERLINE'])) { $table['thead-underline'] = $properties['THEAD-UNDERLINE']; }
17517
17518 if (isset($properties['BORDER'])) {
17519 $bord = $this->border_details($properties['BORDER']);
17520 if ($bord['s']) {
17521 $table['border'] = _BORDER_ALL;
17522 $table['border_details']['R'] = $bord;
17523 $table['border_details']['L'] = $bord;
17524 $table['border_details']['T'] = $bord;
17525 $table['border_details']['B'] = $bord;
17526 }
17527 }
17528 if (isset($properties['BORDER-RIGHT'])) {
17529 if ($table['direction'] == 'rtl') { // *RTL*
17530 $table['border_details']['R'] = $this->border_details($properties['BORDER-LEFT']); // *RTL*
17531 } // *RTL*
17532 else { // *RTL*
17533 $table['border_details']['R'] = $this->border_details($properties['BORDER-RIGHT']);
17534 } // *RTL*
17535 $this->setBorder($table['border'], _BORDER_RIGHT, $table['border_details']['R']['s']);
17536 }
17537 if (isset($properties['BORDER-LEFT'])) {
17538 if ($table['direction'] == 'rtl') { // *RTL*
17539 $table['border_details']['L'] = $this->border_details($properties['BORDER-RIGHT']); // *RTL*
17540 } // *RTL*
17541 else { // *RTL*
17542 $table['border_details']['L'] = $this->border_details($properties['BORDER-LEFT']);
17543 } // *RTL*
17544 $this->setBorder($table['border'], _BORDER_LEFT, $table['border_details']['L']['s']);
17545 }
17546 if (isset($properties['BORDER-BOTTOM'])) {
17547 $table['border_details']['B'] = $this->border_details($properties['BORDER-BOTTOM']);
17548 $this->setBorder($table['border'], _BORDER_BOTTOM, $table['border_details']['B']['s']);
17549 }
17550 if (isset($properties['BORDER-TOP'])) {
17551 $table['border_details']['T'] = $this->border_details($properties['BORDER-TOP']);
17552 $this->setBorder($table['border'], _BORDER_TOP, $table['border_details']['T']['s']);
17553 }
17554 if ($table['border']){
17555 $this->table_border_css_set = 1;
17556 }
17557 else {
17558 $this->table_border_css_set = 0;
17559 }
17560
17561 if (isset($properties['FONT-FAMILY'])) {
17562 $this->default_font = $properties['FONT-FAMILY'];
17563 $this->SetFont($this->default_font,'',0,false);
17564 }
17565 $this->base_table_properties['FONT-FAMILY'] = $this->FontFamily; // mPDF 5.4.10
17566
17567 if (isset($properties['FONT-SIZE'])) {
17568 // mPDF 5.4.10
17569 if ($this->tableLevel>1) { $mmsize = $this->ConvertSize($properties['FONT-SIZE'], $this->base_table_properties['FONT-SIZE']); }
17570 else { $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK); }
17571 if ($mmsize) {
17572 $this->default_font_size = $mmsize*(_MPDFK);
17573 $this->SetFontSize($this->default_font_size,false);
17574 }
17575 }
17576 $this->base_table_properties['FONT-SIZE'] = $this->FontSize.'mm'; // mPDF 5.4.10
17577
17578 if (isset($properties['FONT-WEIGHT'])) {
17579 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->base_table_properties['FONT-WEIGHT'] = 'BOLD'; }
17580 }
17581 if (isset($properties['FONT-STYLE'])) {
17582 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->base_table_properties['FONT-STYLE'] = 'ITALIC'; }
17583 }
17584 if (isset($properties['COLOR'])) {
17585 $this->base_table_properties['COLOR'] = $properties['COLOR'];
17586 }
17587 if (isset($properties['FONT-KERNING'])) {
17588 $this->base_table_properties['FONT-KERNING'] = $properties['FONT-KERNING'];
17589 }
17590 if (isset($properties['LETTER-SPACING'])) {
17591 $this->base_table_properties['LETTER-SPACING'] = $properties['LETTER-SPACING'];
17592 }
17593 if (isset($properties['WORD-SPACING'])) {
17594 $this->base_table_properties['WORD-SPACING'] = $properties['WORD-SPACING'];
17595 }
17596
17597 if (isset($properties['PADDING-LEFT'])) {
17598 $table['padding']['L'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17599 }
17600 if (isset($properties['PADDING-RIGHT'])) {
17601 $table['padding']['R'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17602 }
17603 if (isset($properties['PADDING-TOP'])) {
17604 $table['padding']['T'] = $this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17605 }
17606 if (isset($properties['PADDING-BOTTOM'])) {
17607 $table['padding']['B'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17608 }
17609
17610 if (isset($properties['MARGIN-TOP'])) {
17611 if ($lastbottommargin) {
17612 $tmp = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17613 if ($tmp > $lastbottommargin) { $properties['MARGIN-TOP'] -= $lastbottommargin; }
17614 else { $properties['MARGIN-TOP'] = 0; }
17615 }
17616 $table['margin']['T'] = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17617 }
17618
17619 if (isset($properties['MARGIN-BOTTOM'])) {
17620 $table['margin']['B'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17621 }
17622 if (isset($properties['MARGIN-LEFT'])) {
17623 $table['margin']['L'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17624 }
17625
17626 if (isset($properties['MARGIN-RIGHT'])) {
17627 $table['margin']['R'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17628 }
17629 if (isset($properties['MARGIN-LEFT']) && isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-LEFT'])=='auto' && strtolower($properties['MARGIN-RIGHT'])=='auto') {
17630 $table['a'] = 'C';
17631 }
17632 else if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
17633 $table['a'] = 'R';
17634 }
17635 else if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
17636 $table['a'] = 'L';
17637 }
17638
17639 if (isset($properties['LINE-HEIGHT']) && $this->tableLevel==1) {
17640 $this->table_lineheight = $this->fixLineheight($properties['LINE-HEIGHT']);
17641 if (!$this->table_lineheight) { $this->table_lineheight = $this->normalLineheight; }
17642 }
17643
17644 if (isset($properties['BORDER-COLLAPSE']) && strtoupper($properties['BORDER-COLLAPSE'])=='SEPARATE') {
17645 $table['borders_separate'] = true;
17646 }
17647 else {
17648 $table['borders_separate'] = false;
17649 }
17650
17651 // mPDF 5.7.3
17652 if (isset($properties['BORDER-SPACING-H'])) {
17653 $table['border_spacing_H'] = $this->ConvertSize($properties['BORDER-SPACING-H'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17654 }
17655 if (isset($properties['BORDER-SPACING-V'])) {
17656 $table['border_spacing_V'] = $this->ConvertSize($properties['BORDER-SPACING-V'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17657 }
17658
17659 if (!$table['borders_separate']) { $table['border_spacing_H'] = $table['border_spacing_V'] = 0; }
17660
17661 if (isset($properties['EMPTY-CELLS'])) {
17662 $table['empty_cells'] = strtolower($properties['EMPTY-CELLS']); // 'hide' or 'show'
17663 }
17664 else { $table['empty_cells'] = ''; }
17665
17666 if (isset($properties['PAGE-BREAK-INSIDE']) && strtoupper($properties['PAGE-BREAK-INSIDE'])=='AVOID' && $this->tableLevel==1 && !$this->writingHTMLfooter) {
17667 $this->table_keep_together = true;
17668 }
17669 else if ($this->tableLevel==1) {
17670 $this->table_keep_together = false;
17671 }
17672 if (isset($properties['PAGE-BREAK-AFTER']) && $this->tableLevel==1) {
17673 $table['page_break_after'] = strtoupper($properties['PAGE-BREAK-AFTER']);
17674 }
17675
17676 /*-- BACKGROUNDS --*/
17677 if (isset($properties['BACKGROUND-GRADIENT']) && !$this->kwt && !$this->ColActive) { $table['gradient'] = $properties['BACKGROUND-GRADIENT']; }
17678
17679 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive) {
17680 $ret = $this->SetBackground($properties, $currblk['inner_width']);
17681 if ($ret) { $table['background-image'] = $ret; }
17682 }
17683 /*-- END BACKGROUNDS --*/
17684
17685 if (isset($properties['OVERFLOW'])) {
17686 $table['overflow'] = strtolower($properties['OVERFLOW']); // 'hidden' 'wrap' or 'visible' or 'auto'
17687 if (($this->ColActive || $this->tableLevel>1) && $table['overflow']=='visible') { unset($table['overflow']); }
17688 }
17689
17690 $properties = array();
17691
17692
17693
17694 if (isset($attr['CELLPADDING'])) {
17695 $table['cell_padding'] = $attr['CELLPADDING'];
17696 }
17697 else {
17698 $table['cell_padding'] = false;
17699 }
17700
17701 if (isset($attr['BORDER']) && $attr['BORDER']=='1') { // mPDF 5.5.08
17702 $this->table_border_attr_set = 1; // mPDF 5.5.08
17703 $bord = $this->border_details('#000000 1px solid');
17704 if ($bord['s']) {
17705 $table['border'] = _BORDER_ALL;
17706 $table['border_details']['R'] = $bord;
17707 $table['border_details']['L'] = $bord;
17708 $table['border_details']['T'] = $bord;
17709 $table['border_details']['B'] = $bord;
17710 }
17711 }
17712 else {
17713 $this->table_border_attr_set = 0;
17714 }
17715
17716 if ($w) {
17717 $maxwidth = $this->blk[$this->blklvl]['inner_width'];
17718 if ($table['borders_separate']) {
17719 $tblblw = $table['margin']['L'] + $table['margin']['R'] + $table['border_details']['L']['w']/2 + $table['border_details']['R']['w']/2;
17720 }
17721 else {
17722 $tblblw = $table['margin']['L'] + $table['margin']['R'] + $table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2;
17723 }
17724 if (strpos($w,'%') && $this->tableLevel == 1 && !$this->ignore_table_percents ) {
17725 // % needs to be of inner box without table margins etc.
17726 $maxwidth -= $tblblw ;
17727 $wmm = $this->ConvertSize($w,$maxwidth,$this->FontSize,false);
17728 $table['w'] = $wmm + $tblblw ;
17729 }
17730 if (strpos($w,'%') && $this->tableLevel > 1 && !$this->ignore_table_percents && $this->keep_table_proportions) {
17731 $table['wpercent'] = $w + 0; // makes 80% -> 80
17732 }
17733 if (!strpos($w,'%') && !$this->ignore_table_widths ) {
17734 $wmm = $this->ConvertSize($w,$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
17735 $table['w'] = $wmm + $tblblw ;
17736 }
17737 if (!$this->keep_table_proportions) {
17738 if (isset($table['w']) && $table['w'] > $this->blk[$this->blklvl]['inner_width']) { $table['w'] = $this->blk[$this->blklvl]['inner_width']; }
17739 }
17740 }
17741
17742 if (isset($attr['AUTOSIZE']) && $this->tableLevel==1) {
17743 $this->shrink_this_table_to_fit = $attr['AUTOSIZE'];
17744 if ($this->shrink_this_table_to_fit < 1) { $this->shrink_this_table_to_fit = 1; }
17745 }
17746 if (isset($attr['ROTATE']) && $this->tableLevel==1) {
17747 $this->table_rotate = $attr['ROTATE'];
17748 }
17749
17750 //++++++++++++++++++++++++++++
17751 // keeping block together on one page
17752 // Autosize is now forced therefore keep block together disabled
17753 if ($this->keep_block_together) {
17754 $this->keep_block_together = 0;
17755 $this->printdivbuffer();
17756 $this->blk[$this->blklvl]['keep_block_together'] = 0;
17757 }
17758 if ($this->table_rotate) {
17759 $this->tbrot_Links = array();
17760 $this->tbrot_Annots = array();
17761 $this->tbrotForms = array();
17762 $this->tbrot_Reference = array();
17763 $this->tbrot_BMoutlines = array();
17764 $this->tbrot_toc = array();
17765 }
17766
17767 if ($this->kwt) {
17768 if ($this->table_rotate) { $this->table_keep_together = true; }
17769 $this->kwt = false;
17770 $this->kwt_saved = true;
17771 }
17772
17773 if ($this->tableLevel==1 && $this->useGraphs) {
17774 if (isset($attr['ID']) && $attr['ID']) { $this->currentGraphId = strtoupper($attr['ID']); }
17775 else { $this->currentGraphId = '0'; }
17776 $this->graphs[$this->currentGraphId] = array();
17777 }
17778 //++++++++++++++++++++++++++++
17779 $this->plainCell_properties = array();
17780 unset($table);
17781 break;
17782
17783 case 'THEAD':
17784 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17785 $this->cssmgr->tbCSSlvl++;
17786 $this->tablethead = 1;
17787 $this->tabletfoot = 0;
17788 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17789 if (isset($properties['FONT-WEIGHT'])) {
17790 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->thead_font_weight = 'B'; }
17791 else { $this->thead_font_weight = ''; }
17792 }
17793
17794 if (isset($properties['FONT-STYLE'])) {
17795 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->thead_font_style = 'I'; }
17796 else { $this->thead_font_style = ''; }
17797 }
17798 if (isset($properties['FONT-VARIANT'])) {
17799 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this->thead_font_smCaps = 'S'; }
17800 else { $this->thead_font_smCaps = ''; }
17801 }
17802
17803 if (isset($properties['VERTICAL-ALIGN'])) {
17804 $this->thead_valign_default = $properties['VERTICAL-ALIGN'];
17805 }
17806 if (isset($properties['TEXT-ALIGN'])) {
17807 $this->thead_textalign_default = $properties['TEXT-ALIGN'];
17808 }
17809 $properties = array();
17810 break;
17811
17812 case 'TFOOT':
17813 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17814 $this->cssmgr->tbCSSlvl++;
17815 $this->tabletfoot = 1;
17816 $this->tablethead = 0;
17817 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17818 if (isset($properties['FONT-WEIGHT'])) {
17819 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->tfoot_font_weight = 'B'; }
17820 else { $this->tfoot_font_weight = ''; }
17821 }
17822
17823 if (isset($properties['FONT-STYLE'])) {
17824 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->tfoot_font_style = 'I'; }
17825 else { $this->tfoot_font_style = ''; }
17826 }
17827 if (isset($properties['FONT-VARIANT'])) {
17828 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this->tfoot_font_smCaps = 'S'; }
17829 else { $this->tfoot_font_smCaps = ''; }
17830 }
17831
17832 if (isset($properties['VERTICAL-ALIGN'])) {
17833 $this->tfoot_valign_default = $properties['VERTICAL-ALIGN'];
17834 }
17835 if (isset($properties['TEXT-ALIGN'])) {
17836 $this->tfoot_textalign_default = $properties['TEXT-ALIGN'];
17837 }
17838 $properties = array();
17839 break;
17840
17841
17842 case 'TBODY':
17843 $this->tablethead = 0;
17844 $this->tabletfoot = 0;
17845 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17846 $this->cssmgr->tbCSSlvl++;
17847 $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17848 break;
17849
17850
17851 case 'TR':
17852 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17853 $this->cssmgr->tbCSSlvl++;
17854 $this->row++;
17855 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']++;
17856 $this->col = -1;
17857 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
17858
17859 if (!$this->simpleTables && (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['borders_separate']) || !$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['borders_separate'])) {
17860 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-left'][$this->row] = $properties['BORDER-LEFT']; }
17861 if (isset($properties['BORDER-RIGHT']) && $properties['BORDER-RIGHT']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-right'][$this->row] = $properties['BORDER-RIGHT']; }
17862 if (isset($properties['BORDER-TOP']) && $properties['BORDER-TOP']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-top'][$this->row] = $properties['BORDER-TOP']; }
17863 if (isset($properties['BORDER-BOTTOM']) && $properties['BORDER-BOTTOM']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-bottom'][$this->row] = $properties['BORDER-BOTTOM']; }
17864 }
17865
17866 if (isset($properties['BACKGROUND-COLOR'])) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$this->row] = $properties['BACKGROUND-COLOR']; }
17867 else if (isset($attr['BGCOLOR'])) $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$this->row] = $attr['BGCOLOR'];
17868
17869 /*-- BACKGROUNDS --*/
17870 if (isset($properties['BACKGROUND-GRADIENT']) && !$this->kwt && !$this->ColActive) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$this->row] = $properties['BACKGROUND-GRADIENT']; }
17871
17872 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive) {
17873 $ret = $this->SetBackground($properties, $currblk['inner_width']);
17874 if ($ret) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$this->row] = $ret; }
17875 }
17876 /*-- END BACKGROUNDS --*/
17877
17878
17879 if (isset($properties['TEXT-ROTATE'])) {
17880 $this->trow_text_rotate = $properties['TEXT-ROTATE'];
17881 }
17882 if (isset($attr['TEXT-ROTATE'])) $this->trow_text_rotate = $attr['TEXT-ROTATE'];
17883
17884 if ($this->tablethead) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead'][$this->row] = true; }
17885 if ($this->tabletfoot) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$this->row] = true; }
17886 $properties = array();
17887 break;
17888
17889
17890 case 'TH':
17891 case 'TD':
17892 $this->ignorefollowingspaces = true;
17893 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
17894 $this->cssmgr->tbCSSlvl++;
17895 $this->InlineProperties = array();
17896 $this->tdbegin = true;
17897 $this->col++;
17898 while (isset($this->cell[$this->row][$this->col])) { $this->col++; }
17899
17900 //Update number column
17901 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; }
17902
17903 $table = &$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]];
17904
17905 $c = array('a' => false,
17906 'R' => false,
17907 'nowrap' => false,
17908 'bgcolor' => false,
17909 'padding' => array('L' => false,
17910 'R' => false,
17911 'T' => false,
17912 'B' => false
17913 )
17914 );
17915
17916 if ($this->simpleTables && $this->row==0 && $this->col==0){
17917 $table['simple']['border'] = false;
17918 $table['simple']['border_details']['R']['w'] = 0;
17919 $table['simple']['border_details']['L']['w'] = 0;
17920 $table['simple']['border_details']['T']['w'] = 0;
17921 $table['simple']['border_details']['B']['w'] = 0;
17922 $table['simple']['border_details']['R']['style'] = '';
17923 $table['simple']['border_details']['L']['style'] = '';
17924 $table['simple']['border_details']['T']['style'] = '';
17925 $table['simple']['border_details']['B']['style'] = '';
17926 }
17927 else if (!$this->simpleTables) {
17928 $c['border'] = false;
17929 $c['border_details']['R']['w'] = 0;
17930 $c['border_details']['L']['w'] = 0;
17931 $c['border_details']['T']['w'] = 0;
17932 $c['border_details']['B']['w'] = 0;
17933 $c['border_details']['mbw']['BL'] = 0;
17934 $c['border_details']['mbw']['BR'] = 0;
17935 $c['border_details']['mbw']['RT'] = 0;
17936 $c['border_details']['mbw']['RB'] = 0;
17937 $c['border_details']['mbw']['TL'] = 0;
17938 $c['border_details']['mbw']['TR'] = 0;
17939 $c['border_details']['mbw']['LT'] = 0;
17940 $c['border_details']['mbw']['LB'] = 0;
17941 $c['border_details']['R']['style'] = '';
17942 $c['border_details']['L']['style'] = '';
17943 $c['border_details']['T']['style'] = '';
17944 $c['border_details']['B']['style'] = '';
17945 $c['border_details']['R']['s'] = 0;
17946 $c['border_details']['L']['s'] = 0;
17947 $c['border_details']['T']['s'] = 0;
17948 $c['border_details']['B']['s'] = 0;
17949 $c['border_details']['R']['c'] = $this->ConvertColor(0);
17950 $c['border_details']['L']['c'] = $this->ConvertColor(0);
17951 $c['border_details']['T']['c'] = $this->ConvertColor(0);
17952 $c['border_details']['B']['c'] = $this->ConvertColor(0);
17953 $c['border_details']['R']['dom'] = 0;
17954 $c['border_details']['L']['dom'] = 0;
17955 $c['border_details']['T']['dom'] = 0;
17956 $c['border_details']['B']['dom'] = 0;
17957 }
17958
17959
17960 if ($table['va']) { $c['va'] = $table['va']; }
17961 if ($table['txta']) { $c['a'] = $table['txta']; }
17962 if ($this->table_border_attr_set) {
17963 if ($table['border_details']) {
17964 if (!$this->simpleTables){
17965 $c['border_details']['R'] = $table['border_details']['R'];
17966 $c['border_details']['L'] = $table['border_details']['L'];
17967 $c['border_details']['T'] = $table['border_details']['T'];
17968 $c['border_details']['B'] = $table['border_details']['B'];
17969 $c['border'] = $table['border'];
17970 $c['border_details']['L']['dom'] = 1;
17971 $c['border_details']['R']['dom'] = 1;
17972 $c['border_details']['T']['dom'] = 1;
17973 $c['border_details']['B']['dom'] = 1;
17974 }
17975 else if ($this->simpleTables && $this->row==0 && $this->col==0){
17976 $table['simple']['border_details']['R'] = $table['border_details']['R'];
17977 $table['simple']['border_details']['L'] = $table['border_details']['L'];
17978 $table['simple']['border_details']['T'] = $table['border_details']['T'];
17979 $table['simple']['border_details']['B'] = $table['border_details']['B'];
17980 $table['simple']['border'] = $table['border'];
17981 }
17982 }
17983 }
17984 // INHERITED THEAD CSS Properties
17985 if ($this->tablethead) {
17986 if ($this->thead_valign_default) $c['va'] = $align[strtolower($this->thead_valign_default)];
17987 if ($this->thead_textalign_default) $c['a'] = $align[strtolower($this->thead_textalign_default)];
17988 if ($this->thead_font_weight == 'B') { $this->SetStyle('B',true); }
17989 if ($this->thead_font_style == 'I') { $this->SetStyle('I',true); }
17990 if ($this->thead_font_smCaps == 'S') { $this->SetStyle('S',true); }
17991 }
17992
17993 // INHERITED TFOOT CSS Properties
17994 if ($this->tabletfoot) {
17995 if ($this->tfoot_valign_default) $c['va'] = $align[strtolower($this->tfoot_valign_default)];
17996 if ($this->tfoot_textalign_default) $c['a'] = $align[strtolower($this->tfoot_textalign_default)];
17997 if ($this->tfoot_font_weight == 'B') { $this->SetStyle('B',true); }
17998 if ($this->tfoot_font_style == 'I') { $this->SetStyle('I',true); }
17999 if ($this->tfoot_font_style == 'S') { $this->SetStyle('S',true); }
18000 }
18001
18002
18003 if ($this->trow_text_rotate){
18004 $c['R'] = $this->trow_text_rotate;
18005 }
18006
18007 $this->cell_border_dominance_L = 0;
18008 $this->cell_border_dominance_R = 0;
18009 $this->cell_border_dominance_T = 0;
18010 $this->cell_border_dominance_B = 0;
18011
18012 $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
18013 $properties = $this->cssmgr->array_merge_recursive_unique($this->base_table_properties, $properties);
18014
18015 if (isset($properties['FONT-KERNING']) && (strtoupper($properties['FONT-KERNING'])=='NORMAL' || strtoupper($properties['FONT-KERNING'])=='AUTO')) {
18016 $this->kerning = true;
18017 }
18018 else { $this->kerning = false; }
18019
18020 if (isset($properties['LETTER-SPACING']) && ($properties['LETTER-SPACING'] || $properties['LETTER-SPACING']==='0') && strtoupper($properties['LETTER-SPACING']) != 'NORMAL') {
18021 $this->lSpacingCSS = strtoupper($properties['LETTER-SPACING']);
18022 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
18023 }
18024 else {
18025 $this->lSpacingCSS = '';
18026 $this->fixedlSpacing = false;
18027 }
18028 if (isset($properties['WORD-SPACING']) && strtoupper($properties['WORD-SPACING']) != 'NORMAL') {
18029 $this->wSpacingCSS = strtoupper($properties['WORD-SPACING']);
18030 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
18031 }
18032 else {
18033 $this->minwSpacing = 0;
18034 $this->wSpacingCSS = '';
18035 }
18036 // mPDF 5.6.08
18037 if (isset($properties['HYPHENS']) && $properties['HYPHENS']) {
18038 if (strtoupper($properties['HYPHENS']) == 'NONE') { $this->textparam['hyphens'] = 2; }
18039 else if (strtoupper($properties['HYPHENS']) == 'AUTO') { $this->textparam['hyphens'] = 1; }
18040 else if (strtoupper($properties['HYPHENS']) == 'MANUAL') { $this->textparam['hyphens'] = 0; }
18041 }
18042
18043 if (isset($properties['BACKGROUND-COLOR'])) { $c['bgcolor'] = $properties['BACKGROUND-COLOR']; }
18044 else if (isset($properties['BACKGROUND'])) { $c['bgcolor'] = $properties['BACKGROUND']; }
18045 else if (isset($attr['BGCOLOR'])) $c['bgcolor'] = $attr['BGCOLOR'];
18046
18047
18048
18049 /*-- BACKGROUNDS --*/
18050 if (isset($properties['BACKGROUND-GRADIENT'])) { $c['gradient'] = $properties['BACKGROUND-GRADIENT']; }
18051 else { $c['gradient'] = false; }
18052
18053 if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->keep_block_together) {
18054 $ret = $this->SetBackground($properties, $this->blk[$this->blklvl]['inner_width']);
18055 if ($ret) { $c['background-image'] = $ret; }
18056 }
18057 /*-- END BACKGROUNDS --*/
18058 if (isset($properties['VERTICAL-ALIGN'])) { $c['va']=$align[strtolower($properties['VERTICAL-ALIGN'])]; }
18059 else if (isset($attr['VALIGN'])) $c['va'] = $align[strtolower($attr['VALIGN'])];
18060
18061
18062 // mPDF 5.6.13
18063 if (isset($properties['TEXT-ALIGN']) && $properties['TEXT-ALIGN']) {
18064 if (substr($properties['TEXT-ALIGN'],0,1)=='D') { $c['a'] = $properties['TEXT-ALIGN']; }
18065 else { $c['a'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
18066 }
18067 // mPDF 5.6.13
18068 if (isset($attr['ALIGN']) && $attr['ALIGN']) {
18069 if (strtolower($attr['ALIGN']) == 'char') {
18070 if (isset($attr['CHAR']) && $attr['CHAR']) {
18071 $char = html_entity_decode($attr['CHAR']);
18072 $char = strcode2utf($char);
18073 $d = array_search($char,$this->decimal_align);
18074 if ($d !== false) { $c['a'] = $d.'R'; }
18075 }
18076 else { $c['a'] = 'DPR'; }
18077 }
18078 else { $c['a'] = $align[strtolower($attr['ALIGN'])]; }
18079 }
18080
18081 if (!$c['a']) {
18082 if (isset($table['direction']) && $table['direction'] == 'rtl' ) { $c['a'] = 'R'; }
18083 else { $c['a'] = 'L'; }
18084 }
18085
18086
18087 if (isset($properties['TEXT-ROTATE']) && ($properties['TEXT-ROTATE'] || $properties['TEXT-ROTATE']==="0")){
18088 $c['R'] = $properties['TEXT-ROTATE'];
18089 }
18090 if (isset($properties['BORDER'])) {
18091 $bord = $this->border_details($properties['BORDER']);
18092 if ($bord['s']) {
18093 if (!$this->simpleTables){
18094 $c['border'] = _BORDER_ALL;
18095 $c['border_details']['R'] = $bord;
18096 $c['border_details']['L'] = $bord;
18097 $c['border_details']['T'] = $bord;
18098 $c['border_details']['B'] = $bord;
18099 $c['border_details']['L']['dom'] = $this->cell_border_dominance_L;
18100 $c['border_details']['R']['dom'] = $this->cell_border_dominance_R;
18101 $c['border_details']['T']['dom'] = $this->cell_border_dominance_T;
18102 $c['border_details']['B']['dom'] = $this->cell_border_dominance_B;
18103 }
18104 else if ($this->simpleTables && $this->row==0 && $this->col==0){
18105 $table['simple']['border'] = _BORDER_ALL;
18106 $table['simple']['border_details']['R'] = $bord;
18107 $table['simple']['border_details']['L'] = $bord;
18108 $table['simple']['border_details']['T'] = $bord;
18109 $table['simple']['border_details']['B'] = $bord;
18110 }
18111 }
18112 }
18113 if (!$this->simpleTables){
18114 if (isset($properties['BORDER-RIGHT']) && $properties['BORDER-RIGHT']) {
18115 $c['border_details']['R'] = $this->border_details($properties['BORDER-RIGHT']);
18116 $this->setBorder($c['border'], _BORDER_RIGHT, $c['border_details']['R']['s']);
18117 $c['border_details']['R']['dom'] = $this->cell_border_dominance_R;
18118 }
18119 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) {
18120 $c['border_details']['L'] = $this->border_details($properties['BORDER-LEFT']);
18121 $this->setBorder($c['border'], _BORDER_LEFT, $c['border_details']['L']['s']);
18122 $c['border_details']['L']['dom'] = $this->cell_border_dominance_L;
18123 }
18124 if (isset($properties['BORDER-BOTTOM']) && $properties['BORDER-BOTTOM']) {
18125 $c['border_details']['B'] = $this->border_details($properties['BORDER-BOTTOM']);
18126 $this->setBorder($c['border'], _BORDER_BOTTOM, $c['border_details']['B']['s']);
18127 $c['border_details']['B']['dom'] = $this->cell_border_dominance_B;
18128 }
18129 if (isset($properties['BORDER-TOP']) && $properties['BORDER-TOP']) {
18130 $c['border_details']['T'] = $this->border_details($properties['BORDER-TOP']);
18131 $this->setBorder($c['border'], _BORDER_TOP, $c['border_details']['T']['s']);
18132 $c['border_details']['T']['dom'] = $this->cell_border_dominance_T;
18133 }
18134 }
18135 else if ($this->simpleTables && $this->row==0 && $this->col==0){
18136 if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) {
18137 $bord = $this->border_details($properties['BORDER-LEFT']);
18138 if ($bord['s']) { $table['simple']['border'] = _BORDER_ALL; }
18139 else { $table['simple']['border'] = 0; }
18140 $table['simple']['border_details']['R'] = $bord;
18141 $table['simple']['border_details']['L'] = $bord;
18142 $table['simple']['border_details']['T'] = $bord;
18143 $table['simple']['border_details']['B'] = $bord;
18144 }
18145 }
18146
18147 if ($this->simpleTables && $this->row==0 && $this->col==0 && !$table['borders_separate'] && $table['simple']['border'] ){
18148 $table['border_details'] = $table['simple']['border_details'];
18149 $table['border'] = $table['simple']['border'];
18150 }
18151
18152 // Border set on TR (if collapsed only)
18153 if (!$table['borders_separate'] && !$this->simpleTables && isset($table['trborder-left'][$this->row])) {
18154 if ($this->col==0) {
18155 $left = $this->border_details($table['trborder-left'][$this->row]);
18156 $c['border_details']['L'] = $left;
18157 $this->setBorder($c['border'], _BORDER_LEFT, $c['border_details']['L']['s']);
18158 }
18159 $c['border_details']['B'] = $this->border_details($table['trborder-bottom'][$this->row]);
18160 $this->setBorder($c['border'], _BORDER_BOTTOM, $c['border_details']['B']['s']);
18161 $c['border_details']['T'] = $this->border_details($table['trborder-top'][$this->row]);
18162 $this->setBorder($c['border'], _BORDER_TOP, $c['border_details']['T']['s']);
18163 }
18164
18165 if ($this->packTableData && !$this->simpleTables) {
18166 $c['borderbin'] = $this->_packCellBorder($c);
18167 unset($c['border']);
18168 unset($c['border_details']);
18169 }
18170
18171 if (isset($properties['PADDING-LEFT'])) {
18172 $c['padding']['L'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18173 }
18174 if (isset($properties['PADDING-RIGHT'])) {
18175 $c['padding']['R'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18176 }
18177 if (isset($properties['PADDING-BOTTOM'])) {
18178 $c['padding']['B'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18179 }
18180 if (isset($properties['PADDING-TOP'])) {
18181 $c['padding']['T'] = $this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18182 }
18183
18184 $w = '';
18185 if (isset($properties['WIDTH'])) { $w = $properties['WIDTH']; }
18186 else if (isset($attr['WIDTH'])) { $w = $attr['WIDTH']; }
18187 if ($w) {
18188 if (strpos($w,'%') && !$this->ignore_table_percents ) { $c['wpercent'] = $w + 0; } // makes 80% -> 80
18189 else if (!strpos($w,'%') && !$this->ignore_table_widths ) { $c['w'] = $this->ConvertSize($w,$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
18190 }
18191
18192 if (isset($properties['HEIGHT']) && !strpos($properties['HEIGHT'],'%')) { $c['h'] = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
18193 else if (isset($attr['HEIGHT']) && !strpos($attr['HEIGHT'],'%')) $c['h'] = $this->ConvertSize($attr['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18194
18195
18196 if (isset($properties['COLOR'])) {
18197 $cor = $this->ConvertColor($properties['COLOR']);
18198 if ($cor) {
18199 $this->colorarray = $cor;
18200 $this->SetTColor($cor);
18201 }
18202 }
18203 if (isset($properties['FONT-FAMILY'])) {
18204 $this->SetFont($properties['FONT-FAMILY'],'',0,false);
18205 }
18206 if (isset($properties['FONT-SIZE'])) {
18207 $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
18208 if ($mmsize) {
18209 $this->SetFontSize($mmsize*(_MPDFK),false);
18210 }
18211 }
18212 $c['dfs'] = $this->FontSize; // Default Font size
18213 if (isset($properties['FONT-WEIGHT'])) {
18214 if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->SetStyle('B',true); }
18215 }
18216 if (isset($properties['FONT-STYLE'])) {
18217 if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->SetStyle('I',true); }
18218 }
18219 if (isset($properties['FONT-VARIANT'])) {
18220 if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this->SetStyle('S',true); }
18221 }
18222 if (isset($properties['TEXT-DECORATION'])) {
18223 if (strtoupper($properties['TEXT-DECORATION']) == 'LINE-THROUGH') { $this->strike = true; }
18224 else if (strtoupper($properties['TEXT-DECORATION']) == 'UNDERLINE') { $this->SetStyle('U',true); }
18225 }
18226 if (isset($properties['TEXT-SHADOW'])) {
18227 $ts = $this->cssmgr->setCSStextshadow($properties['TEXT-SHADOW']);
18228 if ($ts) { $this->textshadow = $ts; }
18229 }
18230 if (isset($properties['TEXT-TRANSFORM'])) {
18231 if (strtoupper($properties['TEXT-TRANSFORM']) == 'CAPITALIZE') { $this->capitalize = true; }
18232 else if (strtoupper($properties['TEXT-TRANSFORM']) == 'UPPERCASE') { $this->toupper = true; }
18233 else if (strtoupper($properties['TEXT-TRANSFORM']) == 'LOWERCASE') { $this->tolower = true; }
18234 }
18235 if (isset($properties['WHITE-SPACE'])) {
18236 if (strtoupper($properties['WHITE-SPACE']) == 'NOWRAP') { $c['nowrap']= 1; }
18237 }
18238 $properties = array();
18239
18240 if (isset($attr['TEXT-ROTATE'])) {
18241 $c['R'] = $attr['TEXT-ROTATE'];
18242 }
18243 if (isset($attr['NOWRAP']) && $attr['NOWRAP']) $c['nowrap']= 1;
18244
18245 $this->cell[$this->row][$this->col] = $c;
18246 unset($c);
18247 $this->cell[$this->row][$this->col]['s'] = 0 ;
18248
18249 $cs = $rs = 1;
18250 if (isset($attr['COLSPAN']) && $attr['COLSPAN']>1) $cs = $this->cell[$this->row][$this->col]['colspan'] = $attr['COLSPAN'];
18251 if ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'] < $this->col+$cs) {
18252 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'] = $this->col+$cs;
18253 } // following code moved outside if...
18254 for($l=$this->col; $l < $this->col+$cs ;$l++) {
18255 if ($l-$this->col) $this->cell[$this->row][$l] = 0;
18256 }
18257
18258 if (isset($attr['ROWSPAN']) && $attr['ROWSPAN']>1) $rs = $this->cell[$this->row][$this->col]['rowspan'] = $attr['ROWSPAN'];
18259 for ($k=$this->row ; $k < $this->row+$rs ;$k++) {
18260 for($l=$this->col; $l < $this->col+$cs ;$l++) {
18261 if ($k-$this->row || $l-$this->col) $this->cell[$k][$l] = 0;
18262 }
18263 }
18264 unset($table);
18265 break;
18266 /*-- END TABLES --*/
18267
18268
18269 /*-- LISTS --*/
18270 // *********** LISTS ********************
18271 case 'OL':
18272 case 'UL':
18273 $this->listjustfinished = false;
18274
18275 if ($this->blockjustfinished && !count($this->textbuffer) && $this->y != $this->tMargin && $this->collapseBlockMargins) { $lastbottommargin = $this->lastblockbottommargin; }
18276 else { $lastbottommargin = 0; }
18277 $this->lastblockbottommargin = 0;
18278 $this->blockjustfinished=false;
18279
18280 $this->linebreakjustfinished=false;
18281 $this->lastoptionaltag = ''; // Save current HTML specified optional endtag
18282 $this->cssmgr->listCSSlvl++;
18283 if((!$this->tableLevel) && ($this->listlvl == 0)) {
18284 $blockstate = 0;
18285 //if ($this->lastblocklevelchange == 1) { $blockstate = -1; } // Top margins/padding only
18286 //else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
18287 // called from block after new div e.g. <div> ... <ol> ... Outputs block top margin/border and padding
18288 if (count($this->textbuffer) == 0 && $this->lastblocklevelchange == 1 && !$this->tableLevel && !$this->kwt) {
18289 $this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,1,true, $this->blk[$this->blklvl]['direction']);
18290 $this->finishFlowingBlock(true); // true = END of flowing block
18291 }
18292 else if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer,$blockstate); }
18293 $this->textbuffer=array();
18294 $this->lastblocklevelchange = -1;
18295 }
18296 // ol and ul types are mixed here
18297 if ($this->listlvl == 0) {
18298 $this->list_indent = array();
18299 $this->list_align = array();
18300 $this->list_lineheight = array();
18301 $this->InlineProperties['LIST'] = array();
18302 $this->InlineProperties['LISTITEM'] = array();
18303 }
18304
18305 /*-- TABLES --*/
18306 // A simple list for inside a table
18307 if($this->tableLevel) {
18308 $this->list_indent[$this->listlvl] = 0; // mm default indent for each level
18309 if ($tag == 'OL') $this->listtype = '1';
18310 else if ($tag == 'UL') $this->listtype = 'disc';
18311 if ($this->listlvl > 0) {
18312 $this->listlist[$this->listlvl]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
18313 }
18314 $this->listlvl++;
18315 // mPDF 5.6.15
18316 if (isset($attr['START'])) { $this->listnum = intval($attr['START']); }
18317 else { $this->listnum = 0; }
18318 $this->listlist[$this->listlvl] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
18319 break;
18320 }
18321 /*-- END TABLES --*/
18322
18323
18324 if (($this->PDFA || $this->PDFX) && $tag == 'UL') {
18325 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 '-')"; }
18326 }
18327
18328 if ($this->cssmgr->listCSSlvl==1) {
18329 $properties = $this->cssmgr->MergeCSS('TOPLIST',$tag,$attr);
18330 }
18331 else {
18332 $properties = $this->cssmgr->MergeCSS('LIST',$tag,$attr);
18333 }
18334 if (!empty($properties)) $this->setCSS($properties,'LIST');
18335 // List-type
18336
18337 $this->listtype = '';
18338 if (isset($properties['LIST-STYLE-TYPE'])) {
18339 $this->listtype = $this->_getListStyle($properties['LIST-STYLE-TYPE']);
18340 }
18341 else if (isset($properties['LIST-STYLE'])) {
18342 $this->listtype = $this->_getListStyle($properties['LIST-STYLE']);
18343 }
18344 else if (isset($attr['TYPE']) && $attr['TYPE']) { $this->listtype = $attr['TYPE']; }
18345 if (!$this->listtype) {
18346 if ($tag == 'OL') $this->listtype = '1';
18347 if ($tag == 'UL') {
18348 if ($this->listlvl % 3 == 0) $this->listtype = 'disc';
18349 elseif ($this->listlvl % 3 == 1) $this->listtype = 'circle';
18350 else $this->listtype = 'square';
18351 }
18352 }
18353 if ($this->listlvl == 0) {
18354 $this->inherit_lineheight = 0;
18355 $this->listlvl++; // first depth level
18356 // mPDF 5.6.15
18357 if (isset($attr['START'])) { $this->listnum = intval($attr['START']); }
18358 else { $this->listnum = 0; }
18359 $this->listDir = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : null);
18360 $occur = $this->listoccur[$this->listlvl] = 1;
18361 $this->listlist[$this->listlvl][1] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
18362 }
18363 else {
18364 if (!empty($this->textbuffer))
18365 {
18366 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
18367 $this->listnum++;
18368 }
18369 // Save current lineheight to inherit
18370 $this->textbuffer = array();
18371 $occur = $this->listoccur[$this->listlvl];
18372 $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
18373 $this->listlvl++;
18374 // mPDF 5.6.15
18375 if (isset($attr['START'])) { $this->listnum = intval($attr['START']); }
18376 else { $this->listnum = 0; }
18377
18378
18379 if (!isset($this->listoccur[$this->listlvl]) || $this->listoccur[$this->listlvl] == 0) $this->listoccur[$this->listlvl] = 1;
18380 else $this->listoccur[$this->listlvl]++;
18381 $occur = $this->listoccur[$this->listlvl];
18382 $this->listlist[$this->listlvl][$occur] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
18383 }
18384
18385
18386 // TOP LEVEL ONLY
18387 if ($this->listlvl == 1) {
18388 if (isset($properties['MARGIN-TOP'])) {
18389 if ($lastbottommargin) {
18390 $tmp = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18391 if ($tmp > $lastbottommargin) { $properties['MARGIN-TOP'] -= $lastbottommargin; }
18392 else { $properties['MARGIN-TOP'] = 0; }
18393 }
18394 $this->DivLn($this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false),$this->blklvl,true,1); // collapsible
18395 }
18396 if (isset($properties['MARGIN-BOTTOM'])) {
18397 $this->list_margin_bottom = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
18398 }
18399
18400 if (isset($this->blk[$this->blklvl]['line_height'])) {
18401 $this->list_lineheight[$this->listlvl][$occur] = $this->blk[$this->blklvl]['line_height'];
18402 }
18403
18404 if (isset($properties['DIRECTION']) && $properties['DIRECTION']) { $this->listDir = strtolower($properties['DIRECTION']); }
18405 else if (isset($attr['DIR']) && $attr['DIR']) { $this->listDir = strtolower($attr['DIR']); }
18406
18407 }
18408 $this->list_indent[$this->listlvl][$occur] = 5; // mm default indent for each level
18409 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); }
18410
18411 if (isset($properties['TEXT-ALIGN'])) {
18412 $this->list_align[$this->listlvl][$occur] = $align[strtolower($properties['TEXT-ALIGN'])];
18413 }
18414
18415
18416 if (isset($properties['LINE-HEIGHT'])) {
18417 $this->list_lineheight[$this->listlvl][$occur] = $this->fixLineheight($properties['LINE-HEIGHT']);
18418 }
18419 else if ($this->listlvl>1 && isset($this->list_lineheight[($this->listlvl - 1)][1])) {
18420 $this->list_lineheight[$this->listlvl][$occur] = end($this->list_lineheight[($this->listlvl - 1)]);
18421 }
18422 if (!isset($this->list_lineheight[$this->listlvl][$occur]) || !$this->list_lineheight[$this->listlvl][$occur]) {
18423 $this->list_lineheight[$this->listlvl][$occur] = $this->normalLineheight;
18424 }
18425
18426 $this->InlineProperties['LIST'][$this->listlvl][$occur] = $this->saveInlineProperties();
18427 $properties = array();
18428 break;
18429
18430
18431
18432 case 'LI':
18433 // Start Block
18434 $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
18435 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
18436 /*-- TABLES --*/
18437 // A simple list for inside a table
18438 if($this->tableLevel) {
18439 $this->blockjustfinished=false;
18440
18441 // If already something in the Cell
18442 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 ) {
18443 $this->_saveCellTextBuffer("\n");
18444 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
18445 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18446 }
18447 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
18448 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18449 }
18450 $this->cell[$this->row][$this->col]['s'] = 0 ;
18451 }
18452 if ($this->listlvl == 0) { //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
18453 $this->listlvl++; // first depth level
18454 $this->listnum = 0; // reset
18455 $this->listlist[$this->listlvl] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum);
18456 }
18457
18458 $this->listnum++;
18459 switch($this->listlist[$this->listlvl]['TYPE']) {
18460 case 'A':
18461 $blt = $this->dec2alpha($this->listnum,true).$this->list_number_suffix;
18462 break;
18463 case 'a':
18464 $blt = $this->dec2alpha($this->listnum,false).$this->list_number_suffix;
18465 break;
18466 case 'I':
18467 $blt = $this->dec2roman($this->listnum,true).$this->list_number_suffix;
18468 break;
18469 case 'i':
18470 $blt = $this->dec2roman($this->listnum,false).$this->list_number_suffix;
18471 break;
18472 case '1':
18473 $blt = $this->listnum.$this->list_number_suffix;
18474 break;
18475 default:
18476 if ($this->listlvl % 3 == 1 && $this->_charDefined($this->CurrentFont['cw'],8226)) { $blt = "\xe2\x80\xa2"; } // &#8226;
18477 else if ($this->listlvl % 3 == 2 && $this->_charDefined($this->CurrentFont['cw'],9900)) { $blt = "\xe2\x9a\xac"; } // &#9900;
18478 else if ($this->listlvl % 3 == 0 && $this->_charDefined($this->CurrentFont['cw'],9642)) { $blt = "\xe2\x96\xaa"; } // &#9642;
18479 else { $blt = '-'; }
18480 break;
18481 }
18482
18483 // change to &nbsp; spaces
18484 if ($this->usingCoreFont) {
18485 $ls = str_repeat(chr(160).chr(160),($this->listlvl-1)*2) . $blt . ' ';
18486 }
18487 else {
18488 $ls = str_repeat("\xc2\xa0\xc2\xa0",($this->listlvl-1)*2) . $blt . ' ';
18489 }
18490
18491 $this->_saveCellTextBuffer($ls, $this->HREF);
18492 $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($ls);
18493 break;
18494 }
18495 /*-- END TABLES --*/
18496 //Observation: </LI> is ignored
18497 if ($this->listlvl == 0) { //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
18498 //First of all, skip a line
18499 $this->listlvl++; // first depth level
18500 $this->listnum = 0; // reset
18501 $this->listoccur[$this->listlvl] = 1;
18502 $this->listlist[$this->listlvl][1] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum);
18503 }
18504 if ($this->listnum == 0) {
18505 $this->listnum++;
18506 $this->textbuffer = array();
18507 }
18508 else {
18509 if (!empty($this->textbuffer)) {
18510 if (!$this->listjustfinished) {
18511 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
18512 $this->listnum++;
18513 }
18514 else {
18515 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype, true);
18516 }
18517 }
18518 $this->textbuffer = array();
18519 }
18520 $this->listjustfinished = false;
18521
18522 $this->cssmgr->listCSSlvl++;
18523 $properties = $this->cssmgr->MergeCSS('LIST',$tag,$attr);
18524 if (!empty($properties)) $this->setCSS($properties,'LIST');
18525 $this->InlineProperties['LISTITEM'][$this->listlvl][$this->listoccur[$this->listlvl]][$this->listnum] = $this->saveInlineProperties();
18526
18527 // List-type
18528 if (isset($properties['LIST-STYLE-TYPE'])) {
18529 $this->listitemtype = $this->_getListStyle($properties['LIST-STYLE-TYPE']);
18530 }
18531 else if (isset($properties['LIST-STYLE'])) {
18532 $this->listitemtype = $this->_getListStyle($properties['LIST-STYLE']);
18533 }
18534 else if (isset($attr['TYPE']) && $attr['TYPE']) { $this->listitemtype = $attr['TYPE']; }
18535 else $this->listitemtype = '';
18536 break;
18537 /*-- END LISTS --*/
18538
18539 }//end of switch
18540 }
18541
18542 /*-- LISTS --*/
18543
18544 function _getListStyle($ls) {
18545 if (stristr($ls,'decimal')) { return '1'; }
18546 else if (preg_match('/(disc|circle|square|arabic-indic|bengali|devanagari|gujarati|gurmukhi|kannada|malayalam|oriya|persian|tamil|telugu|thai|urdu|cambodian|khmer|lao)/i',$ls,$m)) {
18547 return strtolower(trim($m[1]));
18548 }
18549 else if (stristr($ls,'lower-roman')) { return 'i'; }
18550 else if (stristr($ls,'upper-roman')) { return 'I'; }
18551 else if (stristr($ls,'lower-latin')|| stristr($ls,'lower-alpha')) { return 'a'; }
18552 else if (stristr($ls,'upper-latin') || stristr($ls,'upper-alpha')) { return 'A'; }
18553 else if (stristr($ls,'none')) { return 'none'; }
18554 else if (preg_match('/U\+([a-fA-F0-9]+)/i',$ls)) { return $ls; }
18555 else { return ''; }
18556 }
18557 /*-- END LISTS --*/
18558
18559
18560
18561 function CloseTag($tag)
18562 {
18563 $this->ignorefollowingspaces = false; //Eliminate exceeding left-side spaces
18564 //Closing tag
18565 if($tag=='OPTION') { $this->selectoption['ACTIVE'] = false; $this->lastoptionaltag = ''; }
18566
18567 if($tag=='TTS' or $tag=='TTA' or $tag=='TTZ') {
18568 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18569 unset($this->InlineProperties[$tag]);
18570 $ltag = strtolower($tag);
18571 $this->$ltag = false;
18572 }
18573
18574
18575 if($tag=='FONT' || $tag=='SPAN' || $tag=='CODE' || $tag=='KBD' || $tag=='SAMP' || $tag=='TT' || $tag=='VAR'
18576 || $tag=='INS' || $tag=='STRONG' || $tag=='CITE' || $tag=='SUB' || $tag=='SUP' || $tag=='S' || $tag=='STRIKE' || $tag=='DEL'
18577 || $tag=='Q' || $tag=='EM' || $tag=='B' || $tag=='I' || $tag=='U' | $tag=='SMALL' || $tag=='BIG' || $tag=='ACRONYM'
18578 || $tag=='MARK' || $tag=='TIME' || $tag=='PROGRESS' || $tag=='METER'
18579 ) { // mPDF 5.5.09
18580
18581 // mPDF 5.7.3 Inline tags
18582 if ($tag=='PROGRESS' || $tag=='METER') {
18583 if (isset($this->InlineProperties[$tag]) && $this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18584 unset($this->InlineProperties[$tag]);
18585 if (isset($this->InlineAnnots[$tag]) && $this->InlineAnnots[$tag]) { $annot = $this->InlineAnnots[$tag]; } // *ANNOTATIONS*
18586 unset($this->InlineAnnots[$tag]); // *ANNOTATIONS*
18587 }
18588 else {
18589 if (isset($this->InlineProperties[$tag]) && count($this->InlineProperties[$tag])) {
18590 $tmpProps = array_pop($this->InlineProperties[$tag]); // mPDF 5.7.4
18591 $this->restoreInlineProperties($tmpProps);
18592 }
18593 if (isset($this->InlineAnnots[$tag]) && count($this->InlineAnnots[$tag])) { // *ANNOTATIONS*
18594 $annot = array_pop($this->InlineAnnots[$tag]); // *ANNOTATIONS*
18595 } // *ANNOTATIONS*
18596 }
18597
18598 /*-- ANNOTATIONS --*/
18599 if (isset($annot)) {
18600 if($this->tableLevel) { // *TABLES*
18601 $this->cell[$this->row][$this->col]['textbuffer'][] = array($annot); // *TABLES*
18602 } // *TABLES*
18603 else { // *TABLES*
18604 $this->textbuffer[] = array($annot);
18605 } // *TABLES*
18606 }
18607 /*-- END ANNOTATIONS --*/
18608 }
18609
18610 if($tag=='METER' || $tag=='PROGRESS') {
18611 $this->inMeter = false; // mPDF 5.5.09
18612 }
18613
18614
18615 if($tag=='A') {
18616 $this->HREF='';
18617 if (isset($this->InlineProperties['A'])) { $this->restoreInlineProperties($this->InlineProperties['A']); }
18618 unset($this->InlineProperties['A']);
18619 }
18620
18621 if($tag=='LEGEND') { // mPDF 5.4.18
18622 if (count($this->textbuffer) && !$this->tableLevel) {
18623 $leg = $this->textbuffer[(count($this->textbuffer)-1)];
18624 unset($this->textbuffer[(count($this->textbuffer)-1)]);
18625 $this->textbuffer = array_values($this->textbuffer);
18626 $this->blk[$this->blklvl]['border_legend'] = $leg;
18627 $this->blk[$this->blklvl]['margin_top'] += ($leg[11]/2)/_MPDFK;
18628 $this->blk[$this->blklvl]['padding_top'] += ($leg[11]/2)/_MPDFK;
18629 }
18630 if (isset($this->InlineProperties['LEGEND'])) { $this->restoreInlineProperties($this->InlineProperties['LEGEND']); }
18631 unset($this->InlineProperties['LEGEND']);
18632 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
18633 }
18634
18635
18636
18637 /*-- FORMS --*/
18638 // *********** FORM ELEMENTS ********************
18639
18640 if($tag=='TEXTAREA') {
18641 $this->specialcontent = '';
18642 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18643 unset($this->InlineProperties[$tag]);
18644 }
18645
18646
18647 if($tag=='SELECT') {
18648 $this->lastoptionaltag = '';
18649 $texto = '';
18650 if (isset($this->selectoption['SELECTED'])) { $texto = $this->selectoption['SELECTED']; }
18651
18652 if ($this->useActiveForms) { $w = $this->selectoption['MAXWIDTH']; }
18653 else { $w = $this->GetStringWidth($texto); }
18654 if ($w == 0) { $w = 5; }
18655 $objattr['type'] = 'select';
18656 $objattr['text'] = $texto;
18657 if (isset($this->selectoption['NAME'])) { $objattr['fieldname'] = $this->selectoption['NAME']; }
18658 if (isset($this->selectoption['READONLY'])) { $objattr['readonly'] = true; }
18659 if (isset($this->selectoption['REQUIRED'])) { $objattr['required'] = true; }
18660 if (isset($this->selectoption['SPELLCHECK'])) { $objattr['spellcheck'] = true; }
18661 if (isset($this->selectoption['EDITABLE'])) { $objattr['editable'] = true; }
18662 if (isset($this->selectoption['ONCHANGE'])) { $objattr['onChange'] = $this->selectoption['ONCHANGE']; }
18663 if (isset($this->selectoption['ITEMS'])) { $objattr['items'] = $this->selectoption['ITEMS']; }
18664 if (isset($this->selectoption['MULTIPLE'])) { $objattr['multiple'] = $this->selectoption['MULTIPLE']; }
18665 if (isset($this->selectoption['DISABLED'])) { $objattr['disabled'] = $this->selectoption['DISABLED']; }
18666 if (isset($this->selectoption['TITLE'])) { $objattr['title'] = $this->selectoption['TITLE']; }
18667 if (isset($this->selectoption['COLOR'])) { $objattr['color'] = $this->selectoption['COLOR']; }
18668 if (isset($this->selectoption['SIZE'])) { $objattr['size'] = $this->selectoption['SIZE']; }
18669 if (isset($objattr['size']) && $objattr['size']>1) { $rows=$objattr['size']; } else { $rows = 1; }
18670
18671 $objattr['fontfamily'] = $this->FontFamily;
18672 $objattr['fontsize'] = $this->FontSizePt;
18673
18674 $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);
18675 $objattr['height'] = ($this->FontSize*$rows) + ($this->form->form_element_spacing['select']['outer']['v']*2)+($this->form->form_element_spacing['select']['inner']['v']*2);
18676 $e = "\xbb\xa4\xactype=select,objattr=".serialize($objattr)."\xbb\xa4\xac";
18677
18678 // Clear properties - tidy up
18679 $properties = array();
18680
18681 // Output it to buffers
18682 if ($this->tableLevel) { // *TABLES*
18683 $this->_saveCellTextBuffer($e, $this->HREF);
18684 $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ; // *TABLES*
18685 } // *TABLES*
18686 else { // *TABLES*
18687 $this->_saveTextBuffer($e, $this->HREF);
18688 } // *TABLES*
18689
18690 $this->selectoption = array();
18691 $this->specialcontent = '';
18692
18693 if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
18694 unset($this->InlineProperties[$tag]);
18695
18696 }
18697 /*-- END FORMS --*/
18698
18699
18700 // *********** BLOCKS ********************
18701 if($tag=='P' || $tag=='DIV' || $tag=='H1' || $tag=='H2' || $tag=='H3' || $tag=='H4' || $tag=='H5' || $tag=='H6' || $tag=='PRE'
18702 || $tag=='FORM' || $tag=='ADDRESS' || $tag=='BLOCKQUOTE' || $tag=='CENTER' || $tag=='DT' || $tag=='DD' || $tag=='DL'
18703 || $tag=='CAPTION' || $tag=='FIELDSET'
18704 || $tag=='ARTICLE' || $tag=='ASIDE' || $tag=='FIGURE' || $tag=='FIGCAPTION' || $tag=='FOOTER' || $tag=='HEADER' || $tag=='HGROUP'
18705 || $tag=='MAIN' || $tag=='NAV' || $tag=='SECTION' || $tag=='DETAILS' || $tag=='SUMMARY'
18706 ) { // mPDF 5.7.3
18707
18708 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
18709 $this->blockjustfinished=true;
18710
18711 $this->lastblockbottommargin = $this->blk[$this->blklvl]['margin_bottom'];
18712 /*-- LISTS --*/
18713 if ($this->listlvl>0) { return; }
18714 /*-- END LISTS --*/
18715
18716 // mPDF 5.6.34
18717 if (preg_match('/^H\d/',$tag) && !$this->tableLevel && !$this->writingToC) { // mPDF 5.6.38
18718 if (isset($this->h2toc[$tag]) || isset($this->h2bookmarks[$tag])) {
18719 $content = '';
18720 if (count($this->textbuffer)==1) { $content = $this->textbuffer[0][0]; }
18721 else {
18722 for ($i=0;$i<count($this->textbuffer);$i++) {
18723 if (substr($this->textbuffer[$i][0],0,3) != "\xbb\xa4\xac") { //inline object
18724 $content .= $this->textbuffer[$i][0];
18725 }
18726 }
18727 }
18728 /*-- TOC --*/
18729 if (isset($this->h2toc[$tag])) {
18730 $objattr = array();
18731 $objattr['type'] = 'toc';
18732 $objattr['toclevel'] = $this->h2toc[$tag];
18733 $objattr['CONTENT'] = htmlspecialchars($content); // mPDF 5.6.37
18734 $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
18735 array_unshift($this->textbuffer,array($e));
18736 }
18737 /*-- END TOC --*/
18738 /*-- BOOKMARKS --*/
18739 if (isset($this->h2bookmarks[$tag])) {
18740 $objattr = array();
18741 $objattr['type'] = 'bookmark';
18742 $objattr['bklevel'] = $this->h2bookmarks[$tag];
18743 $objattr['CONTENT'] = $content;
18744 $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
18745 array_unshift($this->textbuffer,array($e));
18746 }
18747 /*-- END BOOKMARKS --*/
18748 }
18749 }
18750
18751 /*-- TABLES --*/
18752 if($this->tableLevel) {
18753 if ($this->linebreakjustfinished) { $this->blockjustfinished=false; }
18754 if (isset($this->InlineProperties['BLOCKINTABLE'])) {
18755 if ($this->InlineProperties['BLOCKINTABLE']) { $this->restoreInlineProperties($this->InlineProperties['BLOCKINTABLE']); }
18756 unset($this->InlineProperties['BLOCKINTABLE']);
18757 }
18758 if($tag=='PRE') { $this->ispre=false; }
18759 return;
18760 }
18761 /*-- END TABLES --*/
18762 $this->lastoptionaltag = '';
18763 $this->divbegin=false;
18764
18765 $this->linebreakjustfinished=false;
18766
18767 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
18768
18769 /*-- CSS-FLOAT --*/
18770 // If float contained in a float, need to extend bottom to allow for it
18771 $currpos = $this->page*1000 + $this->y;
18772 if (isset($this->blk[$this->blklvl]['float_endpos']) && $this->blk[$this->blklvl]['float_endpos'] > $currpos) {
18773 $old_page = $this->page;
18774 $new_page = intval($this->blk[$this->blklvl]['float_endpos'] /1000);
18775 if ($old_page != $new_page) {
18776 $s = $this->PrintPageBackgrounds();
18777 // Writes after the marker so not overwritten later by page background etc.
18778 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
18779 $this->pageBackgrounds = array();
18780 $this->page = $new_page;
18781 $this->ResetMargins();
18782 $this->Reset();
18783 $this->pageoutput[$this->page] = array();
18784 }
18785 $this->y = (($this->blk[$this->blklvl]['float_endpos'] *1000) % 1000000)/1000; // mod changes operands to integers before processing
18786 }
18787 /*-- END CSS-FLOAT --*/
18788
18789
18790 //Print content
18791 if ($this->lastblocklevelchange == 1) { $blockstate = 3; } // Top & bottom margins/padding
18792 else if ($this->lastblocklevelchange == -1) { $blockstate = 2; } // Bottom margins/padding only
18793 else { $blockstate = 0; }
18794 // called from after e.g. </table> </div> </div> ... Outputs block margin/border and padding
18795 if (count($this->textbuffer) && $this->textbuffer[count($this->textbuffer)-1]) {
18796 if (substr($this->textbuffer[count($this->textbuffer)-1][0],0,3) != "\xbb\xa4\xac") { // not special content
18797 if ($this->usingCoreFont) {
18798 $this->textbuffer[count($this->textbuffer)-1][0] = preg_replace('/[ ]+$/', '', $this->textbuffer[count($this->textbuffer)-1][0]);
18799 }
18800 else {
18801 $this->textbuffer[count($this->textbuffer)-1][0] = preg_replace('/[ ]+$/u', '', $this->textbuffer[count($this->textbuffer)-1][0]); }
18802 }
18803 }
18804
18805 if (count($this->textbuffer) == 0 && $this->lastblocklevelchange != 0) {
18806 //$this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,2,true, $this->blk[$this->blklvl]['direction']);
18807 $this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,false,$blockstate,true, $this->blk[$this->blklvl]['direction']);
18808 $this->finishFlowingBlock(true); // true = END of flowing block
18809 $this->PaintDivBB('',$blockstate);
18810 }
18811 else {
18812 $this->printbuffer($this->textbuffer,$blockstate);
18813 }
18814
18815
18816 $this->textbuffer=array();
18817
18818 if ($this->blk[$this->blklvl]['keep_block_together']) {
18819 $this->printdivbuffer();
18820 }
18821
18822 if ($this->kwt) {
18823 $this->kwt_height = $this->y - $this->kwt_y0;
18824 }
18825
18826 /*-- CSS-IMAGE-FLOAT --*/
18827 $this->printfloatbuffer();
18828 /*-- END CSS-IMAGE-FLOAT --*/
18829
18830 if($tag=='PRE') { $this->ispre=false; }
18831
18832 /*-- CSS-FLOAT --*/
18833 if ($this->blk[$this->blklvl]['float'] == 'R') {
18834 // If width not set, here would need to adjust and output buffer
18835 $s = $this->PrintPageBackgrounds();
18836 // Writes after the marker so not overwritten later by page background etc.
18837 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
18838 $this->pageBackgrounds = array();
18839 $this->Reset();
18840 $this->pageoutput[$this->page] = array();
18841
18842 for($i=($this->blklvl-1); $i >= 0; $i--) {
18843 if (isset($this->blk[$i]['float_endpos'])) { $this->blk[$i]['float_endpos'] = max($this->blk[$i]['float_endpos'], ($this->page*1000 + $this->y)); }
18844 else { $this->blk[$i]['float_endpos'] = $this->page*1000 + $this->y; }
18845 }
18846
18847 $this->floatDivs[] = array(
18848 'side'=>'R',
18849 'startpage'=>$this->blk[$this->blklvl]['startpage'] ,
18850 'y0'=>$this->blk[$this->blklvl]['float_start_y'] ,
18851 'startpos'=> ($this->blk[$this->blklvl]['startpage']*1000 + $this->blk[$this->blklvl]['float_start_y']),
18852 'endpage'=>$this->page ,
18853 'y1'=>$this->y ,
18854 'endpos'=> ($this->page*1000 + $this->y),
18855 'w'=> $this->blk[$this->blklvl]['float_width'],
18856 'blklvl'=>$this->blklvl,
18857 'blockContext' => $this->blk[$this->blklvl-1]['blockContext']
18858 );
18859
18860 $this->y = $this->blk[$this->blklvl]['float_start_y'] ;
18861 $this->page = $this->blk[$this->blklvl]['startpage'] ;
18862 $this->ResetMargins();
18863 $this->pageoutput[$this->page] = array();
18864 }
18865 if ($this->blk[$this->blklvl]['float'] == 'L') {
18866 // If width not set, here would need to adjust and output buffer
18867 $s = $this->PrintPageBackgrounds();
18868 // Writes after the marker so not overwritten later by page background etc.
18869 $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
18870 $this->pageBackgrounds = array();
18871 $this->Reset();
18872 $this->pageoutput[$this->page] = array();
18873
18874 for($i=($this->blklvl-1); $i >= 0; $i--) {
18875 if (isset($this->blk[$i]['float_endpos'])) { $this->blk[$i]['float_endpos'] = max($this->blk[$i]['float_endpos'], ($this->page*1000 + $this->y)); }
18876 else { $this->blk[$i]['float_endpos'] = $this->page*1000 + $this->y; }
18877 }
18878
18879 $this->floatDivs[] = array(
18880 'side'=>'L',
18881 'startpage'=>$this->blk[$this->blklvl]['startpage'] ,
18882 'y0'=>$this->blk[$this->blklvl]['float_start_y'] ,
18883 'startpos'=> ($this->blk[$this->blklvl]['startpage']*1000 + $this->blk[$this->blklvl]['float_start_y']),
18884 'endpage'=>$this->page ,
18885 'y1'=>$this->y ,
18886 'endpos'=> ($this->page*1000 + $this->y),
18887 'w'=> $this->blk[$this->blklvl]['float_width'],
18888 'blklvl'=>$this->blklvl,
18889 'blockContext' => $this->blk[$this->blklvl-1]['blockContext']
18890 );
18891
18892 $this->y = $this->blk[$this->blklvl]['float_start_y'] ;
18893 $this->page = $this->blk[$this->blklvl]['startpage'] ;
18894 $this->ResetMargins();
18895 $this->pageoutput[$this->page] = array();
18896 }
18897 /*-- END CSS-FLOAT --*/
18898
18899 if (isset($this->blk[$this->blklvl]['visibility']) && $this->blk[$this->blklvl]['visibility']!='visible') {
18900 $this->SetVisibility('visible');
18901 }
18902
18903 if (isset($this->blk[$this->blklvl]['page_break_after'])) { $page_break_after = $this->blk[$this->blklvl]['page_break_after']; }
18904 else { $page_break_after = ''; }
18905
18906 //Reset values
18907 $this->Reset();
18908
18909 // mPDF 5.6.01 - LAYERS
18910 if (isset($this->blk[$this->blklvl]['z-index']) && $this->blk[$this->blklvl]['z-index'] > 0) {
18911 $this->EndLayer();
18912 }
18913
18914 if ($this->blklvl > 0) { // ==0 SHOULDN'T HAPPEN - NOT XHTML
18915 if ($this->blk[$this->blklvl]['tag'] == $tag) {
18916 unset($this->blk[$this->blklvl]);
18917 $this->blklvl--;
18918 }
18919 //else { echo $tag; exit; } // debug - forces error if incorrectly nested html tags
18920 }
18921
18922 $this->lastblocklevelchange = -1 ;
18923 // Reset Inline-type properties
18924 if (isset($this->blk[$this->blklvl]['InlineProperties'])) { $this->restoreInlineProperties($this->blk[$this->blklvl]['InlineProperties']); }
18925
18926 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
18927
18928 if ($page_break_after) {
18929 $save_blklvl = $this->blklvl;
18930 $save_blk = $this->blk;
18931 $save_silp = $this->saveInlineProperties();
18932 $save_ilp = $this->InlineProperties;
18933 if ($this->blklvl>1) {
18934 // Close any open block tags
18935 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
18936 // Output any text left in buffer
18937 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); $this->textbuffer=array(); }
18938 }
18939 /*-- COLUMNS --*/
18940 $save_cols = false;
18941 if ($this->ColActive) {
18942 $save_cols = true;
18943 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
18944 $this->SetColumns(0);
18945 }
18946 /*-- END COLUMNS --*/
18947 if ($page_break_after == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
18948 else if ($page_break_after == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
18949 else { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
18950 // mPDF 5.7.3
18951 if (!$this->restoreBlockPagebreaks) {
18952 $this->blklvl = 0;
18953 $this->lastblocklevelchange = 0;
18954 $this->Reset();
18955 $this->restoreInlineProperties($this->blk[0]['InlineProperties']);
18956 }
18957 /*-- COLUMNS --*/
18958 if ($save_cols) {
18959 // Restore columns
18960 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
18961 }
18962 /*-- END COLUMNS --*/
18963 if ($this->restoreBlockPagebreaks && !$this->tableLevel && !$this->listlvl) {
18964 $this->blk = $save_blk;
18965 // Re-open block tags
18966 $t = $this->blk[0]['tag'];
18967 $a = $this->blk[0]['attr'];
18968 $this->blklvl = 0;
18969 for ($b=0; $b<=$save_blklvl;$b++) {
18970 $tc = $t;
18971 $ac = $a;
18972 $t = $this->blk[$b+1]['tag'];
18973 $a = $this->blk[$b+1]['attr'];
18974 unset($this->blk[$b+1]);
18975 $this->OpenTag($tc,$ac);
18976 }
18977 $this->InlineProperties = $save_ilp;
18978 $this->restoreInlineProperties($save_silp);
18979 }
18980 }
18981
18982 }
18983
18984
18985 /*-- TABLES --*/
18986
18987 if($tag=='TH') $this->SetStyle('B',false);
18988
18989 if(($tag=='TH' or $tag=='TD') && $this->tableLevel) {
18990 $this->lastoptionaltag = 'TR';
18991 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
18992 $this->cssmgr->tbCSSlvl--;
18993 if (!$this->tdbegin) { return; }
18994 $this->tdbegin = false;
18995 // Added for correct calculation of cell column width - otherwise misses the last line if not end </p> etc.
18996 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
18997 if (!is_array($this->cell[$this->row][$this->col])) { $this->Error("You may have an error in your HTML code e.g. &lt;/td&gt;&lt;/td&gt;"); }
18998 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
18999 }
19000 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
19001 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
19002 }
19003
19004 // Remove last <br> if at end of cell
19005 if (isset($this->cell[$this->row][$this->col]['textbuffer'])) { $ntb = count($this->cell[$this->row][$this->col]['textbuffer']); }
19006 else { $ntb = 0; }
19007 if ($ntb>1 && $this->cell[$this->row][$this->col]['textbuffer'][$ntb-1][0] == "\n") {
19008 unset($this->cell[$this->row][$this->col]['textbuffer'][$ntb-1]);
19009 }
19010
19011 if ($this->cacheTables) {
19012 $clen = $this->_cacheCell($this->cell[$this->row][$this->col], $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cache']);
19013 $this->cell[$this->row][$this->col] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['ptr'];
19014 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['ptr'] += $clen;
19015 }
19016
19017 if ($this->tablethead) {
19018 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead'][$this->row] = true;
19019 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)); }
19020 }
19021 if ($this->tabletfoot) {
19022 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$this->row] = true;
19023 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'] )); }
19024 }
19025 $this->Reset();
19026 }
19027
19028 if($tag=='TR' && $this->tableLevel) {
19029 // If Border set on TR - Update right border
19030 if (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-left'][$this->row])) {
19031 if ($this->cacheTables) {
19032 $c = $this->_uncacheCell($this->cell[$this->row][$this->col], $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cache'], null);
19033 }
19034 else { $c =& $this->cell[$this->row][$this->col]; }
19035 if ($c) {
19036 if ($this->packTableData) {
19037 $cell = $this->_unpackCellBorder($c['borderbin'] );
19038 }
19039 else { $cell = $c; }
19040 $cell['border_details']['R'] = $this->border_details($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-right'][$this->row]);
19041 $this->setBorder($cell['border'], _BORDER_RIGHT, $cell['border_details']['R']['s']);
19042 if ($this->packTableData) {
19043 $c['borderbin'] = $this->_packCellBorder($cell);
19044 unset($c['border']);
19045 unset($c['border_details']);
19046 }
19047 else { $c = $cell; }
19048 }
19049 if ($this->cacheTables) {
19050 $fh = fopen($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cache'], "r+b");
19051 $this->_cacheUpdateBorder($c, $fh, $this->cell[$this->row][$this->col]);
19052 fclose($fh);
19053 }
19054 }
19055 $this->lastoptionaltag = '';
19056 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
19057 $this->cssmgr->tbCSSlvl--;
19058 $this->trow_text_rotate = '';
19059 $this->tabletheadjustfinished = false;
19060 }
19061
19062 if($tag=='TBODY') {
19063 $this->lastoptionaltag = '';
19064 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
19065 $this->cssmgr->tbCSSlvl--;
19066 }
19067
19068 if($tag=='THEAD') {
19069 $this->lastoptionaltag = '';
19070 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
19071 $this->cssmgr->tbCSSlvl--;
19072 $this->tablethead = 0;
19073 $this->tabletheadjustfinished = true;
19074 $this->ResetStyles();
19075 $this->thead_font_weight = '';
19076 $this->thead_font_style = '';
19077 $this->thead_font_smCaps = '';
19078
19079 $this->thead_valign_default = '';
19080 $this->thead_textalign_default = '';
19081 }
19082
19083 if($tag=='TFOOT') {
19084 $this->lastoptionaltag = '';
19085 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
19086 $this->cssmgr->tbCSSlvl--;
19087 $this->tabletfoot = 0;
19088 $this->ResetStyles();
19089 $this->tfoot_font_weight = '';
19090 $this->tfoot_font_style = '';
19091 $this->tfoot_font_smCaps = '';
19092
19093 $this->tfoot_valign_default = '';
19094 $this->tfoot_textalign_default = '';
19095 }
19096
19097 if($tag=='TABLE') { // TABLE-END (
19098 if ($this->progressBar) { $this->UpdateProgressBar(1,'','TABLE'); } // *PROGRESS-BAR*
19099 if ($this->progressBar) { $this->UpdateProgressBar(7,0,''); } // *PROGRESS-BAR*
19100 $this->lastoptionaltag = '';
19101 unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
19102 $this->cssmgr->tbCSSlvl--;
19103 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
19104
19105 // mPDF 5.7.3
19106 // In case a colspan (on a row after first row) exceeded number of columns in table
19107 for ($k=0; $k < $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']; $k++) {
19108 for($l=0; $l < $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc']; $l++) {
19109 if (!isset($this->cell[$k][$l])) {
19110 for ($n=$l-1; $n>=0; $n--) {
19111 if (isset($this->cell[$k][$n]) && $this->cell[$k][$n]!=0) { break; }
19112 }
19113 $this->cell[$k][$l] = array(
19114 'a' => 'C',
19115 'va' => 'M',
19116 'R' => false,
19117 'nowrap' => false,
19118 'bgcolor' => false,
19119 'padding' => array('L' => false, 'R' => false, 'T' => false, 'B' => false),
19120 'gradient' => false,
19121 's' => 0,
19122 'maxs' => 0,
19123 'textbuffer' => array(),
19124 'dfs' => $this->FontSize,
19125 );
19126
19127 if (!$this->simpleTables){
19128 $this->cell[$k][$l]['border'] = 0;
19129 $this->cell[$k][$l]['border_details']['R'] = array('s' => 0, 'w' => 0, 'c' => false, 'style' => 'none', 'dom' => 0);
19130 $this->cell[$k][$l]['border_details']['L'] = array('s' => 0, 'w' => 0, 'c' => false, 'style' => 'none', 'dom' => 0);
19131 $this->cell[$k][$l]['border_details']['T'] = array('s' => 0, 'w' => 0, 'c' => false, 'style' => 'none', 'dom' => 0);
19132 $this->cell[$k][$l]['border_details']['B'] = array('s' => 0, 'w' => 0, 'c' => false, 'style' => 'none', 'dom' => 0);
19133 $this->cell[$k][$l]['border_details']['mbw'] = array('BL' =>0,'BR' =>0,'RT' =>0,'RB' =>0,'TL' =>0,'TR' =>0,'LT' =>0,'LB' =>0);
19134 if ($this->packTableData) {
19135 $this->cell[$k][$l]['borderbin'] = $this->_packCellBorder($this->cell[$k][$l]);
19136 unset($this->cell[$k][$l]['border']);
19137 unset($this->cell[$k][$l]['border_details']);
19138 }
19139 }
19140 }
19141 }
19142 }
19143
19144 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = $this->cell;
19145 $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));
19146 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['hr'] = array_pad(array(),$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr'],0);
19147
19148 // Move table footer <tfoot> row to end of table
19149 if (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot']) && count($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'])) {
19150 $tfrows = array();
19151 foreach($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'] AS $r=>$val) {
19152 if ($val) { $tfrows[] = $r; }
19153 }
19154 $temp = array();
19155 $temptf = array();
19156 foreach($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] AS $k=>$row) {
19157 if (in_array($k,$tfrows)) {
19158 $temptf[] = $row;
19159 }
19160 else {
19161 $temp[] = $row;
19162 }
19163 }
19164 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'] = array();
19165 for($i=count($temp) ; $i<(count($temp)+count($temptf)); $i++) {
19166 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$i] = true;
19167 }
19168 // Update nestedpos row references
19169 if (count($this->table[($this->tableLevel+1)])) {
19170 foreach($this->table[($this->tableLevel+1)] AS $nid=>$nested) {
19171 $this->table[($this->tableLevel+1)][$nid]['nestedpos'][0] -= count($temptf);
19172 }
19173 }
19174 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = array_merge($temp, $temptf);
19175
19176 // Update other arays set on row number
19177 // [trbackground-images] [trgradients]
19178 $temptrbgi = array();
19179 $temptrbgg = array();
19180 $temptrbgc = array();
19181 $temptrbgc[-1] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][-1];
19182 for($k=0; $k<$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']; $k++) {
19183 if (!in_array($k,$tfrows)) {
19184 $temptrbgi[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$k];
19185 $temptrbgg[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$k];
19186 $temptrbgc[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$k];
19187 }
19188 }
19189 for($k=0; $k<$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']; $k++) {
19190 if (in_array($k,$tfrows)) {
19191 $temptrbgi[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$k];
19192 $temptrbgg[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$k];
19193 $temptrbgc[] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$k];
19194 }
19195 }
19196 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'] = $temptrbgi;
19197 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'] = $temptrbgg;
19198 $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'] = $temptrbgc ;
19199 // Should Update all other arays set on row number, but cell properties have been set so not needed
19200 // [bgcolor] [trborder-left] [trborder-right] [trborder-top] [trborder-bottom]
19201 }
19202
19203 if ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['direction']=='rtl') {
19204 $this->_reverseTableDir($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]);
19205 }
19206
19207 // Fix Borders *********************************************
19208 $this->_fixTableBorders($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]);
19209
19210 if ($this->progressBar) { $this->UpdateProgressBar(7,10,' '); } // *PROGRESS-BAR*
19211
19212 if ($this->ColActive) { $this->table_rotate = 0; } // *COLUMNS*
19213 if ($this->table_rotate <> 0) {
19214 $this->tablebuffer = '';
19215 // Max width for rotated table
19216 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 1);
19217 $this->tbrot_maxh = $this->blk[$this->blklvl]['inner_width'] ; // Max width for rotated table
19218 $this->tbrot_align = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['a'] ;
19219 }
19220 $this->shrin_k = 1;
19221
19222 if ($this->shrink_tables_to_fit < 1) { $this->shrink_tables_to_fit = 1; }
19223 if (!$this->shrink_this_table_to_fit) { $this->shrink_this_table_to_fit = $this->shrink_tables_to_fit; }
19224
19225 if ($this->tableLevel>1) {
19226 // deal with nested table
19227
19228 $this->_tableColumnWidth($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]],true);
19229
19230 $tmiw = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['miw'];
19231 $tmaw = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['maw'];
19232 $tl = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['tl'];
19233
19234 // Go down to lower table level
19235 $this->tableLevel--;
19236
19237 // Reset lower level table
19238 $this->base_table_properties = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['baseProperties'];
19239 // mPDF 5.7.3
19240 $this->default_font = $this->base_table_properties['FONT-FAMILY'];
19241 $this->SetFont($this->default_font,'',0,false);
19242 $this->default_font_size = $this->ConvertSize($this->base_table_properties['FONT-SIZE'])*(_MPDFK);
19243 $this->SetFontSize($this->default_font_size,false);
19244
19245 $this->cell = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'];
19246 // mPDF 5.4.10
19247 if (isset($this->cell['PARENTCELL'])) {
19248 if ($this->cell['PARENTCELL']) { $this->restoreInlineProperties($this->cell['PARENTCELL']); }
19249 unset($this->cell['PARENTCELL']);
19250 }
19251 $this->row = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currrow'];
19252 $this->col = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currcol'];
19253 $objattr = array();
19254 $objattr['type'] = 'nestedtable';
19255 $objattr['nestedcontent'] = $this->tbctr[($this->tableLevel+1)];
19256 $objattr['table'] = $this->tbctr[$this->tableLevel];
19257 $objattr['row'] = $this->row;
19258 $objattr['col'] = $this->col;
19259 $objattr['level'] = $this->tableLevel;
19260 $e = "\xbb\xa4\xactype=nestedtable,objattr=".serialize($objattr)."\xbb\xa4\xac";
19261 $this->_saveCellTextBuffer($e);
19262 $this->cell[$this->row][$this->col]['s'] += $tl ;
19263 if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
19264 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
19265 }
19266 elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
19267 $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
19268 }
19269 $this->cell[$this->row][$this->col]['s'] = 0;// reset
19270 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 ; }
19271 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 ; }
19272 $this->tdbegin = true;
19273 $this->nestedtablejustfinished = true;
19274 $this->ignorefollowingspaces = true;
19275 return;
19276 }
19277 $this->cMarginL = 0;
19278 $this->cMarginR = 0;
19279 $this->cMarginT = 0;
19280 $this->cMarginB = 0;
19281 $this->cellPaddingL = 0;
19282 $this->cellPaddingR = 0;
19283 $this->cellPaddingT = 0;
19284 $this->cellPaddingB = 0;
19285
19286 if (isset($this->table[1][1]['overflow']) && $this->table[1][1]['overflow']=='visible') {
19287 if ($this->kwt || $this->table_rotate || $this->table_keep_together || $this->ColActive) {
19288 $this->kwt = false;
19289 $this->table_rotate = 0;
19290 $this->table_keep_together = false;
19291 //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");
19292 }
19293 $this->_tableColumnWidth($this->table[1][1],true);
19294 $this->_tableWidth($this->table[1][1]);
19295 }
19296 else {
19297 if (!$this->kwt_saved) { $this->kwt_height = 0; }
19298
19299 list($check,$tablemiw) = $this->_tableColumnWidth($this->table[1][1],true);
19300 $save_table = $this->table;
19301 if ($this->cacheTables) { $this->_backupCacheFiles(); }
19302 $reset_to_minimum_width = false;
19303 $added_page = false;
19304
19305 if ($check > 1) {
19306 if ($check > $this->shrink_this_table_to_fit && $this->table_rotate) {
19307 if ($this->y != $this->tMargin) {
19308 $this->AddPage($this->CurOrientation);
19309 $this->kwt_moved = true;
19310 }
19311 $added_page = true;
19312 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19313 //$check = $tablemiw/$this->tbrot_maxw; // undo any shrink
19314 $check = 1; // undo any shrink
19315 }
19316 $reset_to_minimum_width = true;
19317 }
19318
19319 if ($reset_to_minimum_width) {
19320
19321 $this->shrin_k = $check;
19322
19323 $this->default_font_size /= $this->shrin_k;
19324 $this->SetFontSize($this->default_font_size, false );
19325
19326 $this->shrinkTable($this->table[1][1],$this->shrin_k);
19327
19328 $this->_tableColumnWidth($this->table[1][1],false); // repeat
19329
19330 // Starting at $this->innermostTableLevel
19331 // Shrink table values - and redo columnWidth
19332 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19333 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19334 $this->shrinkTable($this->table[$lvl][$nid],$this->shrin_k);
19335 $this->_tableColumnWidth($this->table[$lvl][$nid],false);
19336 }
19337 }
19338 }
19339
19340 // Set table cell widths for top level table
19341 // Use $shrin_k to resize but don't change again
19342 $this->SetLineHeight('',$this->table_lineheight);
19343
19344 // Top level table
19345 $this->_tableWidth($this->table[1][1]);
19346
19347 }
19348
19349
19350 // Now work through any nested tables setting child table[w'] = parent cell['w']
19351 // Now do nested tables _tableWidth
19352 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19353 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19354 // HERE set child table width = cell width
19355
19356 list($parentrow, $parentcol, $parentnid) = $this->table[$lvl][$nid]['nestedpos'];
19357
19358 if ($this->cacheTables) {
19359 $c = $this->_uncacheCell($this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol], $this->table[($lvl-1)][$parentnid]['cache'], null);
19360 }
19361 else
19362 $c =& $this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol];
19363
19364 if (isset($c['colspan']) && $c['colspan']> 1) {
19365 $parentwidth = 0;
19366 for($cs=0;$cs<$c['colspan'] ; $cs++) {
19367 $parentwidth += $this->table[($lvl-1)][$parentnid]['wc'][$parentcol+$cs];
19368 }
19369 }
19370 else { $parentwidth = $this->table[($lvl-1)][$parentnid]['wc'][$parentcol]; }
19371
19372
19373 //$parentwidth -= ALLOW FOR PADDING ETC.in parent cell
19374 if (!$this->simpleTables){
19375 if ($this->packTableData) {
19376 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
19377 }
19378 else {
19379 $br = $c['border_details']['R']['w'];
19380 $bl = $c['border_details']['L']['w'];
19381 }
19382 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19383 $parentwidth -= $br + $bl
19384 + $c['padding']['L']
19385 + $c['padding']['R']
19386 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19387 }
19388 else {
19389 $parentwidth -= $br/2 + $bl/2
19390 + $c['padding']['L']
19391 + $c['padding']['R'];
19392 }
19393 }
19394 else if ($this->simpleTables){
19395 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19396 $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19397 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']
19398 + $c['padding']['L']
19399 + $c['padding']['R']
19400 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19401 }
19402 else {
19403 $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']/2
19404 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']/2
19405 + $c['padding']['L']
19406 + $c['padding']['R'];
19407 }
19408 }
19409 if (isset($this->table[$lvl][$nid]['wpercent']) && $this->table[$lvl][$nid]['wpercent'] && $lvl>1) {
19410 $this->table[$lvl][$nid]['w'] = $parentwidth;
19411 }
19412 else if ($parentwidth > $this->table[$lvl][$nid]['maw']) {
19413 $this->table[$lvl][$nid]['w'] = $this->table[$lvl][$nid]['maw'];
19414 }
19415 else {
19416 $this->table[$lvl][$nid]['w'] = $parentwidth;
19417 }
19418 unset($c);
19419 $this->_tableWidth($this->table[$lvl][$nid]);
19420 }
19421 }
19422
19423 // Starting at $this->innermostTableLevel
19424 // Cascade back up nested tables: setting heights back up the tree
19425 for($lvl=$this->innermostTableLevel;$lvl>0;$lvl--) {
19426 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19427 list($tableheight,$maxrowheight,$fullpage,$remainingpage, $maxfirstrowheight) = $this->_tableHeight($this->table[$lvl][$nid]); }
19428 }
19429 if ($this->progressBar) { $this->UpdateProgressBar(7,20,' '); } // *PROGRESS-BAR*
19430 if ($this->table[1][1]['overflow']=='visible') {
19431 if ($maxrowheight > $fullpage) { die("mPDF Warning: A Table row is greater than available height. You cannot use CSS overflow:visible"); }
19432 if ($maxfirstrowheight > $remainingpage) { $this->AddPage($this->CurOrientation); }
19433 $r = 0; $c = 0; $p = 0; $y = 0;
19434 while (!$finished) {
19435 list($finished,$r,$c,$p,$y,$y0) = $this->_tableWrite($this->table[1][1],true,$r,$c,$p,$y);
19436 if (!$finished) {
19437 $this->AddPage($this->CurOrientation);
19438 // If printed something on first spread, set same y
19439 if ($r==0 && $y0 > -1) { $this->y = $y0; }
19440 }
19441 }
19442 }
19443 else {
19444 $recalculate = 1;
19445 $forcerecalc = false;
19446 // RESIZING ALGORITHM
19447 if ($maxrowheight > $fullpage) {
19448 $recalculate = $this->tbsqrt($maxrowheight / $fullpage, 1);
19449 $forcerecalc = true;
19450 }
19451 else if ($this->table_rotate) { // NB $remainingpage == $fullpage == the width of the page
19452 if ($tableheight > $remainingpage) {
19453 // If can fit on remainder of page whilst respecting autsize value..
19454 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, 1)) <= $this->shrink_this_table_to_fit) {
19455 $recalculate = $this->tbsqrt($tableheight / $remainingpage, 1);
19456 }
19457 else if (!$added_page) {
19458 if ($this->y != $this->tMargin) {
19459 $this->AddPage($this->CurOrientation);
19460 $this->kwt_moved = true;
19461 }
19462 $added_page = true;
19463 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19464 // 0.001 to force it to recalculate
19465 $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
19466 }
19467 }
19468 else { $recalculate = 1; }
19469 }
19470 else if ($this->table_keep_together || ($this->table[1][1]['nr']==1 && !$this->writingHTMLfooter)) {
19471 if ($tableheight > $fullpage) {
19472 if (($this->shrin_k * $this->tbsqrt($tableheight / $fullpage, 1)) <= $this->shrink_this_table_to_fit) {
19473 $recalculate = $this->tbsqrt($tableheight / $fullpage, 1);
19474 }
19475 else if ($this->tableMinSizePriority) {
19476 $this->table_keep_together = false;
19477 $recalculate = 1.001;
19478 }
19479 else {
19480 if ($this->y != $this->tMargin) { // mPDF 5.1
19481 $this->AddPage($this->CurOrientation);
19482 $this->kwt_moved = true;
19483 }
19484 $added_page = true;
19485 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19486 $recalculate = $this->tbsqrt($tableheight / $fullpage, 1);
19487 }
19488 }
19489 else if ($tableheight > $remainingpage) {
19490 // If can fit on remainder of page whilst respecting autsize value..
19491 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, 1)) <= $this->shrink_this_table_to_fit) {
19492 $recalculate = $this->tbsqrt($tableheight / $remainingpage, 1);
19493 }
19494 else {
19495 if ($this->y != $this->tMargin) {
19496 $this->AddPage($this->CurOrientation);
19497 $this->kwt_moved = true;
19498 }
19499 $added_page = true;
19500 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19501 $recalculate = 1.001;
19502 }
19503 }
19504 else { $recalculate = 1; }
19505 }
19506 else { $recalculate = 1; }
19507
19508 if ($recalculate > $this->shrink_this_table_to_fit && !$forcerecalc) { $recalculate = $this->shrink_this_table_to_fit; }
19509
19510 $iteration = 1;
19511
19512 // RECALCULATE
19513 while($recalculate <> 1) {
19514 $this->shrin_k1 = $recalculate ;
19515 $this->shrin_k *= $recalculate ;
19516 $this->default_font_size /= ($this->shrin_k1) ;
19517 $this->SetFontSize($this->default_font_size, false );
19518 $this->SetLineHeight('',$this->table_lineheight);
19519 $this->table = $save_table;
19520 if ($this->cacheTables) { $this->_restoreCacheFiles(); }
19521 if ($this->shrin_k <> 1) { $this->shrinkTable($this->table[1][1],$this->shrin_k); }
19522 $this->_tableColumnWidth($this->table[1][1],false); // repeat
19523
19524 // Starting at $this->innermostTableLevel
19525 // Shrink table values - and redo columnWidth
19526 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19527 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19528 if ($this->shrin_k <> 1) { $this->shrinkTable($this->table[$lvl][$nid],$this->shrin_k); }
19529 $this->_tableColumnWidth($this->table[$lvl][$nid],false);
19530 }
19531 }
19532 // Set table cell widths for top level table
19533
19534 // Top level table
19535 $this->_tableWidth($this->table[1][1]);
19536
19537 // Now work through any nested tables setting child table[w'] = parent cell['w']
19538 // Now do nested tables _tableWidth
19539 for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
19540 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19541 // HERE set child table width = cell width
19542
19543 list($parentrow, $parentcol, $parentnid) = $this->table[$lvl][$nid]['nestedpos'];
19544 if ($this->cacheTables) {
19545 $c = $this->_uncacheCell($this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol], $this->table[($lvl-1)][$parentnid]['cache'], null);
19546 }
19547 else
19548 $c =& $this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol];
19549
19550 if (isset($c['colspan']) && $c['colspan']> 1) {
19551 $parentwidth = 0;
19552 for($cs=0;$cs<$c['colspan'] ; $cs++) {
19553 $parentwidth += $this->table[($lvl-1)][$parentnid]['wc'][$parentcol+$cs];
19554 }
19555 }
19556 else { $parentwidth = $this->table[($lvl-1)][$parentnid]['wc'][$parentcol]; }
19557
19558 //$parentwidth -= ALLOW FOR PADDING ETC.in parent cell
19559 if (!$this->simpleTables){
19560 if ($this->packTableData) {
19561 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
19562 }
19563 else {
19564 $br = $c['border_details']['R']['w'];
19565 $bl = $c['border_details']['L']['w'];
19566 }
19567 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19568 $parentwidth -= $br + $bl
19569 + $c['padding']['L']
19570 + $c['padding']['R']
19571 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19572 }
19573 else {
19574 $parentwidth -= $br/2 + $bl/2
19575 + $c['padding']['L']
19576 + $c['padding']['R'];
19577 }
19578 }
19579 else if ($this->simpleTables){
19580 if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
19581 $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19582 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']
19583 + $c['padding']['L']
19584 + $c['padding']['R']
19585 + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
19586 }
19587 else {
19588 $parentwidth -= ($this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
19589 + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']) /2
19590 + $c['padding']['L']
19591 + $c['padding']['R'];
19592 }
19593 }
19594 if (isset($this->table[$lvl][$nid]['wpercent']) && $this->table[$lvl][$nid]['wpercent'] && $lvl>1) {
19595 $this->table[$lvl][$nid]['w'] = $parentwidth;
19596 }
19597 else if ($parentwidth > $this->table[$lvl][$nid]['maw']) {
19598 $this->table[$lvl][$nid]['w'] = $this->table[$lvl][$nid]['maw'] ;
19599 }
19600 else {
19601 $this->table[$lvl][$nid]['w'] = $parentwidth;
19602 }
19603 unset($c);
19604 $this->_tableWidth($this->table[$lvl][$nid]);
19605 }
19606 }
19607
19608 // Starting at $this->innermostTableLevel
19609 // Cascade back up nested tables: setting heights back up the tree
19610 for($lvl=$this->innermostTableLevel;$lvl>0;$lvl--) {
19611 for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
19612 list($tableheight,$maxrowheight,$fullpage,$remainingpage, $maxfirstrowheight) = $this->_tableHeight($this->table[$lvl][$nid]); }
19613 }
19614
19615 // RESIZING ALGORITHM
19616
19617 if ($maxrowheight > $fullpage) { $recalculate = $this->tbsqrt($maxrowheight / $fullpage, $iteration); $iteration++; }
19618 else if ($this->table_rotate && $tableheight > $remainingpage && !$added_page) {
19619 // If can fit on remainder of page whilst respecting autosize value..
19620 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, $iteration)) <= $this->shrink_this_table_to_fit) {
19621 $recalculate = $this->tbsqrt($tableheight / $remainingpage, $iteration); $iteration++;
19622 }
19623 else {
19624 if (!$added_page) {
19625 $this->AddPage($this->CurOrientation);
19626 $added_page = true;
19627 $this->kwt_moved = true;
19628 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19629 }
19630 // 0.001 to force it to recalculate
19631 $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
19632 }
19633 }
19634 else if ($this->table_keep_together || ($this->table[1][1]['nr']==1 && !$this->writingHTMLfooter)) {
19635 if ($tableheight > $fullpage) {
19636 if (($this->shrin_k * $this->tbsqrt($tableheight / $fullpage, $iteration)) <= $this->shrink_this_table_to_fit) {
19637 $recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
19638 }
19639 else if ($this->tableMinSizePriority) {
19640 $this->table_keep_together = false;
19641 $recalculate = (1 / $this->shrin_k) + 0.001;
19642 }
19643 else {
19644 if (!$added_page && $this->y != $this->tMargin) {
19645 $this->AddPage($this->CurOrientation);
19646 $added_page = true;
19647 $this->kwt_moved = true;
19648 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19649 }
19650 $recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
19651 }
19652 }
19653 else if ($tableheight > $remainingpage) {
19654 // If can fit on remainder of page whilst respecting autosize value..
19655 if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, $iteration)) <= $this->shrink_this_table_to_fit) {
19656 $recalculate = $this->tbsqrt($tableheight / $remainingpage, $iteration); $iteration++;
19657 }
19658 else {
19659 if (!$added_page) {
19660 $this->AddPage($this->CurOrientation);
19661 $added_page = true;
19662 $this->kwt_moved = true;
19663 $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
19664 }
19665
19666 //$recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
19667 $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
19668 }
19669 }
19670 else { $recalculate = 1; }
19671 }
19672 else { $recalculate = 1; }
19673 }
19674
19675
19676 if ($maxfirstrowheight > $remainingpage && !$added_page && !$this->table_rotate && !$this->ColActive && !$this->table_keep_together && !$this->writingHTMLheader && !$this->writingHTMLfooter) {
19677 $this->AddPage($this->CurOrientation);
19678 $this->kwt_moved = true;
19679 }
19680
19681 // keep-with-table: if page has advanced, print out buffer now, else done in fn. _Tablewrite()
19682 if ($this->kwt_saved && $this->kwt_moved) {
19683 $this->printkwtbuffer();
19684 $this->kwt_moved = false;
19685 $this->kwt_saved = false;
19686 }
19687
19688 if ($this->progressBar) { $this->UpdateProgressBar(7,30,' '); } // *PROGRESS-BAR*
19689 // Recursively writes all tables starting at top level
19690 $this->_tableWrite($this->table[1][1]);
19691
19692 if ($this->table_rotate && $this->tablebuffer) {
19693 $this->PageBreakTrigger=$this->h-$this->bMargin;
19694 $save_tr = $this->table_rotate;
19695 $save_y = $this->y;
19696 $this->table_rotate = 0;
19697 $this->y = $this->tbrot_y0;
19698 $h = $this->tbrot_w;
19699 $this->DivLn($h,$this->blklvl,true);
19700
19701 $this->table_rotate = $save_tr;
19702 $this->y = $save_y;
19703
19704 $this->printtablebuffer();
19705 }
19706 $this->table_rotate = 0;
19707 }
19708
19709
19710 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
19711
19712 $this->maxPosR = max($this->maxPosR , ($this->x + $this->table[1][1]['w']));
19713
19714 $this->blockjustfinished=true;
19715 $this->lastblockbottommargin = $this->table[1][1]['margin']['B'];
19716 //Reset values
19717
19718 if (isset($this->table[1][1]['page_break_after'])) { $page_break_after = $this->table[1][1]['page_break_after']; }
19719 else { $page_break_after = ''; }
19720
19721 // Keep-with-table
19722 $this->kwt = false;
19723 $this->kwt_y0 = 0;
19724 $this->kwt_x0 = 0;
19725 $this->kwt_height = 0;
19726 $this->kwt_buffer = array();
19727 $this->kwt_Links = array();
19728 $this->kwt_Annots = array();
19729 $this->kwt_moved = false;
19730 $this->kwt_saved = false;
19731
19732 $this->kwt_Reference = array();
19733 $this->kwt_BMoutlines = array();
19734 $this->kwt_toc = array();
19735
19736 $this->shrin_k = 1;
19737 $this->shrink_this_table_to_fit = 0;
19738
19739 unset($this->table);
19740 $this->table=array(); //array
19741 $this->tableLevel=0;
19742 $this->tbctr=array();
19743 $this->innermostTableLevel=0;
19744 $this->cssmgr->tbCSSlvl = 0;
19745 $this->cssmgr->tablecascadeCSS = array();
19746
19747 unset($this->cell);
19748 $this->cell=array(); //array
19749
19750 $this->col=-1; //int
19751 $this->row=-1; //int
19752 $this->Reset();
19753
19754 $this->cellPaddingL = 0;
19755 $this->cellPaddingT = 0;
19756 $this->cellPaddingR = 0;
19757 $this->cellPaddingB = 0;
19758 $this->cMarginL = 0;
19759 $this->cMarginT = 0;
19760 $this->cMarginR = 0;
19761 $this->cMarginB = 0;
19762 $this->default_font_size = $this->original_default_font_size;
19763 $this->default_font = $this->original_default_font;
19764 $this->SetFontSize($this->default_font_size, false);
19765 $this->SetFont($this->default_font,'',0,false);
19766 $this->SetLineHeight();
19767 if (isset($this->blk[$this->blklvl]['InlineProperties'])) { $this->restoreInlineProperties($this->blk[$this->blklvl]['InlineProperties']);}
19768 if ($this->progressBar) { $this->UpdateProgressBar(7,100,' '); } // *PROGRESS-BAR*
19769
19770 if ($page_break_after) {
19771 $save_blklvl = $this->blklvl;
19772 $save_blk = $this->blk;
19773 $save_silp = $this->saveInlineProperties();
19774 $save_ilp = $this->InlineProperties;
19775 if ($this->blklvl>1) {
19776 // Close any open block tags
19777 for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag']); }
19778 // Output any text left in buffer
19779 if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); $this->textbuffer=array(); }
19780 }
19781 /*-- COLUMNS --*/
19782 $save_cols = false;
19783 if ($this->ColActive) {
19784 $save_cols = true;
19785 $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
19786 $this->SetColumns(0);
19787 }
19788 /*-- END COLUMNS --*/
19789 if ($page_break_after == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
19790 else if ($page_break_after == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
19791 else { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
19792 if (!$this->restoreBlockPagebreaks) {
19793 $this->blklvl = 0;
19794 $this->lastblocklevelchange = 0;
19795 $this->blk = array();
19796 $this->initialiseBlock($this->blk[0]);
19797 $this->blk[0]['width'] =& $this->pgwidth;
19798 $this->blk[0]['inner_width'] =& $this->pgwidth;
19799 $this->blk[0]['blockContext'] = $this->blockContext;
19800 $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
19801 $this->setCSS($properties,'','BODY');
19802 }
19803
19804 /*-- COLUMNS --*/
19805 if ($save_cols) {
19806 // Restore columns
19807 $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
19808 }
19809 /*-- END COLUMNS --*/
19810 if ($this->restoreBlockPagebreaks) {
19811 $this->blk = $save_blk;
19812 // Re-open block tags
19813 $t = $this->blk[0]['tag'];
19814 $a = $this->blk[0]['attr'];
19815 $this->blklvl = 0;
19816 for ($b=0; $b<=$save_blklvl;$b++) {
19817 $tc = $t;
19818 $ac = $a;
19819 $t = $this->blk[$b+1]['tag'];
19820 $a = $this->blk[$b+1]['attr'];
19821 unset($this->blk[$b+1]);
19822 $this->OpenTag($tc,$ac);
19823 }
19824 $this->InlineProperties = $save_ilp;
19825 $this->restoreInlineProperties($save_silp);
19826 }
19827 }
19828
19829 }
19830 /*-- END TABLES --*/
19831
19832 /*-- LISTS --*/
19833 // *********** LISTS ********************
19834
19835 if($tag=='LI') {
19836 $this->lastoptionaltag = '';
19837 unset($this->cssmgr->listcascadeCSS[$this->cssmgr->listCSSlvl]);
19838 $this->cssmgr->listCSSlvl--;
19839 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]]); }
19840 }
19841
19842
19843 if(($tag=='UL') or ($tag=='OL')) {
19844 $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
19845 unset($this->cssmgr->listcascadeCSS[$this->cssmgr->listCSSlvl]);
19846 $this->cssmgr->listCSSlvl--;
19847
19848 $this->lastoptionaltag = '';
19849 /*-- TABLES --*/
19850 // A simple list for inside a table
19851 if($this->tableLevel) {
19852 $this->listlist[$this->listlvl]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
19853 unset($this->listlist[$this->listlvl]);
19854 $this->listlvl--;
19855 if (isset($this->listlist[$this->listlvl]['MAXNUM'])) { $this->listnum = $this->listlist[$this->listlvl]['MAXNUM']; } // restore previous levels
19856 if ($this->listlvl == 0) { $this->listjustfinished = true; }
19857 return;
19858 }
19859 /*-- END TABLES --*/
19860
19861 if ($this->listlvl > 1) { // returning one level
19862 $this->listjustfinished=true;
19863 if (!empty($this->textbuffer)) {
19864 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
19865 }
19866 else {
19867 $this->listnum--;
19868 }
19869
19870 $this->textbuffer = array();
19871 $occur = $this->listoccur[$this->listlvl];
19872 $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
19873 $this->listlvl--;
19874 $occur = $this->listoccur[$this->listlvl];
19875 $this->listnum = $this->listlist[$this->listlvl][$occur]['MAXNUM']; // recover previous level's number
19876 $this->listtype = $this->listlist[$this->listlvl][$occur]['TYPE']; // recover previous level's type
19877 if ($this->InlineProperties['LIST'][$this->listlvl][$occur]) { $this->restoreInlineProperties($this->InlineProperties['LIST'][$this->listlvl][$occur]); }
19878
19879 }
19880 else { // We are closing the last OL/UL tag
19881 if (!empty($this->textbuffer)) {
19882 $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl],$this->listitemtype);
19883 }
19884 else {
19885 $this->listnum--;
19886 }
19887
19888 $occur = $this->listoccur[$this->listlvl];
19889 $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum;
19890 $this->textbuffer = array();
19891 $this->listlvl--;
19892
19893 $this->printlistbuffer();
19894 unset($this->InlineProperties['LIST']);
19895 // SPACING AFTER LIST (Top level only)
19896 $this->Ln(0);
19897 if ($this->list_margin_bottom) {
19898 $this->DivLn($this->list_margin_bottom,$this->blklvl,true,1); // collapsible
19899 }
19900 if (isset($this->blk[$this->blklvl]['InlineProperties'])) { $this->restoreInlineProperties($this->blk[$this->blklvl]['InlineProperties']);}
19901 $this->listjustfinished = true;
19902 $this->cssmgr->listCSSlvl = 0;
19903 $this->cssmgr->listcascadeCSS = array();
19904 $this->blockjustfinished=true;
19905 $this->lastblockbottommargin = $this->list_margin_bottom;
19906 }
19907 }
19908 /*-- END LISTS --*/
19909
19910
19911 }
19912
19913
19914 /*-- TABLES --*/
19915 // This function determines the shrink factor when resizing tables
19916 // val is the table_height / page_height_available
19917 // returns a scaling factor used as $shrin_k to resize the table
19918 // Overcompensating will be quicker but may unnecessarily shrink table too much
19919 // Undercompensating means it will reiterate more times (taking more processing time)
19920 function tbsqrt($val, $iteration=3) {
19921 $k = 4; // Alters number of iterations until it returns $val itself - Must be > 2
19922 // Probably best guess and most accurate
19923 if ($iteration==1) return sqrt($val);
19924 // Faster than using sqrt (because it won't undercompensate), and gives reasonable results
19925 //return 1+(($val-1)/2);
19926 $x = 2-(($iteration-2)/($k-2));
19927 if ($x == 0) { $ret = $val+0.00001; }
19928 else if ($x < 0) { $ret = 1 + ( pow(2, ($iteration-2-$k))/1000 ); }
19929 else { $ret = 1+(($val-1)/$x); }
19930 return $ret;
19931 }
19932 /*-- END TABLES --*/
19933
19934
19935 /*-- LISTS --*/
19936 function printlistbuffer() {
19937 //Save x coordinate
19938 $x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
19939 $this->cMarginL = 0;
19940 $this->cMarginR = 0;
19941 $currIndentLvl = -1;
19942 $lastIndent = array();
19943 $bak_page = $this->page;
19944 $indent = 0;
19945 foreach($this->listitem as $item)
19946 {
19947 // COLS
19948 $oldcolumn = $this->CurrCol;
19949
19950 $this->bulletarray = array();
19951 //Get list's buffered data
19952 $this->listlvl = $lvl = $item[0];
19953 $num = $item[1];
19954 $this->textbuffer = $item[2];
19955 $occur = $item[3];
19956 if ($item[4]) { $type = $item[4]; } // listitemtype
19957 else { $type = $this->listlist[$lvl][$occur]['TYPE']; }
19958 $maxnum = $this->listlist[$lvl][$occur]['MAXNUM'];
19959 $this->restoreInlineProperties($this->InlineProperties['LIST'][$lvl][$occur]);
19960 $this->SetFont($this->FontFamily,$this->FontStyle,$this->FontSizePt,true,true); // force to write
19961 $clh = $this->FontSize;
19962
19963 $this->SetLineHeight($this->FontSizePt,$this->list_lineheight[$lvl][$occur]);
19964 $this->listOcc = $occur;
19965 $this->listnum = $num;
19966
19967 if (isset($this->list_align[$this->listlvl][$occur])) { $this->divalign = $this->list_align[$this->listlvl][$occur]; }
19968 else {
19969 if (isset($this->blk[$this->blklvl]['direction']) && $this->blk[$this->blklvl]['direction']=='rtl') { $this->divalign = 'R'; }
19970 else { $this->divalign = 'L'; }
19971 }
19972
19973 // Set the bullet fontsize
19974 $bullfs = $this->InlineProperties['LISTITEM'][$lvl][$occur][$num]['size'];
19975
19976 $space_width = $this->GetCharWidth(' ',false) * 1.5;
19977
19978 //Set default width & height values
19979 $this->divwidth = $this->blk[$this->blklvl]['inner_width'];
19980 $this->divheight = $this->lineheight;
19981 $typefont = $this->FontFamily;
19982 if (preg_match('/U\+([a-fA-F0-9]+)/i',$type,$m)) {
19983 if ($this->_charDefined($this->CurrentFont['cw'],hexdec($m[1]))) { $list_item_marker = codeHex2utf($m[1]); }
19984 else { $list_item_marker = '-'; }
19985 $blt_width = $this->GetStringWidth($list_item_marker);
19986 $typefont = '';
19987 if (preg_match('/rgb\(.*?\)/',$type,$m)) {
19988 $list_item_color = $this->ConvertColor($m[0]);
19989 }
19990 }
19991 else {
19992 $list_item_color = false;
19993
19994 switch($type) //Format type
19995 {
19996 case '1':
19997 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $num; }
19998 else { $list_item_marker = $num . $this->list_number_suffix; }
19999 $blt_width = $this->GetStringWidth(str_repeat('5',strlen($maxnum)).$this->list_number_suffix);
20000 break;
20001 case 'none':
20002 $list_item_marker = '';
20003 $blt_width = 0;
20004 break;
20005 case 'A':
20006 $anum = $this->dec2alpha($num,true);
20007 $maxnum = $this->dec2alpha($maxnum,true);
20008 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
20009 else { $list_item_marker = $anum . $this->list_number_suffix; }
20010 $blt_width = $this->GetStringWidth(str_repeat('W',strlen($maxnum)).$this->list_number_suffix);
20011 break;
20012 case 'a':
20013 $anum = $this->dec2alpha($num,false);
20014 $maxnum = $this->dec2alpha($maxnum,false);
20015 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
20016 else { $list_item_marker = $anum . $this->list_number_suffix; }
20017 $blt_width = $this->GetStringWidth(str_repeat('m',strlen($maxnum)).$this->list_number_suffix);
20018 break;
20019 case 'I':
20020 $anum = $this->dec2roman($num,true);
20021 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
20022 else { $list_item_marker = $anum . $this->list_number_suffix; }
20023
20024 if ($maxnum>87) { $bbit = 87; }
20025 else if ($maxnum>86) { $bbit = 86; }
20026 else if ($maxnum>37) { $bbit = 38; }
20027 else if ($maxnum>36) { $bbit = 37; }
20028 else if ($maxnum>27) { $bbit = 28; }
20029 else if ($maxnum>26) { $bbit = 27; }
20030 else if ($maxnum>17) { $bbit = 18; }
20031 else if ($maxnum>16) { $bbit = 17; }
20032 else if ($maxnum>7) { $bbit = 8; }
20033 else if ($maxnum>6) { $bbit = 7; }
20034 else if ($maxnum>3) { $bbit = 4; }
20035 else { $bbit = $maxnum; }
20036 $maxlnum = $this->dec2roman($bbit,true);
20037 $blt_width = $this->GetStringWidth($maxlnum.$this->list_number_suffix);
20038 break;
20039 case 'i':
20040 $anum = $this->dec2roman($num,false);
20041 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $anum; }
20042 else { $list_item_marker = $anum . $this->list_number_suffix; }
20043
20044 if ($maxnum>87) { $bbit = 87; }
20045 else if ($maxnum>86) { $bbit = 86; }
20046 else if ($maxnum>37) { $bbit = 38; }
20047 else if ($maxnum>36) { $bbit = 37; }
20048 else if ($maxnum>27) { $bbit = 28; }
20049 else if ($maxnum>26) { $bbit = 27; }
20050 else if ($maxnum>17) { $bbit = 18; }
20051 else if ($maxnum>16) { $bbit = 17; }
20052 else if ($maxnum>7) { $bbit = 8; }
20053 else if ($maxnum>6) { $bbit = 7; }
20054 else if ($maxnum>3) { $bbit = 4; }
20055 else { $bbit = $maxnum; }
20056 $maxlnum = $this->dec2roman($bbit,false);
20057
20058 $blt_width = $this->GetStringWidth($maxlnum.$this->list_number_suffix);
20059 break;
20060 case 'disc':
20061 if ($this->PDFA || $this->PDFX) {
20062 if ($this->_charDefined($this->CurrentFont['cw'],8226)) { $list_item_marker = "\xe2\x80\xa2"; } // &#8226;
20063 else { $list_item_marker = '-'; }
20064 $blt_width = $this->GetCharWidth($list_item_marker);
20065 break;
20066 }
20067 $list_item_marker = chr(108); // bullet disc in Zapfdingbats 'l'
20068 $typefont = 'czapfdingbats';
20069 $blt_width = (0.791 * $this->FontSize/2.5);
20070 break;
20071 case 'circle':
20072 if ($this->PDFA || $this->PDFX) {
20073 if ($this->_charDefined($this->CurrentFont['cw'],9900)) { $list_item_marker = "\xe2\x9a\xac"; } // &#9900;
20074 else { $list_item_marker = '-'; }
20075 $blt_width = $this->GetCharWidth($list_item_marker);
20076 break;
20077 }
20078 $list_item_marker = chr(109); // circle in Zapfdingbats 'm'
20079 $typefont = 'czapfdingbats';
20080 $blt_width = (0.873 * $this->FontSize/2.5);
20081 break;
20082 case 'square':
20083 if ($this->PDFA || $this->PDFX) {
20084 if ($this->_charDefined($this->CurrentFont['cw'],9642)) { $list_item_marker = "\xe2\x96\xaa"; } // &#9642;
20085 else { $list_item_marker = '-'; }
20086 $blt_width = $this->GetCharWidth($list_item_marker);
20087 break;
20088 }
20089 $list_item_marker = chr(110); //black square in Zapfdingbats font 'n'
20090 $typefont = 'czapfdingbats';
20091 $blt_width = (0.761 * $this->FontSize/2.5);
20092 break;
20093
20094 /* CSS3 list-styles numeric + I added tamil
20095 arabic-indic | bengali | cambodian | devanagari | gujarati | gurmukhi | kannada | khmer | lao | malayalam | mongolian | myanmar | oriya | persian | telugu | tibetan | thai | urdu
20096 */
20097 case 'arabic-indic':
20098 $cp = 0x0660;
20099 $rnum = $this->dec2other($num, $cp);
20100 $list_item_marker = $this->list_number_suffix . $rnum; // RTL
20101 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20102 break;
20103 case 'persian':
20104 case 'urdu':
20105 $cp = 0x06F0;
20106 $rnum = $this->dec2other($num, $cp);
20107 $list_item_marker = $this->list_number_suffix . $rnum; // RTL
20108 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20109 break;
20110 case 'bengali':
20111 $cp = 0x09E6;
20112 $rnum = $this->dec2other($num, $cp);
20113 $list_item_marker = $rnum . $this->list_number_suffix;
20114 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20115 break;
20116 case 'devanagari':
20117 $cp = 0x0966;
20118 $rnum = $this->dec2other($num, $cp);
20119 $list_item_marker = $rnum . $this->list_number_suffix;
20120 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20121 break;
20122 case 'gujarati':
20123 $cp = 0x0AE6;
20124 $rnum = $this->dec2other($num, $cp);
20125 $list_item_marker = $rnum . $this->list_number_suffix;
20126 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20127 break;
20128 case 'gurmukhi':
20129 $cp = 0x0A66;
20130 $rnum = $this->dec2other($num, $cp);
20131 $list_item_marker = $rnum . $this->list_number_suffix;
20132 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20133 break;
20134 case 'kannada':
20135 $cp = 0x0CE6;
20136 $rnum = $this->dec2other($num, $cp);
20137 $list_item_marker = $rnum . $this->list_number_suffix;
20138 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20139 break;
20140 case 'malayalam':
20141 $cp = 0x0D66;
20142 $rnum = $this->dec2other($num, $cp);
20143 $list_item_marker = $rnum . $this->list_number_suffix;
20144 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(6, $cp),strlen($maxnum)).$this->list_number_suffix);
20145 break;
20146 case 'oriya':
20147 $cp = 0x0B66;
20148 $rnum = $this->dec2other($num, $cp);
20149 $list_item_marker = $rnum . $this->list_number_suffix;
20150 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20151 break;
20152 case 'telugu':
20153 $cp = 0x0C66;
20154 $rnum = $this->dec2other($num, $cp);
20155 $list_item_marker = $rnum . $this->list_number_suffix;
20156 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20157 break;
20158 case 'tamil':
20159 $cp = 0x0BE6;
20160 $rnum = $this->dec2other($num, $cp);
20161 $list_item_marker = $rnum . $this->list_number_suffix;
20162 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(9, $cp),strlen($maxnum)).$this->list_number_suffix);
20163 break;
20164 case 'thai':
20165 $cp = 0x0E50;
20166 $rnum = $this->dec2other($num, $cp);
20167 $list_item_marker = $rnum . $this->list_number_suffix;
20168 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(5, $cp),strlen($maxnum)).$this->list_number_suffix);
20169 break;
20170 case 'khmer':
20171 case 'cambodian':
20172 $cp = 0x17E0;
20173 $rnum = $this->dec2other($num, $cp);
20174 $list_item_marker = $rnum . $this->list_number_suffix;
20175 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, $cp),strlen($maxnum)).$this->list_number_suffix);
20176 break;
20177 case 'lao':
20178 $cp = 0x0ED0;
20179 $rnum = $this->dec2other($num, $cp);
20180 $list_item_marker = $rnum . $this->list_number_suffix;
20181 $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(6, $cp),strlen($maxnum)).$this->list_number_suffix);
20182 break;
20183 default:
20184 if ($this->listDir == 'rtl') { $list_item_marker = $this->list_number_suffix . $num; }
20185 else { $list_item_marker = $num . $this->list_number_suffix; }
20186 $blt_width = $this->GetStringWidth(str_repeat('5',strlen($maxnum)).$this->list_number_suffix);
20187 break;
20188 }
20189 }
20190
20191 if (isset($item[5]) && $item[5]) { $list_item_marker = ''; }
20192
20193 if ($currIndentLvl < $lvl) {
20194 if ($lvl > 1 || $this->list_indent_first_level) {
20195 $indent += $this->list_indent[$lvl][$occur];
20196 $lastIndent[$lvl] = $this->list_indent[$lvl][$occur];
20197 }
20198 }
20199 else if ($currIndentLvl > $lvl) {
20200 while ($currIndentLvl > $lvl) {
20201 $indent -= $lastIndent[$currIndentLvl];
20202 $currIndentLvl--;
20203 }
20204 }
20205 $currIndentLvl = $lvl;
20206
20207
20208 /*-- RTL --*/
20209
20210 if ($this->listDir == 'rtl') {
20211 // list_align_style Determines alignment of numbers in numbered lists
20212 if ($this->list_align_style == 'L') { $lalign = 'R'; }
20213 else { $lalign = 'L'; }
20214 $this->divwidth = $this->blk[$this->blklvl]['width'] - ($indent + $blt_width + $space_width) ;
20215 $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)
20216 //Output bullet
20217 $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 );
20218 $this->x = $x;
20219 }
20220 else {
20221 /*-- END RTL --*/
20222
20223 if ($this->list_align_style == 'L') { $lalign = 'L'; }
20224 else { $lalign = 'R'; }
20225 $this->divwidth = $this->blk[$this->blklvl]['width'] - ($indent + $blt_width + $space_width) ;
20226 $xb = $this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'] - $blt_width - $space_width;
20227 //Output bullet
20228 $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 );
20229 $this->x = $x + $indent + $blt_width + $space_width;
20230 } // *RTL*
20231
20232 //Print content
20233 $this->printbuffer($this->textbuffer,'',false,true);
20234 $this->textbuffer=array();
20235
20236 // Added to correct for OddEven Margins
20237 if ($this->page != $bak_page) {
20238 if (($this->page-$bak_page) % 2 == 1) {
20239 $x += $this->MarginCorrection;
20240 }
20241 $bak_page = $this->page;
20242 }
20243 /*-- COLUMNS --*/
20244 // OR COLUMN CHANGE
20245 if ($this->CurrCol != $oldcolumn) {
20246 if ($this->directionality == 'rtl') { // *RTL*
20247 $x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20248 } // *RTL*
20249 else { // *RTL*
20250 $x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20251 } // *RTL*
20252 $oldcolumn = $this->CurrCol;
20253 }
20254 /*-- END COLUMNS --*/
20255
20256 }
20257
20258 //Reset all used values
20259 $this->listoccur = array();
20260 $this->listitem = array();
20261 $this->listlist = array();
20262 $this->listlvl = 0;
20263 $this->listnum = 0;
20264 $this->listtype = '';
20265 $this->textbuffer = array();
20266 $this->divwidth = 0;
20267 $this->divheight = 0;
20268 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
20269 }
20270 /*-- END LISTS --*/
20271
20272 function _saveTextBuffer($t, $link = '', $intlink = '') {
20273 // $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);
20274 // mPDF 5.6.14
20275 $arr = array();
20276 $arr[0] = $t;
20277 if (isset($link) && $link) $arr[1] = $link;
20278 $arr[2] = $this->currentfontstyle;
20279 if (isset($this->colorarray) && $this->colorarray) $arr[3] = $this->colorarray;
20280 $arr[4] = $this->currentfontfamily;
20281 if (isset($this->SUP) && $this->SUP) $arr[5] = $this->SUP;
20282 if (isset($this->SUB) && $this->SUB) $arr[6] = $this->SUB;
20283 if (isset($intlink) && $intlink) $arr[7] = $intlink;
20284 if (isset($this->strike) && $this->strike) $arr[8] = $this->strike;
20285 if (isset($this->textparam) && $this->textparam) $arr[9] = $this->textparam;
20286 if (isset($this->spanbgcolorarray) && $this->spanbgcolorarray) $arr[10] = $this->spanbgcolorarray;
20287 $arr[11] = $this->currentfontsize;
20288 if (isset($this->ReqFontStyle) && $this->ReqFontStyle) $arr[12] = $this->ReqFontStyle;
20289 if (isset($this->kerning) && $this->kerning) $arr[13] = $this->kerning;
20290 if (isset($this->lSpacingCSS) && $this->lSpacingCSS) $arr[14] = $this->lSpacingCSS;
20291 if (isset($this->wSpacingCSS) && $this->wSpacingCSS) $arr[15] = $this->wSpacingCSS;
20292 if (isset($this->spanborddet) && $this->spanborddet) $arr[16] = $this->spanborddet;
20293 if (isset($this->textshadow) && $this->textshadow) $arr[17] = $this->textshadow;
20294 $this->textbuffer[] = $arr;
20295 }
20296
20297 function _saveCellTextBuffer($t, $link = '', $intlink = '') {
20298 // $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);
20299 // mPDF 5.6.14
20300 $arr = array();
20301 $arr[0] = $t;
20302 if (isset($link) && $link) $arr[1] = $link;
20303 $arr[2] = $this->currentfontstyle;
20304 if (isset($this->colorarray) && $this->colorarray) $arr[3] = $this->colorarray;
20305 $arr[4] = $this->currentfontfamily;
20306 if (isset($this->SUP) && $this->SUP) $arr[5] = $this->SUP;
20307 if (isset($this->SUB) && $this->SUB) $arr[6] = $this->SUB;
20308 if (isset($intlink) && $intlink) $arr[7] = $intlink;
20309 if (isset($this->strike) && $this->strike) $arr[8] = $this->strike;
20310 if (isset($this->textparam) && $this->textparam) $arr[9] = $this->textparam;
20311 if (isset($this->spanbgcolorarray) && $this->spanbgcolorarray) $arr[10] = $this->spanbgcolorarray;
20312 $arr[11] = $this->currentfontsize;
20313 if (isset($this->ReqFontStyle) && $this->ReqFontStyle) $arr[12] = $this->ReqFontStyle;
20314 if (isset($this->kerning) && $this->kerning) $arr[13] = $this->kerning;
20315 if (isset($this->lSpacingCSS) && $this->lSpacingCSS) $arr[14] = $this->lSpacingCSS;
20316 if (isset($this->wSpacingCSS) && $this->wSpacingCSS) $arr[15] = $this->wSpacingCSS;
20317 if (isset($this->spanborddet) && $this->spanborddet) $arr[16] = $this->spanborddet;
20318 if (isset($this->textshadow) && $this->textshadow) $arr[17] = $this->textshadow;
20319 $this->cell[$this->row][$this->col]['textbuffer'][] = $arr;
20320 }
20321
20322
20323 function printbuffer($arrayaux,$blockstate=0,$is_table=false,$is_list=false)
20324 {
20325 // $blockstate = 0; // NO margins/padding
20326 // $blockstate = 1; // Top margins/padding only
20327 // $blockstate = 2; // Bottom margins/padding only
20328 // $blockstate = 3; // Top & bottom margins/padding
20329 $this->spanbgcolorarray = '';
20330 $this->spanbgcolor = false;
20331 $this->spanborder = false;
20332 $this->spanborddet = array();
20333 $paint_ht_corr = 0;
20334
20335 /*-- CSS-FLOAT --*/
20336 if (count($this->floatDivs)) {
20337 list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
20338 if (($this->blk[$this->blklvl]['inner_width']-$l_width-$r_width) < (2*$this->GetCharWidth('W',false))) {
20339 // Too narrow to fit - try to move down past L or R float
20340 if ($l_max < $r_max && ($this->blk[$this->blklvl]['inner_width']-$r_width) > (2*$this->GetCharWidth('W',false))) {
20341 $this->ClearFloats('LEFT', $this->blklvl);
20342 }
20343 else if ($r_max < $l_max && ($this->blk[$this->blklvl]['inner_width']-$l_width) > (2*$this->GetCharWidth('W',false))) {
20344 $this->ClearFloats('RIGHT', $this->blklvl);
20345 }
20346 else { $this->ClearFloats('BOTH', $this->blklvl); }
20347 }
20348 }
20349 /*-- END CSS-FLOAT --*/
20350 $bak_y = $this->y;
20351 $bak_x = $this->x;
20352 $align = '';
20353 if (!$is_table && !$is_list) {
20354 if (isset($this->blk[$this->blklvl]['align']) && $this->blk[$this->blklvl]['align']) { $align = $this->blk[$this->blklvl]['align']; }
20355 // Block-align is set by e.g. <.. align="center"> Takes priority for this block but not inherited
20356 if (isset($this->blk[$this->blklvl]['block-align']) && $this->blk[$this->blklvl]['block-align']) { $align = $this->blk[$this->blklvl]['block-align']; }
20357 if (isset($this->blk[$this->blklvl]['direction'])) $blockdir = $this->blk[$this->blklvl]['direction'];
20358 else $blockdir = "";
20359 $this->divwidth = $this->blk[$this->blklvl]['width'];
20360 }
20361 else {
20362 $align = $this->divalign;
20363 if ($is_table) { $blockdir = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['direction']; }
20364 else { $blockdir = $this->listDir; }
20365 }
20366 $oldpage = $this->page;
20367
20368 // ADDED for Out of Block now done as Flowing Block
20369 if ($this->divwidth == 0) {
20370 $this->divwidth = $this->pgwidth;
20371 }
20372
20373 if (!$is_table && !$is_list) { $this->SetLineHeight($this->FontSizePt,$this->blk[$this->blklvl]['line_height']); }
20374 $this->divheight = $this->lineheight;
20375 $old_height = $this->divheight;
20376
20377 // As a failsafe - if font has been set but not output to page
20378 $this->SetFont($this->default_font,'',$this->default_font_size,true,true); // force output to page
20379
20380 $array_size = count($arrayaux);
20381 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,true,$blockdir);
20382
20383 // Added - Otherwise <div><div><p> did not output top margins/padding for 1st/2nd div
20384 if ($array_size == 0) { $this->finishFlowingBlock(true); } // true = END of flowing block
20385
20386 for($i=0;$i < $array_size; $i++)
20387 {
20388 // COLS
20389 $oldcolumn = $this->CurrCol;
20390
20391 $vetor = $arrayaux[$i];
20392 if ($i == 0 and $vetor[0] != "\n" and !$this->ispre) {
20393 $vetor[0] = ltrim($vetor[0]);
20394 }
20395
20396 // FIXED TO ALLOW IT TO SHOW '0'
20397 if (empty($vetor[0]) && !($vetor[0]==='0') && empty($vetor[7])) { //Ignore empty text and not carrying an internal link
20398 //Check if it is the last element. If so then finish printing the block
20399 if ($i == ($array_size-1)) { $this->finishFlowingBlock(true); } // true = END of flowing block
20400 continue;
20401 }
20402
20403
20404 //Activating buffer properties
20405 if(isset($vetor[11]) and $vetor[11] != '') { // Font Size
20406 if ($is_table && $this->shrin_k) {
20407 $this->SetFontSize($vetor[11]/$this->shrin_k,false);
20408 }
20409 else {
20410 $this->SetFontSize($vetor[11],false);
20411 }
20412 }
20413
20414 if(isset($vetor[17]) && !empty($vetor[17])) { //TextShadow
20415 $this->textshadow = $vetor[17];
20416 }
20417 if(isset($vetor[16]) && !empty($vetor[16])) { //Border
20418 $this->spanborddet = $vetor[16];
20419 $this->spanborder = true;
20420 }
20421
20422 if(isset($vetor[15])) { // Word spacing
20423 $this->wSpacingCSS = $vetor[15];
20424 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
20425 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize)/$this->shrin_k; // mPDF 5.7.3
20426 }
20427 }
20428 if(isset($vetor[14])) { // Letter spacing
20429 $this->lSpacingCSS = $vetor[14];
20430 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
20431 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize)/$this->shrin_k; // mPDF 5.7.3
20432 }
20433 }
20434 if(isset($vetor[13])) { // Font Kerning
20435 $this->kerning = $vetor[13];
20436 }
20437
20438
20439 if(isset($vetor[10]) and !empty($vetor[10])) //Background color
20440 {
20441 $this->spanbgcolorarray = $vetor[10];
20442 $this->spanbgcolor = true;
20443 }
20444 if(isset($vetor[9]) and !empty($vetor[9])) // Text parameters - Outline + hyphens
20445 {
20446 $this->textparam = $vetor[9] ; // mPDF 5.6.14
20447 $this->SetTextOutline($this->textparam); // mPDF 5.6.07
20448 // mPDF 5.7.3 inline text-decoration parameters
20449 if ($is_table && $this->shrin_k) {
20450 if (isset($this->textparam['text-baseline'])) { $this->textparam['text-baseline'] /= $this->shrin_k; }
20451 if (isset($this->textparam['decoration-baseline'])) { $this->textparam['decoration-baseline'] /= $this->shrin_k; }
20452 if (isset($this->textparam['decoration-fontsize'])) { $this->textparam['decoration-fontsize'] /= $this->shrin_k; }
20453 }
20454 }
20455 if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text
20456 {
20457 $this->strike = true;
20458 }
20459 if(isset($vetor[7]) and $vetor[7] != '') // internal target: <a name="anyvalue">
20460 {
20461 $ily = $this->y;
20462 if ($this->keep_block_together) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "kt"=>true ); }
20463 else if ($this->table_rotate) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "tbrot"=>true ); }
20464 else if ($this->kwt) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "kwt"=>true ); }
20465 else if ($this->ColActive) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "col"=>$this->CurrCol ); }
20466 else
20467 $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page );
20468 if (empty($vetor[0])) { //Ignore empty text
20469 //Check if it is the last element. If so then finish printing the block
20470 if ($i == ($array_size-1)) { $this->finishFlowingBlock(true); } // true = END of flowing block
20471 continue;
20472 }
20473 }
20474 if(isset($vetor[6]) and $vetor[6] === true) // Subscript
20475 {
20476 $this->SUB = true;
20477 }
20478 if(isset($vetor[5]) and $vetor[5] === true) // Superscript
20479 {
20480 $this->SUP = true;
20481 }
20482 if(isset($vetor[4]) and $vetor[4] != '') { // Font Family
20483 $font = $this->SetFont($vetor[4],$this->FontStyle,0,false);
20484 }
20485 if (!empty($vetor[3])) //Font Color
20486 {
20487 $cor = $vetor[3];
20488 $this->SetTColor($cor);
20489 }
20490 if(isset($vetor[2]) and $vetor[2] != '') //Bold,Italic,Underline styles
20491 {
20492 $this->SetStyles($vetor[2]);
20493 }
20494
20495 if(isset($vetor[12]) and $vetor[12] != '') { //Requested Bold,Italic,Underline
20496 $this->ReqFontStyle = $vetor[12];
20497 }
20498 if(isset($vetor[1]) and $vetor[1] != '') //LINK
20499 {
20500 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.)
20501 {
20502 //Repeated reference to same anchor?
20503 while(array_key_exists($vetor[1],$this->internallink)) $vetor[1]="#".$vetor[1];
20504 $this->internallink[$vetor[1]] = $this->AddLink();
20505 $vetor[1] = $this->internallink[$vetor[1]];
20506 }
20507 $this->HREF = $vetor[1]; // HREF link style set here ******
20508 }
20509
20510 // SPECIAL CONTENT - IMAGES & FORM OBJECTS
20511 //Print-out special content
20512
20513 if (substr($vetor[0],0,3) == "\xbb\xa4\xac") { //identifier has been identified!
20514
20515 $objattr = $this->_getObjAttr($vetor[0]);
20516
20517 /*-- TABLES --*/
20518 if ($objattr['type'] == 'nestedtable') {
20519 if ($objattr['nestedcontent']) {
20520 $level = $objattr['level'];
20521 $table = &$this->table[$level][$objattr['table']];
20522 if ($this->cacheTables) {
20523 $fh = fopen($table['cache'], "r+b");
20524 $cell = $this->_uncacheCell($table['cells'][$objattr['row']][$objattr['col']], '', $fh);
20525 }
20526 else {
20527 $fh = null;
20528 $cell = &$table['cells'][$objattr['row']][$objattr['col']];
20529 }
20530 $this->finishFlowingBlock(false,'nestedtable');
20531 $save_dw = $this->divwidth ;
20532 $save_buffer = $this->cellBorderBuffer;
20533 $this->cellBorderBuffer = array();
20534 $ncx = $this->x;
20535 list($dummyx,$w) = $this->_tableGetWidth($table, $objattr['row'], $objattr['col'], $fh);
20536 $ntw = $this->table[($level+1)][$objattr['nestedcontent']]['w']; // nested table width
20537 if (!$this->simpleTables){
20538 if ($this->packTableData) {
20539 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cell['borderbin']);
20540 }
20541 else {
20542 $br = $cell['border_details']['R']['w'];
20543 $bl = $cell['border_details']['L']['w'];
20544 }
20545 if ($table['borders_separate']) {
20546 $innerw = $w - $bl - $br - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
20547 }
20548 else {
20549 $innerw = $w - $bl/2 - $br/2 - $cell['padding']['L'] - $cell['padding']['R'];
20550 }
20551 }
20552 else if ($this->simpleTables){
20553 if ($table['borders_separate']) {
20554 $innerw = $w - $table['simple']['border_details']['L']['w'] - $table['simple']['border_details']['R']['w'] - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
20555 }
20556 else {
20557 $innerw = $w - $table['simple']['border_details']['L']['w']/2 - $table['simple']['border_details']['R']['w']/2 - $cell['padding']['L'] - $cell['padding']['R'];
20558 }
20559 }
20560 if ($cell['a']=='C' || $this->table[($level+1)][$objattr['nestedcontent']]['a']=='C') {
20561 $ncx += ($innerw-$ntw)/2;
20562 }
20563 elseif ($cell['a']=='R' || $this->table[($level+1)][$objattr['nestedcontent']]['a']=='R') {
20564 $ncx += $innerw- $ntw;
20565 }
20566 $this->x = $ncx ;
20567 if ($this->cacheTables) { fclose($fh); }
20568
20569 $this->_tableWrite($this->table[($level+1)][$objattr['nestedcontent']]);
20570 $this->cellBorderBuffer = $save_buffer;
20571 $this->x = $bak_x ;
20572 $this->divwidth = $save_dw;
20573 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20574 }
20575 }
20576 else {
20577 /*-- END TABLES --*/
20578 if ($is_table) { // *TABLES*
20579 $maxWidth = $this->divwidth; // *TABLES*
20580 } // *TABLES*
20581 else { // *TABLES*
20582 $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']);
20583 } // *TABLES*
20584
20585 /*-- CSS-IMAGE-FLOAT --*/
20586 // If float (already) exists at this level
20587 if (isset($this->floatmargins['R']) && $this->y <= $this->floatmargins['R']['y1'] && $this->y >= $this->floatmargins['R']['y0']) { $maxWidth -= $this->floatmargins['R']['w']; }
20588 if (isset($this->floatmargins['L']) && $this->y <= $this->floatmargins['L']['y1'] && $this->y >= $this->floatmargins['L']['y0']) { $maxWidth -= $this->floatmargins['L']['w']; }
20589 /*-- END CSS-IMAGE-FLOAT --*/
20590
20591 list($skipln) = $this->inlineObject($objattr['type'], '', $this->y, $objattr,$this->lMargin, ($this->flowingBlockAttr['contentWidth']/_MPDFK), $maxWidth, $this->flowingBlockAttr['height'], false, $is_table);
20592 // 1 -> New line needed because of width
20593 // -1 -> Will fit width on line but NEW PAGE REQUIRED because of height
20594 // -2 -> Will not fit on line therefore needs new line but thus NEW PAGE REQUIRED
20595 $iby = $this->y;
20596 $oldpage = $this->page;
20597 $oldcol = $this->CurrCol;
20598 if (($skipln == 1 || $skipln == -2) && !isset($objattr['float'])) {
20599 $this->finishFlowingBlock(false,$objattr['type']);
20600 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20601 }
20602 $thispage = $this->page;
20603 if ($this->CurrCol!=$oldcol) { $changedcol = true; }
20604 else { $changedcol=false; }
20605
20606 // the previous lines can already have triggered page break or column change
20607 if (!$changedcol && $skipln <0 && $this->AcceptPageBreak() && $thispage==$oldpage) {
20608
20609 $this->AddPage($this->CurOrientation);
20610
20611 // Added to correct Images already set on line before page advanced
20612 // i.e. if second inline image on line is higher than first and forces new page
20613 if (count($this->objectbuffer)) {
20614 $yadj = $iby - $this->y;
20615 foreach($this->objectbuffer AS $ib=>$val) {
20616 if ($this->objectbuffer[$ib]['OUTER-Y'] ) $this->objectbuffer[$ib]['OUTER-Y'] -= $yadj;
20617 if ($this->objectbuffer[$ib]['BORDER-Y']) $this->objectbuffer[$ib]['BORDER-Y'] -= $yadj;
20618 if ($this->objectbuffer[$ib]['INNER-Y']) $this->objectbuffer[$ib]['INNER-Y'] -= $yadj;
20619 }
20620 }
20621 }
20622
20623 // Added to correct for OddEven Margins
20624 if ($this->page != $oldpage) {
20625 if (($this->page-$oldpage) % 2 == 1) {
20626 $bak_x += $this->MarginCorrection;
20627 }
20628 $oldpage = $this->page;
20629 $y = $this->tMargin - $paint_ht_corr ;
20630 $this->oldy = $this->tMargin - $paint_ht_corr ;
20631 $old_height = 0;
20632 }
20633 $this->x = $bak_x;
20634 /*-- COLUMNS --*/
20635 // COLS
20636 // OR COLUMN CHANGE
20637 if ($this->CurrCol != $oldcolumn) {
20638 if ($this->directionality == 'rtl') { // *RTL*
20639 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20640 } // *RTL*
20641 else { // *RTL*
20642 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20643 } // *RTL*
20644 $this->x = $bak_x;
20645 $oldcolumn = $this->CurrCol;
20646 $y = $this->y0 - $paint_ht_corr ;
20647 $this->oldy = $this->y0 - $paint_ht_corr ;
20648 $old_height = 0;
20649 }
20650 /*-- END COLUMNS --*/
20651
20652 /*-- CSS-IMAGE-FLOAT --*/
20653 if ($objattr['type'] == 'image' && isset($objattr['float'])) {
20654 $fy = $this->y;
20655
20656 // DIV TOP MARGIN/BORDER/PADDING
20657 if ($this->flowingBlockAttr['newblock'] && ($this->flowingBlockAttr['blockstate']==1 || $this->flowingBlockAttr['blockstate']==3) && $this->flowingBlockAttr['lineCount']== 0) {
20658 $fy += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
20659 }
20660
20661 if ($objattr['float']=='R') {
20662 $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']);
20663
20664
20665 }
20666 else if ($objattr['float']=='L') {
20667 $fx = $this->lMargin + ($this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left']);
20668 }
20669 $w = $objattr['width'];
20670 $h = abs($objattr['height']);
20671
20672 $widthLeft = $maxWidth - ($this->flowingBlockAttr['contentWidth']/_MPDFK);
20673 $maxHeight = $this->h - ($this->tMargin + $this->margin_header + $this->bMargin + 10) ;
20674 // For Images
20675 $extraWidth = ($objattr['border_left']['w'] + $objattr['border_right']['w'] + $objattr['margin_left']+ $objattr['margin_right']);
20676 $extraHeight = ($objattr['border_top']['w'] + $objattr['border_bottom']['w'] + $objattr['margin_top']+ $objattr['margin_bottom']);
20677
20678 if ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg') {
20679 $file = $objattr['file'];
20680 $info=$this->formobjects[$file];
20681 }
20682 else {
20683 $file = $objattr['file'];
20684 $info=$this->images[$file];
20685 }
20686 $img_w = $w - $extraWidth ;
20687 $img_h = $h - $extraHeight ;
20688 if ($objattr['border_left']['w']) {
20689 $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w'] + $objattr['border_right']['w'])/2) ;
20690 $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w'] + $objattr['border_bottom']['w'])/2) ;
20691 $objattr['BORDER-X'] = $fx + $objattr['margin_left'] + (($objattr['border_left']['w'])/2) ;
20692 $objattr['BORDER-Y'] = $fy + $objattr['margin_top'] + (($objattr['border_top']['w'])/2) ;
20693 }
20694 $objattr['INNER-WIDTH'] = $img_w;
20695 $objattr['INNER-HEIGHT'] = $img_h;
20696 $objattr['INNER-X'] = $fx + $objattr['margin_left'] + ($objattr['border_left']['w']);
20697 $objattr['INNER-Y'] = $fy + $objattr['margin_top'] + ($objattr['border_top']['w']) ;
20698 $objattr['ID'] = $info['i'];
20699 $objattr['OUTER-WIDTH'] = $w;
20700 $objattr['OUTER-HEIGHT'] = $h;
20701 $objattr['OUTER-X'] = $fx;
20702 $objattr['OUTER-Y'] = $fy;
20703 if ($objattr['float']=='R') {
20704 // If R float already exists at this level
20705 $this->floatmargins['R']['skipline'] = false;
20706 if (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > 0 && $fy < $this->floatmargins['R']['y1']) {
20707 $this->WriteFlowingBlock($vetor[0]);
20708 }
20709 // If L float already exists at this level
20710 else if (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > 0 && $fy < $this->floatmargins['L']['y1']) {
20711 // Final check distance between floats is not now too narrow to fit text
20712 $mw = 2*$this->GetCharWidth('W',false);
20713 if (($this->blk[$this->blklvl]['inner_width'] - $w - $this->floatmargins['L']['w']) < $mw) {
20714 $this->WriteFlowingBlock($vetor[0]);
20715 }
20716 else {
20717 $this->floatmargins['R']['x'] = $fx;
20718 $this->floatmargins['R']['w'] = $w;
20719 $this->floatmargins['R']['y0'] = $fy;
20720 $this->floatmargins['R']['y1'] = $fy + $h;
20721 if ($skipln == 1) {
20722 $this->floatmargins['R']['skipline'] = true;
20723 $this->floatmargins['R']['id'] = count($this->floatbuffer)+0;
20724 $objattr['skipline'] = true;
20725 }
20726 $this->floatbuffer[] = $objattr;
20727 }
20728 }
20729 else {
20730 $this->floatmargins['R']['x'] = $fx;
20731 $this->floatmargins['R']['w'] = $w;
20732 $this->floatmargins['R']['y0'] = $fy;
20733 $this->floatmargins['R']['y1'] = $fy + $h;
20734 if ($skipln == 1) {
20735 $this->floatmargins['R']['skipline'] = true;
20736 $this->floatmargins['R']['id'] = count($this->floatbuffer)+0;
20737 $objattr['skipline'] = true;
20738 }
20739 $this->floatbuffer[] = $objattr;
20740 }
20741 }
20742 else if ($objattr['float']=='L') {
20743 // If L float already exists at this level
20744 $this->floatmargins['L']['skipline'] = false;
20745 if (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > 0 && $fy < $this->floatmargins['L']['y1']) {
20746 $this->floatmargins['L']['skipline'] = false;
20747 $this->WriteFlowingBlock($vetor[0]);
20748 }
20749 // If R float already exists at this level
20750 else if (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > 0 && $fy < $this->floatmargins['R']['y1']) {
20751 // Final check distance between floats is not now too narrow to fit text
20752 $mw = 2*$this->GetCharWidth('W',false);
20753 if (($this->blk[$this->blklvl]['inner_width'] - $w - $this->floatmargins['R']['w']) < $mw) {
20754 $this->WriteFlowingBlock($vetor[0]);
20755 }
20756 else {
20757 $this->floatmargins['L']['x'] = $fx + $w;
20758 $this->floatmargins['L']['w'] = $w;
20759 $this->floatmargins['L']['y0'] = $fy;
20760 $this->floatmargins['L']['y1'] = $fy + $h;
20761 if ($skipln == 1) {
20762 $this->floatmargins['L']['skipline'] = true;
20763 $this->floatmargins['L']['id'] = count($this->floatbuffer)+0;
20764 $objattr['skipline'] = true;
20765 }
20766 $this->floatbuffer[] = $objattr;
20767 }
20768 }
20769 else {
20770 $this->floatmargins['L']['x'] = $fx + $w;
20771 $this->floatmargins['L']['w'] = $w;
20772 $this->floatmargins['L']['y0'] = $fy;
20773 $this->floatmargins['L']['y1'] = $fy + $h;
20774 if ($skipln == 1) {
20775 $this->floatmargins['L']['skipline'] = true;
20776 $this->floatmargins['L']['id'] = count($this->floatbuffer)+0;
20777 $objattr['skipline'] = true;
20778 }
20779 $this->floatbuffer[] = $objattr;
20780 }
20781 }
20782 }
20783 else {
20784 /*-- END CSS-IMAGE-FLOAT --*/
20785 $this->WriteFlowingBlock($vetor[0]);
20786 /*-- CSS-IMAGE-FLOAT --*/
20787 }
20788 /*-- END CSS-IMAGE-FLOAT --*/
20789 } // *TABLES*
20790
20791 } // END If special content
20792 else { //THE text
20793 if ($this->tableLevel) { $paint_ht_corr = 0; } // To move the y up when new column/page started if div border needed
20794 else { $paint_ht_corr = $this->blk[$this->blklvl]['border_top']['w']; }
20795
20796 if ($vetor[0] == "\n") { //We are reading a <BR> now turned into newline ("\n")
20797 if ($this->flowingBlockAttr['content']) {
20798 $this->finishFlowingBlock(false,'br');
20799 }
20800 else if ($is_table) {
20801 $this->y+= $this->_computeLineheight($this->table_lineheight);
20802 }
20803 else if (!$is_table) {
20804 $this->DivLn($this->lineheight);
20805 if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
20806 }
20807 // Added to correct for OddEven Margins
20808 if ($this->page != $oldpage) {
20809 if (($this->page-$oldpage) % 2 == 1) {
20810 $bak_x += $this->MarginCorrection;
20811 }
20812 $oldpage = $this->page;
20813 $y = $this->tMargin - $paint_ht_corr ;
20814 $this->oldy = $this->tMargin - $paint_ht_corr ;
20815 $old_height = 0;
20816 }
20817 $this->x = $bak_x;
20818 /*-- COLUMNS --*/
20819 // COLS
20820 // OR COLUMN CHANGE
20821 if ($this->CurrCol != $oldcolumn) {
20822 if ($this->directionality == 'rtl') { // *RTL*
20823 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20824 } // *RTL*
20825 else { // *RTL*
20826 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20827 } // *RTL*
20828 $this->x = $bak_x;
20829 $oldcolumn = $this->CurrCol;
20830 $y = $this->y0 - $paint_ht_corr ;
20831 $this->oldy = $this->y0 - $paint_ht_corr ;
20832 $old_height = 0;
20833 }
20834 /*-- END COLUMNS --*/
20835 $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$is_list,$blockstate,false,$blockdir);
20836 }
20837 else {
20838 $this->WriteFlowingBlock( $vetor[0]);
20839
20840 // Added to correct for OddEven Margins
20841 if ($this->page != $oldpage) {
20842 if (($this->page-$oldpage) % 2 == 1) {
20843 $bak_x += $this->MarginCorrection;
20844 $this->x = $bak_x;
20845 }
20846 $oldpage = $this->page;
20847 $y = $this->tMargin - $paint_ht_corr ;
20848 $this->oldy = $this->tMargin - $paint_ht_corr ;
20849 $old_height = 0;
20850 }
20851 /*-- COLUMNS --*/
20852 // COLS
20853 // OR COLUMN CHANGE
20854 if ($this->CurrCol != $oldcolumn) {
20855 if ($this->directionality == 'rtl') { // *RTL*
20856 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20857 } // *RTL*
20858 else { // *RTL*
20859 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20860 } // *RTL*
20861 $this->x = $bak_x;
20862 $oldcolumn = $this->CurrCol;
20863 $y = $this->y0 - $paint_ht_corr ;
20864 $this->oldy = $this->y0 - $paint_ht_corr ;
20865 $old_height = 0;
20866 }
20867 /*-- END COLUMNS --*/
20868 }
20869
20870
20871 }
20872
20873 //Check if it is the last element. If so then finish printing the block
20874 if ($i == ($array_size-1)) {
20875 $this->finishFlowingBlock(true); // true = END of flowing block
20876 // Added to correct for OddEven Margins
20877 if ($this->page != $oldpage) {
20878 if (($this->page-$oldpage) % 2 == 1) {
20879 $bak_x += $this->MarginCorrection;
20880 $this->x = $bak_x;
20881 }
20882 $oldpage = $this->page;
20883 $y = $this->tMargin - $paint_ht_corr ;
20884 $this->oldy = $this->tMargin - $paint_ht_corr ;
20885 $old_height = 0;
20886 }
20887
20888 /*-- COLUMNS --*/
20889 // COLS
20890 // OR COLUMN CHANGE
20891 if ($this->CurrCol != $oldcolumn) {
20892 if ($this->directionality == 'rtl') { // *RTL*
20893 $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *RTL*
20894 } // *RTL*
20895 else { // *RTL*
20896 $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
20897 } // *RTL*
20898 $this->x = $bak_x;
20899 $oldcolumn = $this->CurrCol;
20900 $y = $this->y0 - $paint_ht_corr ;
20901 $this->oldy = $this->y0 - $paint_ht_corr ;
20902 $old_height = 0;
20903 }
20904 /*-- END COLUMNS --*/
20905
20906 }
20907
20908 // RESETTING VALUES
20909 $this->SetTColor($this->ConvertColor(0));
20910 $this->SetDColor($this->ConvertColor(0));
20911 $this->SetFColor($this->ConvertColor(255));
20912 $this->colorarray = '';
20913 $this->spanbgcolorarray = '';
20914 $this->spanbgcolor = false;
20915 $this->spanborder = false;
20916 $this->spanborddet = array();
20917 $this->HREF = '';
20918 $this->textparam = array();
20919 $this->SetTextOutline();
20920 $this->SUP = false;
20921 $this->SUB = false;
20922
20923 $this->strike = false;
20924 $this->textshadow = '';
20925
20926 $this->currentfontfamily = '';
20927 $this->currentfontsize = '';
20928 $this->currentfontstyle = '';
20929 /*-- TABLES --*/
20930 if ($this->tableLevel) {
20931 $this->SetLineHeight('',$this->table_lineheight); // *TABLES*
20932 }
20933 else
20934 /*-- END TABLES --*/
20935 /*-- LISTS --*/
20936 if ($is_list && $this->list_lineheight[$this->listlvl][$this->listOcc]) {
20937 $this->SetLineHeight('',$this->list_lineheight[$this->listlvl][$this->listOcc]); // sets default line height
20938 }
20939 else
20940 /*-- END LISTS --*/
20941 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
20942 $this->SetLineHeight('',$this->blk[$this->blklvl]['line_height']); // sets default line height
20943 }
20944 $this->ResetStyles();
20945 $this->toupper = false;
20946 $this->tolower = false;
20947 $this->capitalize = false;
20948 $this->kerning = false;
20949 $this->lSpacingCSS = '';
20950 $this->wSpacingCSS = '';
20951 $this->fixedlSpacing = false;
20952 $this->minwSpacing = 0;
20953 $this->SetDash();
20954 $this->dash_on = false;
20955 $this->dotted_on = false;
20956
20957 }//end of for(i=0;i<arraysize;i++)
20958
20959
20960 // PAINT DIV BORDER // DISABLED IN COLUMNS AS DOESN'T WORK WHEN BROKEN ACROSS COLS??
20961 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)) {
20962 $bottom_y = $this->y; // Does not include Bottom Margin
20963 if (isset($this->blk[$this->blklvl]['startpage']) && $this->blk[$this->blklvl]['startpage'] != $this->page && $blockstate != 1) {
20964 $this->PaintDivBB('pagetop',$blockstate);
20965 }
20966
20967 else if ($blockstate != 1) {
20968 $this->PaintDivBB('',$blockstate);
20969 }
20970 $this->y = $bottom_y;
20971 $this->x = $bak_x;
20972 }
20973
20974 // Reset Font
20975 $this->SetFontSize($this->default_font_size,false);
20976
20977
20978 }
20979
20980 function _setDashBorder($style, $div, $cp, $side) {
20981 if ($style == 'dashed' && (($side=='L' || $side=='R') || ($side=='T' && $div != 'pagetop' && !$cp) || ($side=='B' && $div!='pagebottom') )) {
20982 $dashsize = 2; // final dash will be this + 1*linewidth
20983 $dashsizek = 1.5; // ratio of Dash/Blank
20984 $this->SetDash($dashsize,($dashsize/$dashsizek)+($this->LineWidth*2));
20985 }
20986 else if ($style == 'dotted' || ($side=='T' && ($div == 'pagetop' || $cp)) || ($side=='B' && $div == 'pagebottom')) {
20987 //Round join and cap
20988 $this->SetLineJoin(1);
20989 $this->SetLineCap(1);
20990 $this->SetDash(0.001,($this->LineWidth*3));
20991 }
20992 }
20993
20994 function _setBorderLine($b, $k=1) {
20995 $this->SetLineWidth($b['w']/$k);
20996 $this->SetDColor($b['c']);
20997 if ($b['c'][0]==5) { // RGBa
20998 $this->SetAlpha(ord($b['c'][4])/100, 'Normal', false, 'S')."\n"; // mPDF 5.7.2
20999 }
21000 else if ($b['c'][0]==6) { // CMYKa
21001 $this->SetAlpha(ord($b['c'][5])/100, 'Normal', false, 'S')."\n"; // mPDF 5.7.2
21002 }
21003 }
21004
21005 // mPDF 5.6.52
21006 function PaintDivBB($divider='',$blockstate=0,$blvl=0) {
21007 // Borders & backgrounds are done elsewhere for columns - messes up the repositioning in printcolumnbuffer
21008 if ($this->ColActive) { return ; } // *COLUMNS*
21009 $save_y = $this->y;
21010 if (!$blvl) { $blvl = $this->blklvl; }
21011 $x0 = $x1 = $y0 = $y1 = 0;
21012
21013 // Added mPDF 3.0 Float DIV
21014 if (isset($this->blk[$blvl]['bb_painted'][$this->page]) && $this->blk[$blvl]['bb_painted'][$this->page]) { return; } // *CSS-FLOAT*
21015
21016 if (isset($this->blk[$blvl]['x0'])) { $x0 = $this->blk[$blvl]['x0']; } // left
21017 if (isset($this->blk[$blvl]['y1'])) { $y1 = $this->blk[$blvl]['y1']; } // bottom
21018
21019 // Added mPDF 3.0 Float DIV - ensures backgrounds/borders are drawn to bottom of page
21020 if ($y1==0) {
21021 if ($divider=='pagebottom') { $y1 = $this->h-$this->bMargin; }
21022 else { $y1 = $this->y; }
21023 }
21024
21025 if (isset($this->blk[$blvl]['startpage']) && $this->blk[$blvl]['startpage'] != $this->page) { $continuingpage = true; } else { $continuingpage = false; }
21026
21027 if (isset($this->blk[$blvl]['y0'])) { $y0 = $this->blk[$blvl]['y0']; }
21028 $h = $y1 - $y0;
21029 $w = $this->blk[$blvl]['width'];
21030 $x1 = $x0 + $w;
21031
21032 // Set border-widths as used here
21033 $border_top = $this->blk[$blvl]['border_top']['w'];
21034 $border_bottom = $this->blk[$blvl]['border_bottom']['w'];
21035 $border_left = $this->blk[$blvl]['border_left']['w'];
21036 $border_right = $this->blk[$blvl]['border_right']['w'];
21037 if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
21038 $border_top = 0;
21039 }
21040 if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') {
21041 $border_bottom = 0;
21042 }
21043
21044 $brTL_H = 0;
21045 $brTL_V = 0;
21046 $brTR_H = 0;
21047 $brTR_V = 0;
21048 $brBL_H = 0;
21049 $brBL_V = 0;
21050 $brBR_H = 0;
21051 $brBR_V = 0;
21052
21053 $brset = false;
21054 /*-- BORDER-RADIUS --*/
21055 if (isset($this->blk[$blvl]['border_radius_TL_H'])) { $brTL_H = $this->blk[$blvl]['border_radius_TL_H']; $brset = true; }
21056 if (isset($this->blk[$blvl]['border_radius_TL_V'])) { $brTL_V = $this->blk[$blvl]['border_radius_TL_V']; $brset = true; }
21057 if (isset($this->blk[$blvl]['border_radius_TR_H'])) { $brTR_H = $this->blk[$blvl]['border_radius_TR_H']; $brset = true; }
21058 if (isset($this->blk[$blvl]['border_radius_TR_V'])) { $brTR_V = $this->blk[$blvl]['border_radius_TR_V']; $brset = true; }
21059 if (isset($this->blk[$blvl]['border_radius_BR_H'])) { $brBR_H = $this->blk[$blvl]['border_radius_BR_H']; $brset = true; }
21060 if (isset($this->blk[$blvl]['border_radius_BR_V'])) { $brBR_V = $this->blk[$blvl]['border_radius_BR_V']; $brset = true; }
21061 if (isset($this->blk[$blvl]['border_radius_BL_H'])) { $brBL_H = $this->blk[$blvl]['border_radius_BL_H']; $brset = true; }
21062 if (isset($this->blk[$blvl]['border_radius_BL_V'])) { $brBL_V = $this->blk[$blvl]['border_radius_BL_V']; $brset = true; }
21063
21064 // mPDF 5.4.17
21065 //if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage || $this->keep_block_together) {
21066 if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
21067 $brTL_H = 0;
21068 $brTL_V = 0;
21069 $brTR_H = 0;
21070 $brTR_V = 0;
21071 }
21072 // mPDF 5.4.17
21073 //if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom' || $this->keep_block_together) {
21074 if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') {
21075 $brBL_H = 0;
21076 $brBL_V = 0;
21077 $brBR_H = 0;
21078 $brBR_V = 0;
21079 }
21080
21081 // Disallow border-radius if it is smaller than the border width.
21082 if ($brTL_H < min($border_left, $border_top)) { $brTL_H = $brTL_V = 0; }
21083 if ($brTL_V < min($border_left, $border_top)) { $brTL_V = $brTL_H = 0; }
21084 if ($brTR_H < min($border_right, $border_top)) { $brTR_H = $brTR_V = 0; }
21085 if ($brTR_V < min($border_right, $border_top)) { $brTR_V = $brTR_H = 0; }
21086 if ($brBL_H < min($border_left, $border_bottom)) { $brBL_H = $brBL_V = 0; }
21087 if ($brBL_V < min($border_left, $border_bottom)) { $brBL_V = $brBL_H = 0; }
21088 if ($brBR_H < min($border_right, $border_bottom)) { $brBR_H = $brBR_V = 0; }
21089 if ($brBR_V < min($border_right, $border_bottom)) { $brBR_V = $brBR_H = 0; }
21090
21091 // CHECK FOR radii that sum to > width or height of div ********
21092 $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));
21093 if ($f < 1) {
21094 $brTL_H *= $f;
21095 $brTL_V *= $f;
21096 $brTR_H *= $f;
21097 $brTR_V *= $f;
21098 $brBL_H *= $f;
21099 $brBL_V *= $f;
21100 $brBR_H *= $f;
21101 $brBR_V *= $f;
21102 }
21103 /*-- END BORDER-RADIUS --*/
21104
21105 $tbcol = $this->ConvertColor(255);
21106 for($l=0; $l <= $blvl; $l++) {
21107 if ($this->blk[$l]['bgcolor']) {
21108 $tbcol = $this->blk[$l]['bgcolorarray'];
21109 }
21110 }
21111
21112 // BORDERS
21113 if (isset($this->blk[$blvl]['y0']) && $this->blk[$blvl]['y0']) { $y0 = $this->blk[$blvl]['y0']; }
21114 $h = $y1 - $y0;
21115 $w = $this->blk[$blvl]['width'];
21116
21117 //if ($this->blk[$blvl]['border_top']) {
21118 // Reinstate line above for dotted line divider when block border crosses a page
21119 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21120 $tbd = $this->blk[$blvl]['border_top'];
21121
21122 // mPDF 5.4.18
21123 $legend = '';
21124 if (isset($this->blk[$blvl]['border_legend']) && $this->blk[$blvl]['border_legend']) {
21125 $legend = $this->blk[$blvl]['border_legend']; // Same structure array as textbuffer
21126 $txt = ltrim($legend[0]);
21127
21128 //Set font, size, style, color
21129 $this->SetFont($legend[4],$legend[2],$legend[11]);
21130 if ($legend[3]) {
21131 $cor = $legend[3];
21132 $this->SetTColor($cor);
21133 }
21134 $stringWidth = $this->GetStringWidth($txt );
21135 $save_x = $this->x;
21136 $save_y = $this->y;
21137 $save_currentfontfamily = $this->FontFamily;
21138 $save_currentfontsize = $this->FontSizePt;
21139 $save_currentfontstyle = $this->FontStyle.($this->U ? 'U' : '').($this->S ? 'S' : '');
21140 $this->y = $y0 - $this->FontSize/2 + $this->blk[$blvl]['border_top']['w']/2;
21141 $this->x = $x0 + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_left']['w'];
21142
21143 // Set the distance from the border line to the text ? make configurable variable
21144 $gap = 0.2 * $this->FontSize;
21145
21146 $legbreakL = $this->x - $gap;
21147 $legbreakR = $this->x + $stringWidth + $gap;
21148
21149 $this->Cell( $stringWidth, $this->FontSize, $txt , '', 0, 'C', $fill, '', 0, 0,0,'M', $fill);
21150 // Reset
21151 $this->x = $save_x;
21152 $this->y = $save_y;
21153 $this->SetFont($save_currentfontfamily,$save_currentfontstyle,$save_currentfontsize);
21154 $this->SetTColor($this->ConvertColor(0));
21155 }
21156
21157 if (isset($tbd['s']) && $tbd['s']) {
21158 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
21159 $this->_out('q');
21160 $this->SetLineWidth(0);
21161 $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0))*_MPDFK));
21162 $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0 + $border_top))*_MPDFK));
21163 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0 + $border_top))*_MPDFK));
21164 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0))*_MPDFK));
21165 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
21166 }
21167
21168 $this->_setBorderLine($tbd);
21169 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
21170 $legbreakL -= $border_top/2; // because line cap different
21171 $legbreakR += $border_top/2;
21172 $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'T');
21173 }
21174 /*-- BORDER-RADIUS --*/
21175 else if (($brTL_V && $brTL_H) || ($brTR_V && $brTR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
21176 $this->SetLineJoin(0);
21177 $this->SetLineCap(0);
21178 }
21179 $s = '';
21180 if ($brTR_H && $brTR_V) {
21181 $s .= ($this->_EllipseArc($x0 + $w - $brTR_H, $y0 + $brTR_V, $brTR_H - $border_top/2 , $brTR_V - $border_top/2 , 1, 2, true))."\n";
21182 }
21183 else
21184 /*-- END BORDER-RADIUS --*/
21185 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21186 $s .= (sprintf('%.3F %.3F m ',($x0 + $w)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
21187 }
21188 else {
21189 $s .= (sprintf('%.3F %.3F m ',($x0 + $w - ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
21190 }
21191 /*-- BORDER-RADIUS --*/
21192 if ($brTL_H && $brTL_V ) {
21193 // mPDF 5.4.18
21194 if ($legend) {
21195 if ($legbreakR < ($x0 + $w - $brTR_H)) {
21196 $s .= (sprintf('%.3F %.3F l ', $legbreakR*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
21197 }
21198 if ($legbreakL > ($x0 + $brTL_H )) {
21199 $s .= (sprintf('%.3F %.3F m ',$legbreakL*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
21200 $s .= (sprintf('%.3F %.3F l ',($x0 + $brTL_H )*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK)."\n");
21201 }
21202 else {
21203 $s .= (sprintf('%.3F %.3F m ',($x0 + $brTL_H )*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
21204 }
21205 }
21206 else {
21207 $s .= (sprintf('%.3F %.3F l ',($x0 + $brTL_H )*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
21208 }
21209 $s .= ($this->_EllipseArc($x0 + $brTL_H, $y0 + $brTL_V, $brTL_H - $border_top/2 , $brTL_V - $border_top/2 , 2, 1))."\n";
21210 }
21211 else {
21212 /*-- END BORDER-RADIUS --*/
21213 // mPDF 5.4.18
21214 if ($legend) {
21215 if ($legbreakR < ($x0 + $w)) {
21216 $s .= (sprintf('%.3F %.3F l ',$legbreakR*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
21217 }
21218 if ($legbreakL > ($x0)) {
21219 $s .= (sprintf('%.3F %.3F m ',$legbreakL*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
21220 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21221 $s .= (sprintf('%.3F %.3F l ',($x0)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
21222 }
21223 else {
21224 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
21225 }
21226 }
21227 else if ($tbd['style']=='solid' || $tbd['style']=='double') {
21228 $s .= (sprintf('%.3F %.3F m ', ($x0)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
21229 }
21230 else {
21231 $s .= (sprintf('%.3F %.3F m ', ($x0 + $border_top/2)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
21232 }
21233 }
21234 else if ($tbd['style']=='solid' || $tbd['style']=='double') {
21235 $s .= (sprintf('%.3F %.3F l ',($x0)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
21236 }
21237 else {
21238 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
21239 }
21240 /*-- BORDER-RADIUS --*/
21241 }
21242 /*-- END BORDER-RADIUS --*/
21243 $s .= 'S'."\n";
21244 $this->_out($s);
21245
21246 if ($tbd['style']=='double') {
21247 $this->SetLineWidth($tbd['w']/3);
21248 $this->SetDColor($tbcol);
21249 $this->_out($s);
21250 }
21251 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
21252
21253 // Reset Corners and Dash off
21254 $this->SetLineWidth(0.1); // mPDF 5.6.57
21255 $this->SetDColor($this->ConvertColor(0));
21256 $this->SetLineJoin(2);
21257 $this->SetLineCap(2);
21258 $this->SetDash();
21259 }
21260 }
21261 //if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1) {
21262 // Reinstate line above for dotted line divider when block border crosses a page
21263 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21264 $tbd = $this->blk[$blvl]['border_bottom'];
21265 if (isset($tbd['s']) && $tbd['s']) {
21266 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
21267 $this->_out('q');
21268 $this->SetLineWidth(0);
21269 $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
21270 $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
21271 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
21272 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
21273 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
21274 }
21275
21276 $this->_setBorderLine($tbd);
21277 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'B'); }
21278 /*-- BORDER-RADIUS --*/
21279 else if (($brBL_V && $brBL_H) || ($brBR_V && $brBR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
21280 $this->SetLineJoin(0);
21281 $this->SetLineCap(0);
21282 }
21283 $s = '';
21284 if ($brBL_H && $brBL_V) {
21285 $s .= ($this->_EllipseArc($x0 + $brBL_H, $y0 + $h - $brBL_V, $brBL_H - $border_bottom/2 , $brBL_V - $border_bottom/2 , 3, 2, true))."\n";
21286 }
21287 else
21288 /*-- END BORDER-RADIUS --*/
21289 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21290 $s .= (sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
21291 }
21292 else {
21293 $s .= (sprintf('%.3F %.3F m ',($x0 + ($border_bottom/2))*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
21294 }
21295 /*-- BORDER-RADIUS --*/
21296 if ($brBR_H && $brBR_V ) {
21297 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_bottom/2) - $brBR_H )*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
21298 $s .= ($this->_EllipseArc($x0 + $w - $brBR_H, $y0 + $h - $brBR_V, $brBR_H - $border_bottom/2 , $brBR_V - $border_bottom/2 , 4, 1))."\n";
21299 }
21300 else
21301 /*-- END BORDER-RADIUS --*/
21302 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21303 $s .= (sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
21304 }
21305 else {
21306 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_bottom/2))*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
21307 }
21308 $s .= 'S'."\n";
21309 $this->_out($s);
21310
21311 if ($tbd['style']=='double') {
21312 $this->SetLineWidth($tbd['w']/3);
21313 $this->SetDColor($tbcol);
21314 $this->_out($s);
21315 }
21316 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
21317
21318
21319 // Reset Corners and Dash off
21320 $this->SetLineWidth(0.1); // mPDF 5.6.57
21321 $this->SetDColor($this->ConvertColor(0));
21322 $this->SetLineJoin(2);
21323 $this->SetLineCap(2);
21324 $this->SetDash();
21325 }
21326 }
21327 if ($this->blk[$blvl]['border_left']) {
21328 $tbd = $this->blk[$blvl]['border_left'];
21329 if (isset($tbd['s']) && $tbd['s']) {
21330 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
21331 $this->_out('q');
21332 $this->SetLineWidth(0);
21333 $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0))*_MPDFK));
21334 $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0+$border_top))*_MPDFK));
21335 $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
21336 $this->_out(sprintf('%.3F %.3F l ',($x0)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
21337 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
21338 }
21339
21340 $this->_setBorderLine($tbd);
21341 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'L'); }
21342 /*-- BORDER-RADIUS --*/
21343 else if (($brTL_V && $brTL_H) || ($brBL_V && $brBL_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
21344 $this->SetLineJoin(0);
21345 $this->SetLineCap(0);
21346 }
21347 $s = '';
21348 if ($brTL_V && $brTL_H) {
21349 $s .= ($this->_EllipseArc($x0 + $brTL_H, $y0 + $brTL_V, $brTL_H - $border_left/2 , $brTL_V - $border_left/2, 2, 2, true))."\n";
21350 }
21351 else
21352 /*-- END BORDER-RADIUS --*/
21353 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21354 $s .= (sprintf('%.3F %.3F m ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0))*_MPDFK))."\n";
21355 }
21356 else {
21357 $s .= (sprintf('%.3F %.3F m ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + ($border_left/2)))*_MPDFK))."\n";
21358 }
21359 /*-- BORDER-RADIUS --*/
21360 if ($brBL_V && $brBL_H ) {
21361 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h - ($border_left/2)- $brBL_V) )*_MPDFK))."\n";
21362 $s .= ($this->_EllipseArc($x0 + $brBL_H, $y0 + $h - $brBL_V, $brBL_H - $border_left/2 , $brBL_V - $border_left/2, 3, 1))."\n";
21363 }
21364 else
21365 /*-- END BORDER-RADIUS --*/
21366 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21367 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h) )*_MPDFK))."\n";
21368 }
21369 else {
21370 $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h - ($border_left/2)) )*_MPDFK))."\n";
21371 }
21372 $s .= 'S'."\n";
21373 $this->_out($s);
21374
21375 if ($tbd['style']=='double') {
21376 $this->SetLineWidth($tbd['w']/3);
21377 $this->SetDColor($tbcol);
21378 $this->_out($s);
21379 }
21380 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
21381
21382 // Reset Corners and Dash off
21383 $this->SetLineWidth(0.1); // mPDF 5.6.57
21384 $this->SetDColor($this->ConvertColor(0));
21385 $this->SetLineJoin(2);
21386 $this->SetLineCap(2);
21387 $this->SetDash();
21388 }
21389 }
21390 if ($this->blk[$blvl]['border_right']) {
21391 $tbd = $this->blk[$blvl]['border_right'];
21392 if (isset($tbd['s']) && $tbd['s']) {
21393 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
21394 $this->_out('q');
21395 $this->SetLineWidth(0);
21396 $this->_out(sprintf('%.3F %.3F m ',($x0 + $w)*_MPDFK, ($this->h-($y0))*_MPDFK));
21397 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0+$border_top))*_MPDFK));
21398 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
21399 $this->_out(sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
21400 $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
21401 }
21402
21403 $this->_setBorderLine($tbd);
21404 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'R'); }
21405 /*-- BORDER-RADIUS --*/
21406 else if (($brTR_V && $brTR_H) || ($brBR_V && $brBR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) { // mPDF 5.6.58
21407 $this->SetLineJoin(0);
21408 $this->SetLineCap(0);
21409 }
21410 $s = '';
21411 if ($brBR_V && $brBR_H) {
21412 $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";
21413 }
21414 else
21415 /*-- END BORDER-RADIUS --*/
21416 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21417 $s .= (sprintf('%.3F %.3F m ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + $h))*_MPDFK))."\n";
21418 }
21419 else {
21420 $s .= (sprintf('%.3F %.3F m ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + $h - ($border_right/2)))*_MPDFK))."\n";
21421 }
21422 /*-- BORDER-RADIUS --*/
21423 if ($brTR_V && $brTR_H ) {
21424 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + ($border_right/2) + $brTR_V) )*_MPDFK))."\n";
21425 $s .= ($this->_EllipseArc($x0 + $w - $brTR_H, $y0 + $brTR_V, $brTR_H - $border_right/2 , $brTR_V - $border_right/2, 1, 1))."\n";
21426 }
21427 else
21428 /*-- END BORDER-RADIUS --*/
21429 if ($tbd['style']=='solid' || $tbd['style']=='double') {
21430 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0) )*_MPDFK))."\n";
21431 }
21432 else {
21433 $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + ($border_right/2)) )*_MPDFK))."\n";
21434 }
21435 $s .= 'S'."\n";
21436 $this->_out($s);
21437
21438 if ($tbd['style']=='double') {
21439 $this->SetLineWidth($tbd['w']/3);
21440 $this->SetDColor($tbcol);
21441 $this->_out($s);
21442 }
21443 if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
21444
21445 // Reset Corners and Dash off
21446 $this->SetLineWidth(0.1); // mPDF 5.6.57
21447 $this->SetDColor($this->ConvertColor(0));
21448 $this->SetLineJoin(2);
21449 $this->SetLineCap(2);
21450 $this->SetDash();
21451 }
21452 }
21453
21454
21455 $this->SetDash();
21456 $this->y = $save_y;
21457
21458
21459 // BACKGROUNDS are disabled in columns/kbt/headers - messes up the repositioning in printcolumnbuffer
21460 if ($this->ColActive || $this->kwt || $this->keep_block_together) { return ; }
21461
21462
21463 $bgx0 = $x0;
21464 $bgx1 = $x1;
21465 $bgy0 = $y0;
21466 $bgy1 = $y1;
21467
21468 // Defined br values represent the radius of the outer curve - need to take border-width/2 from each radius for drawing the borders
21469 if (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'padding-box') {
21470 $brbgTL_H = max(0, $brTL_H - $this->blk[$blvl]['border_left']['w']);
21471 $brbgTL_V = max(0, $brTL_V - $this->blk[$blvl]['border_top']['w']);
21472 $brbgTR_H = max(0, $brTR_H - $this->blk[$blvl]['border_right']['w']);
21473 $brbgTR_V = max(0, $brTR_V - $this->blk[$blvl]['border_top']['w']);
21474 $brbgBL_H = max(0, $brBL_H - $this->blk[$blvl]['border_left']['w']);
21475 $brbgBL_V = max(0, $brBL_V - $this->blk[$blvl]['border_bottom']['w']);
21476 $brbgBR_H = max(0, $brBR_H - $this->blk[$blvl]['border_right']['w']);
21477 $brbgBR_V = max(0, $brBR_V - $this->blk[$blvl]['border_bottom']['w']);
21478 $bgx0 += $this->blk[$blvl]['border_left']['w'];
21479 $bgx1 -= $this->blk[$blvl]['border_right']['w'];
21480 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21481 $bgy0 += $this->blk[$blvl]['border_top']['w'];
21482 }
21483 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21484 $bgy1 -= $this->blk[$blvl]['border_bottom']['w'];
21485 }
21486 }
21487 // mPDF 5.6.09
21488 else if (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'content-box') {
21489 $brbgTL_H = max(0, $brTL_H - $this->blk[$blvl]['border_left']['w'] - $this->blk[$blvl]['padding_left']);
21490 $brbgTL_V = max(0, $brTL_V - $this->blk[$blvl]['border_top']['w'] - $this->blk[$blvl]['padding_top']);
21491 $brbgTR_H = max(0, $brTR_H - $this->blk[$blvl]['border_right']['w'] - $this->blk[$blvl]['padding_right']);
21492 $brbgTR_V = max(0, $brTR_V - $this->blk[$blvl]['border_top']['w'] - $this->blk[$blvl]['padding_top']);
21493 $brbgBL_H = max(0, $brBL_H - $this->blk[$blvl]['border_left']['w'] - $this->blk[$blvl]['padding_left']);
21494 $brbgBL_V = max(0, $brBL_V - $this->blk[$blvl]['border_bottom']['w'] - $this->blk[$blvl]['padding_bottom']);
21495 $brbgBR_H = max(0, $brBR_H - $this->blk[$blvl]['border_right']['w'] - $this->blk[$blvl]['padding_right']);
21496 $brbgBR_V = max(0, $brBR_V - $this->blk[$blvl]['border_bottom']['w'] - $this->blk[$blvl]['padding_bottom']);
21497 $bgx0 += $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
21498 $bgx1 -= $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right'];
21499 if (($this->blk[$blvl]['border_top']['w'] || $this->blk[$blvl]['padding_top']) && $divider != 'pagetop' && !$continuingpage) {
21500 $bgy0 += $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
21501 }
21502 if (($this->blk[$blvl]['border_bottom']['w'] || $this->blk[$blvl]['padding_bottom']) && $blockstate != 1 && $divider != 'pagebottom') {
21503 $bgy1 -= $this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom'];
21504 }
21505 }
21506 else {
21507 $brbgTL_H = $brTL_H;
21508 $brbgTL_V = $brTL_V;
21509 $brbgTR_H = $brTR_H;
21510 $brbgTR_V = $brTR_V;
21511 $brbgBL_H = $brBL_H;
21512 $brbgBL_V = $brBL_V;
21513 $brbgBR_H = $brBR_H;
21514 $brbgBR_V = $brBR_V;
21515 }
21516
21517 // Set clipping path
21518 $s = ' q 0 w '; // Line width=0
21519 $s .= sprintf('%.3F %.3F m ', ($bgx0+$brbgTL_H )*_MPDFK, ($this->h-$bgy0)*_MPDFK); // start point TL before the arc
21520 /*-- BORDER-RADIUS --*/
21521 if ($brbgTL_H || $brbgTL_V) {
21522 $s .= $this->_EllipseArc($bgx0+$brbgTL_H, $bgy0+$brbgTL_V, $brbgTL_H , $brbgTL_V , 2); // segment 2 TL
21523 }
21524 /*-- END BORDER-RADIUS --*/
21525 $s .= sprintf('%.3F %.3F l ', ($bgx0)*_MPDFK, ($this->h-($bgy1-$brbgBL_V ))*_MPDFK); // line to BL
21526 /*-- BORDER-RADIUS --*/
21527 if ($brbgBL_H || $brbgBL_V) {
21528 $s .= $this->_EllipseArc($bgx0+$brbgBL_H, $bgy1-$brbgBL_V, $brbgBL_H , $brbgBL_V , 3); // segment 3 BL
21529 }
21530 /*-- END BORDER-RADIUS --*/
21531 $s .= sprintf('%.3F %.3F l ', ($bgx1-$brbgBR_H )*_MPDFK, ($this->h-($bgy1))*_MPDFK); // line to BR
21532 /*-- BORDER-RADIUS --*/
21533 if ($brbgBR_H || $brbgBR_V) {
21534 $s .= $this->_EllipseArc($bgx1-$brbgBR_H, $bgy1-$brbgBR_V, $brbgBR_H , $brbgBR_V , 4); // segment 4 BR
21535 }
21536 /*-- END BORDER-RADIUS --*/
21537 $s .= sprintf('%.3F %.3F l ', ($bgx1)*_MPDFK, ($this->h-($bgy0+$brbgTR_V))*_MPDFK); // line to TR
21538 /*-- BORDER-RADIUS --*/
21539 if ($brbgTR_H || $brbgTR_V) {
21540 $s .= $this->_EllipseArc($bgx1-$brbgTR_H, $bgy0+$brbgTR_V, $brbgTR_H , $brbgTR_V , 1); // segment 1 TR
21541 }
21542 /*-- END BORDER-RADIUS --*/
21543 $s .= sprintf('%.3F %.3F l ', ($bgx0+$brbgTL_H )*_MPDFK, ($this->h-$bgy0)*_MPDFK); // line to TL
21544
21545
21546 // Box Shadow
21547 $shadow = '';
21548 if (isset($this->blk[$blvl]['box_shadow']) && $this->blk[$blvl]['box_shadow'] && $h > 0) {
21549 foreach($this->blk[$blvl]['box_shadow'] AS $sh) {
21550 // Colors
21551 if ($sh['col']{0}==1) {
21552 $colspace = 'Gray';
21553 if ($sh['col']{2}==1) { $col1 = '1'.$sh['col'][1].'1'.$sh['col'][3]; }
21554 else { $col1 = '1'.$sh['col'][1].'1'.chr(100); }
21555 $col2 = '1'.$sh['col'][1].'1'.chr(0);
21556 }
21557 else if ($sh['col']{0}==4) { // CMYK
21558 $colspace = 'CMYK';
21559 $col1 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(100);
21560 $col2 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(0);
21561 }
21562 else if ($sh['col']{0}==5) { // RGBa
21563 $colspace = 'RGB';
21564 $col1 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4];
21565 $col2 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(0);
21566 }
21567 else if ($sh['col']{0}==6) { // CMYKa
21568 $colspace = 'CMYK';
21569 $col1 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].$sh['col'][5];
21570 $col2 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(0);
21571 }
21572 else {
21573 $colspace = 'RGB';
21574 $col1 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(100);
21575 $col2 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(0);
21576 }
21577
21578 // Use clipping path as set above (and rectangle around page) to clip area outside box
21579 $shadow .= $s; // Use the clipping path with W*
21580 $shadow .= sprintf('0 %.3F m %.3F %.3F l ', $this->h*_MPDFK, $this->w*_MPDFK, $this->h*_MPDFK);
21581 $shadow .= sprintf('%.3F 0 l 0 0 l 0 %.3F l ', $this->w*_MPDFK, $this->h*_MPDFK);
21582 $shadow .= 'W n'."\n";
21583
21584 $sh['blur'] = abs($sh['blur']); // cannot have negative blur value
21585 // Ensure spread/blur do not make effective shadow width/height < 0
21586 // Could do more complex things but this just adjusts spread value
21587 if (-$sh['spread'] + $sh['blur']/2 > min($w/2, $h/2)) {
21588 $sh['spread'] = $sh['blur']/2 - min($w/2, $h/2) + 0.01;
21589 }
21590 // Shadow Offset
21591 if ($sh['x'] || $sh['y']) $shadow .= sprintf(' q 1 0 0 1 %.4F %.4F cm', $sh['x']*_MPDFK, -$sh['y']*_MPDFK)."\n";
21592
21593 // Set path for INNER shadow
21594 $shadow .= ' q 0 w ';
21595 $shadow .= $this->SetFColor($col1, true)."\n";
21596 if ($col1{0}==5 && ord($col1{4})<100) { // RGBa
21597 $shadow .= $this->SetAlpha(ord($col1{4})/100, 'Normal', true, 'F')."\n";
21598 }
21599 else if ($col1{0}==6 && ord($col1{5})<100) { // CMYKa
21600 $shadow .= $this->SetAlpha(ord($col1{5})/100, 'Normal', true, 'F')."\n";
21601 }
21602 else if ($col1{0}==1 && $col1{2}==1 && ord($col1{3})<100) { // Gray
21603 $shadow .= $this->SetAlpha(ord($col1{3})/100, 'Normal', true, 'F')."\n";
21604 }
21605
21606 // Blur edges
21607 $mag = 0.551784; // Bezier Control magic number for 4-part spline for circle/ellipse
21608 $mag2 = 0.551784; // Bezier Control magic number to fill in edge of blurred rectangle
21609 $d1 = $sh['spread']+$sh['blur']/2;
21610 $d2 = $sh['spread']-$sh['blur']/2;
21611 $bl = $sh['blur'];
21612 $x00 = $x0 - $d1;
21613 $y00 = $y0 - $d1;
21614 $w00 = $w + $d1*2;
21615 $h00 = $h + $d1*2;
21616
21617 // If any border-radius is greater width-negative spread(inner edge), ignore radii for shadow or screws up
21618 $flatten = false;
21619 if (max($brbgTR_H, $brbgTL_H, $brbgBR_H, $brbgBL_H) >= $w+$d2) { $flatten = true; }
21620 if (max($brbgTR_V, $brbgTL_V, $brbgBR_V, $brbgBL_V) >= $h+$d2) { $flatten = true; }
21621
21622
21623 // TOP RIGHT corner
21624 $p1x = $x00+$w00-$d1-$brbgTR_H; $p1c2x = $p1x +($d2+$brbgTR_H)*$mag;
21625 $p1y = $y00+$bl;
21626 $p2x = $x00+$w00-$d1-$brbgTR_H; $p2c2x = $p2x + ($d1+$brbgTR_H)*$mag;
21627 $p2y = $y00; $p2c1y = $p2y + $bl/2;
21628 $p3x = $x00+$w00; $p3c2x = $p3x - $bl/2;
21629 $p3y = $y00+$d1+$brbgTR_V; $p3c1y = $p3y - ($d1+$brbgTR_V)*$mag;
21630 $p4x = $x00+$w00-$bl;
21631 $p4y = $y00+$d1+$brbgTR_V; $p4c2y = $p4y - ($d2+$brbgTR_V)*$mag;
21632 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21633 $p1x = $x00+$w00-$bl; $p1c2x = $p1x;
21634 $p2x = $x00+$w00-$bl; $p2c2x = $p2x + $bl*$mag2;
21635 $p3y = $y00+$bl; $p3c1y = $p3y - $bl*$mag2;
21636 $p4y = $y00+$bl; $p4c2y = $p4y ;
21637 }
21638
21639 $shadow .= sprintf('%.3F %.3F m ', ($p1x )*_MPDFK, ($this->h-($p1y ))*_MPDFK);
21640 $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);
21641 $patch_array[0]['f']=0;
21642 $patch_array[0]['points']=array($p1x,$p1y, $p1x,$p1y,
21643 $p2x,$p2c1y, $p2x,$p2y, $p2c2x,$p2y,
21644 $p3x,$p3c1y, $p3x,$p3y, $p3c2x,$p3y,
21645 $p4x,$p4y, $p4x,$p4y, $p4x,$p4c2y,
21646 $p1c2x,$p1y);
21647 $patch_array[0]['colors'] = array($col1,$col2,$col2,$col1);
21648
21649
21650 // RIGHT
21651 $p1x = $x00+$w00; // control point only matches p3 preceding
21652 $p1y = $y00+$d1+$brbgTR_V;
21653 $p2x = $x00+$w00-$bl; // control point only matches p4 preceding
21654 $p2y = $y00+$d1+$brbgTR_V;
21655 $p3x = $x00+$w00-$bl;
21656 $p3y = $y00+$h00-$d1-$brbgBR_V;
21657 $p4x = $x00+$w00; $p4c1x = $p4x-$bl/2;
21658 $p4y = $y00+$h00-$d1-$brbgBR_V;
21659 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21660 $p1y = $y00+$bl;
21661 $p2y = $y00+$bl;
21662 }
21663 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21664 $p3y = $y00+$h00-$bl;
21665 $p4y = $y00+$h00-$bl;
21666 }
21667
21668 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21669 $patch_array[1]['f']=2;
21670 $patch_array[1]['points']=array($p2x,$p2y,
21671 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21672 $p4c1x,$p4y, $p4x,$p4y, $p4x,$p4y,
21673 $p1x,$p1y);
21674 $patch_array[1]['colors'] = array($col1,$col2);
21675
21676
21677 // BOTTOM RIGHT corner
21678 $p1x = $x00+$w00-$bl; // control points only matches p3 preceding
21679 $p1y = $y00+$h00-$d1-$brbgBR_V; $p1c2y = $p1y + ($d2+$brbgBR_V)*$mag;
21680 $p2x = $x00+$w00; // control point only matches p4 preceding
21681 $p2y = $y00+$h00-$d1-$brbgBR_V; $p2c2y = $p2y + ($d1+$brbgBR_V)*$mag;
21682 $p3x = $x00+$w00-$d1-$brbgBR_H; $p3c1x = $p3x + ($d1+$brbgBR_H)*$mag;
21683 $p3y = $y00+$h00; $p3c2y = $p3y - $bl/2;
21684 $p4x = $x00+$w00-$d1-$brbgBR_H; $p4c2x = $p4x + ($d2+$brbgBR_H)*$mag;
21685 $p4y = $y00+$h00-$bl;
21686
21687 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21688 $p1y = $y00+$h00-$bl; $p1c2y = $p1y;
21689 $p2y = $y00+$h00-$bl; $p2c2y = $p2y + $bl*$mag2;
21690 $p3x = $x00+$w00-$bl; $p3c1x = $p3x + $bl*$mag2;
21691 $p4x = $x00+$w00-$bl; $p4c2x = $p4x;
21692 }
21693
21694 $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);
21695 $patch_array[2]['f']=2;
21696 $patch_array[2]['points']=array($p2x,$p2c2y,
21697 $p3c1x,$p3y, $p3x,$p3y, $p3x,$p3c2y,
21698 $p4x,$p4y, $p4x,$p4y, $p4c2x,$p4y,
21699 $p1x,$p1c2y);
21700 $patch_array[2]['colors'] = array($col2,$col1);
21701
21702
21703
21704 // BOTTOM
21705 $p1x = $x00+$w00-$d1-$brbgBR_H; // control point only matches p3 preceding
21706 $p1y = $y00+$h00;
21707 $p2x = $x00+$w00-$d1-$brbgBR_H; // control point only matches p4 preceding
21708 $p2y = $y00+$h00-$bl;
21709 $p3x = $x00+$d1+$brbgBL_H;
21710 $p3y = $y00+$h00-$bl;
21711 $p4x = $x00+$d1+$brbgBL_H;
21712 $p4y = $y00+$h00; $p4c1y = $p4y - $bl/2;
21713
21714 if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
21715 $p1x = $x00+$w00-$bl;
21716 $p2x = $x00+$w00-$bl;
21717 }
21718 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21719 $p3x = $x00+$bl;
21720 $p4x = $x00+$bl;
21721 }
21722
21723 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21724 $patch_array[3]['f']=2;
21725 $patch_array[3]['points']=array($p2x,$p2y,
21726 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21727 $p4x,$p4c1y, $p4x,$p4y, $p4x,$p4y,
21728 $p1x,$p1y);
21729 $patch_array[3]['colors'] = array($col1,$col2);
21730
21731 // BOTTOM LEFT corner
21732 $p1x = $x00+$d1+$brbgBL_H; $p1c2x = $p1x - ($d2+$brbgBL_H)*$mag; // control points only matches p3 preceding
21733 $p1y = $y00+$h00-$bl;
21734 $p2x = $x00+$d1+$brbgBL_H; $p2c2x = $p2x - ($d1+$brbgBL_H)*$mag; // control point only matches p4 preceding
21735 $p2y = $y00+$h00;
21736 $p3x = $x00; $p3c2x = $p3x + $bl/2;
21737 $p3y = $y00+$h00-$d1-$brbgBL_V; $p3c1y = $p3y + ($d1+$brbgBL_V)*$mag;
21738 $p4x = $x00+$bl;
21739 $p4y = $y00+$h00-$d1-$brbgBL_V; $p4c2y = $p4y + ($d2+$brbgBL_V)*$mag;
21740 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21741 $p1x = $x00+$bl; $p1c2x = $p1x;
21742 $p2x = $x00+$bl; $p2c2x = $p2x - $bl*$mag2;
21743 $p3y = $y00+$h00-$bl; $p3c1y = $p3y + $bl*$mag2;
21744 $p4y = $y00+$h00-$bl; $p4c2y = $p4y;
21745 }
21746
21747 $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);
21748 $patch_array[4]['f']=2;
21749 $patch_array[4]['points']=array($p2c2x,$p2y,
21750 $p3x,$p3c1y, $p3x,$p3y, $p3c2x,$p3y,
21751 $p4x,$p4y, $p4x,$p4y, $p4x,$p4c2y,
21752 $p1c2x,$p1y);
21753 $patch_array[4]['colors'] = array($col2,$col1);
21754
21755
21756 // LEFT - joins on the right (C3-C4 of previous): f = 2
21757 $p1x = $x00; // control point only matches p3 preceding
21758 $p1y = $y00+$h00-$d1-$brbgBL_V;
21759 $p2x = $x00+$bl; // control point only matches p4 preceding
21760 $p2y = $y00+$h00-$d1-$brbgBL_V;
21761 $p3x = $x00+$bl;
21762 $p3y = $y00+$d1+$brbgTL_V;
21763 $p4x = $x00; $p4c1x = $p4x + $bl/2;
21764 $p4y = $y00+$d1+$brbgTL_V;
21765 if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
21766 $p1y = $y00+$h00-$bl;
21767 $p2y = $y00+$h00-$bl;
21768 }
21769 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21770 $p3y = $y00+$bl;
21771 $p4y = $y00+$bl;
21772 }
21773
21774 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21775 $patch_array[5]['f']=2;
21776 $patch_array[5]['points']=array($p2x,$p2y,
21777 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21778 $p4c1x,$p4y, $p4x,$p4y, $p4x,$p4y,
21779 $p1x,$p1y);
21780 $patch_array[5]['colors'] = array($col1,$col2);
21781
21782 // TOP LEFT corner
21783 $p1x = $x00+$bl; // control points only matches p3 preceding
21784 $p1y = $y00+$d1+$brbgTL_V; $p1c2y = $p1y - ($d2+$brbgTL_V)*$mag;
21785 $p2x = $x00; // control point only matches p4 preceding
21786 $p2y = $y00+$d1+$brbgTL_V; $p2c2y = $p2y - ($d1+$brbgTL_V)*$mag;
21787 $p3x = $x00+$d1+$brbgTL_H; $p3c1x = $p3x - ($d1+$brbgTL_H)*$mag;
21788 $p3y = $y00; $p3c2y = $p3y + $bl/2;
21789 $p4x = $x00+$d1+$brbgTL_H; $p4c2x = $p4x - ($d2+$brbgTL_H)*$mag;
21790 $p4y = $y00+$bl;
21791
21792 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21793 $p1y = $y00+$bl; $p1c2y = $p1y;
21794 $p2y = $y00+$bl; $p2c2y = $p2y - $bl*$mag2;
21795 $p3x = $x00+$bl; $p3c1x = $p3x - $bl*$mag2;
21796 $p4x = $x00+$bl; $p4c2x = $p4x ;
21797 }
21798
21799 $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);
21800 $patch_array[6]['f']=2;
21801 $patch_array[6]['points']=array($p2x,$p2c2y,
21802 $p3c1x,$p3y, $p3x,$p3y, $p3x,$p3c2y,
21803 $p4x,$p4y, $p4x,$p4y, $p4c2x,$p4y,
21804 $p1x,$p1c2y);
21805 $patch_array[6]['colors'] = array($col2,$col1);
21806
21807
21808 // TOP - joins on the right (C3-C4 of previous): f = 2
21809 $p1x = $x00+$d1+$brbgTL_H; // control point only matches p3 preceding
21810 $p1y = $y00;
21811 $p2x = $x00+$d1+$brbgTL_H; // control point only matches p4 preceding
21812 $p2y = $y00+$bl;
21813 $p3x = $x00+$w00-$d1-$brbgTR_H;
21814 $p3y = $y00+$bl;
21815 $p4x = $x00+$w00-$d1-$brbgTR_H;
21816 $p4y = $y00; $p4c1y = $p4y + $bl/2;
21817 if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
21818 $p1x = $x00+$bl;
21819 $p2x = $x00+$bl;
21820 }
21821 if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
21822 $p3x = $x00+$w00-$bl;
21823 $p4x = $x00+$w00-$bl;
21824 }
21825
21826 $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
21827 $patch_array[7]['f']=2;
21828 $patch_array[7]['points']=array($p2x,$p2y,
21829 $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
21830 $p4x,$p4c1y, $p4x,$p4y, $p4x,$p4y,
21831 $p1x,$p1y);
21832 $patch_array[7]['colors'] = array($col1,$col2);
21833
21834 $shadow .= ' h f Q '."\n"; // Close path and Fill the inner solid shadow
21835
21836 if ($bl) $shadow .= $this->grad->CoonsPatchMesh($x00,$y00,$w00,$h00,$patch_array,$x00,$x00+$w00,$y00,$y00+$h00, $colspace, true);
21837
21838 if ($sh['x'] || $sh['y']) $shadow .= ' Q'."\n"; // Shadow Offset
21839 $shadow .= ' Q'."\n"; // Ends path no-op & Sets the clipping path
21840
21841 }
21842 }
21843
21844 $s .= ' W n '; // Ends path no-op & Sets the clipping path
21845
21846 if ($this->blk[$blvl]['bgcolor']) {
21847 $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
21848 }
21849 else if ($shadow) {
21850 $this->pageBackgrounds[$blvl][] = array('shadowonly'=>true, 'col'=>'', 'clippath'=>'', 'visibility'=>$this->visibility, 'shadow'=>$shadow, 'z-index'=>$this->current_layer); // mPDF 5.6.01
21851 }
21852
21853 /*-- BACKGROUNDS --*/
21854 if (isset($this->blk[$blvl]['gradient'])) {
21855 $g = $this->grad->parseBackgroundGradient($this->blk[$blvl]['gradient']);
21856 if ($g) {
21857 $gx = $x0;
21858 $gy = $y0;
21859 $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
21860 }
21861 }
21862 if (isset($this->blk[$blvl]['background-image'])) {
21863 if ($this->blk[$blvl]['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->blk[$blvl]['background-image']['gradient'] )) {
21864 $g = $this->grad->parseMozGradient( $this->blk[$blvl]['background-image']['gradient'] );
21865 if ($g) {
21866 $gx = $x0;
21867 $gy = $y0;
21868 // mPDF 5.6.11
21869 // origin specifies the background-positioning-area (bpa)
21870 if ($this->blk[$blvl]['background-image']['origin'] == 'padding-box') {
21871 $gx += $this->blk[$blvl]['border_left']['w'];
21872 $w -= ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['border_right']['w']);
21873 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21874 $gy += $this->blk[$blvl]['border_top']['w'];
21875 }
21876 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21877 $gy1 = $y1 - $this->blk[$blvl]['border_bottom']['w'];
21878 }
21879 else { $gy1 = $y1; }
21880 $h = $gy1 - $gy;
21881 }
21882 else if ($this->blk[$blvl]['background-image']['origin'] == 'content-box') {
21883 $gx += $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
21884 $w -= ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right']);
21885 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21886 $gy += $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
21887 }
21888 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21889 $gy1 = $y1 - ($this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']);
21890 }
21891 else { $gy1 = $y1 - $this->blk[$blvl]['padding_bottom']; }
21892 $h = $gy1 - $gy;
21893 }
21894
21895 if (isset($this->blk[$blvl]['background-image']['size']['w']) && $this->blk[$blvl]['background-image']['size']['w']) {
21896 $size = $this->blk[$blvl]['background-image']['size'];
21897 if ($size['w']!='contain' && $size['w']!='cover') {
21898 if (stristr($size['w'] ,'%')) {
21899 $size['w'] += 0;
21900 $size['w'] /= 100;
21901 $w *= $size['w'];
21902 }
21903 else if ($size['w']!='auto') {
21904 $w = $size['w'];
21905 }
21906 if (stristr($size['h'] ,'%')) {
21907 $size['h'] += 0;
21908 $size['h'] /= 100;
21909 $h *= $size['h'];
21910 }
21911 else if ($size['h']!='auto') {
21912 $h = $size['h'];
21913 }
21914 }
21915 }
21916 $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
21917 }
21918 }
21919 else {
21920 $image_id = $this->blk[$blvl]['background-image']['image_id'];
21921 $orig_w = $this->blk[$blvl]['background-image']['orig_w'];
21922 $orig_h = $this->blk[$blvl]['background-image']['orig_h'];
21923 $x_pos = $this->blk[$blvl]['background-image']['x_pos'];
21924 $y_pos = $this->blk[$blvl]['background-image']['y_pos'];
21925 $x_repeat = $this->blk[$blvl]['background-image']['x_repeat'];
21926 $y_repeat = $this->blk[$blvl]['background-image']['y_repeat'];
21927 $resize = $this->blk[$blvl]['background-image']['resize'];
21928 $opacity = $this->blk[$blvl]['background-image']['opacity'];
21929 $itype = $this->blk[$blvl]['background-image']['itype'];
21930 $size = $this->blk[$blvl]['background-image']['size']; // mPDF 5.6.10
21931 // mPDF 5.6.10
21932 // origin specifies the background-positioning-area (bpa)
21933 $bpa = array('x'=>$x0, 'y'=>$y0, 'w'=>$w, 'h'=>$h);
21934 if ($this->blk[$blvl]['background-image']['origin'] == 'padding-box') {
21935 $bpa['x'] = $x0 + $this->blk[$blvl]['border_left']['w'];
21936 $bpa['w'] = $w - ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['border_right']['w']);
21937 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21938 $bpa['y'] = $y0 + $this->blk[$blvl]['border_top']['w'];
21939 }
21940 else { $bpa['y'] = $y0; }
21941 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21942 $bpay = $y1 - $this->blk[$blvl]['border_bottom']['w'];
21943 }
21944 else { $bpay = $y1; }
21945 $bpa['h'] = $bpay - $bpa['y'];
21946 }
21947 // mPDF 5.6.09
21948 else if ($this->blk[$blvl]['background-image']['origin'] == 'content-box') {
21949 $bpa['x'] = $x0 + $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
21950 $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']);
21951 if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
21952 $bpa['y'] = $y0 + $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
21953 }
21954 else { $bpa['y'] = $y0 + $this->blk[$blvl]['padding_top']; }
21955 if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
21956 $bpay = $y1 - ($this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']);
21957 }
21958 else { $bpay = $y1 - $this->blk[$blvl]['padding_bottom']; }
21959 $bpa['h'] = $bpay - $bpa['y'];
21960 }
21961 $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
21962 }
21963 }
21964 /*-- END BACKGROUNDS --*/
21965
21966 // Float DIV
21967 $this->blk[$blvl]['bb_painted'][$this->page] = true;
21968
21969 }
21970
21971 /*-- BORDER-RADIUS --*/
21972
21973 function _EllipseArc($x0, $y0, $rx, $ry, $seg = 1, $part=false, $start=false) { // Anticlockwise segment 1-4 TR-TL-BL-BR (part=1 or 2)
21974 $s = '';
21975 if ($rx<0) { $rx = 0; }
21976 if ($ry<0) { $ry = 0; }
21977 $rx *= _MPDFK;
21978 $ry *= _MPDFK;
21979 $astart = 0;
21980 if ($seg == 1) { // Top Right
21981 $afinish = 90;
21982 $nSeg = 4;
21983 }
21984 else if ($seg == 2) { // Top Left
21985 $afinish = 180;
21986 $nSeg = 8;
21987 }
21988 else if ($seg == 3) { // Bottom Left
21989 $afinish = 270;
21990 $nSeg = 12;
21991 }
21992 else { // Bottom Right
21993 $afinish = 360;
21994 $nSeg = 16;
21995 }
21996 $astart = deg2rad((float) $astart);
21997 $afinish = deg2rad((float) $afinish);
21998 $totalAngle = $afinish - $astart;
21999 $dt = $totalAngle / $nSeg; // segment angle
22000 $dtm = $dt/3;
22001 $x0 *= _MPDFK;
22002 $y0 = ($this->h - $y0) * _MPDFK;
22003 $t1 = $astart;
22004 $a0 = $x0 + ($rx * cos($t1));
22005 $b0 = $y0 + ($ry * sin($t1));
22006 $c0 = -$rx * sin($t1);
22007 $d0 = $ry * cos($t1);
22008 $op = false;
22009 for ($i = 1; $i <= $nSeg; $i++) {
22010 // Draw this bit of the total curve
22011 $t1 = ($i * $dt) + $astart;
22012 $a1 = $x0 + ($rx * cos($t1));
22013 $b1 = $y0 + ($ry * sin($t1));
22014 $c1 = -$rx * sin($t1);
22015 $d1 = $ry * cos($t1);
22016 if ($i>($nSeg-4) && (!$part || ($part == 1 && $i<=$nSeg-2) || ($part == 2 && $i>$nSeg-2))) {
22017 if ($start && !$op) {
22018 $s .= sprintf('%.3F %.3F m ', $a0, $b0);
22019 }
22020 $s .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($a0 + ($c0 * $dtm)), ($b0 + ($d0 * $dtm)), ($a1 - ($c1 * $dtm)) , ($b1 - ($d1 * $dtm)), $a1 , $b1 );
22021 $op = true;
22022 }
22023 $a0 = $a1;
22024 $b0 = $b1;
22025 $c0 = $c1;
22026 $d0 = $d1;
22027 }
22028 return $s;
22029 }
22030 /*-- END BORDER-RADIUS --*/
22031
22032
22033
22034 function PaintDivLnBorder($state=0,$blvl=0,$h) {
22035 // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
22036 $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y + $h;
22037
22038 $save_y = $this->y;
22039
22040 $w = $this->blk[$blvl]['width'];
22041 $x0 = $this->x; // left
22042 $y0 = $this->y; // top
22043 $x1 = $this->x + $w; // bottom
22044 $y1 = $this->y + $h; // bottom
22045
22046 if ($this->blk[$blvl]['border_top'] && ($state==1 || $state==3)) {
22047 $tbd = $this->blk[$blvl]['border_top'];
22048 if (isset($tbd['s']) && $tbd['s']) {
22049 $this->_setBorderLine($tbd);
22050 $this->y = $y0 + ($tbd['w']/2);
22051 // mPDF 5.6.56
22052 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
22053 $this->_setDashBorder($tbd['style'],'',$continuingpage,'T');
22054 $this->Line($x0 + ($tbd['w']/2) , $this->y , $x0 + $w - ($tbd['w']/2), $this->y);
22055 }
22056 else {
22057 $this->SetLineJoin(0);
22058 $this->SetLineCap(0);
22059 $this->Line($x0, $this->y , $x0 + $w, $this->y);
22060 }
22061 $this->y += $tbd['w'];
22062 // Reset Corners and Dash off
22063 $this->SetLineJoin(2);
22064 $this->SetLineCap(2);
22065 $this->SetDash();
22066 }
22067 }
22068 if ($this->blk[$blvl]['border_left']) {
22069 $tbd = $this->blk[$blvl]['border_left'];
22070 if (isset($tbd['s']) && $tbd['s']) {
22071 $this->_setBorderLine($tbd);
22072 // mPDF 5.6.56
22073 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
22074 $this->y = $y0 + ($tbd['w']/2);
22075 $this->_setDashBorder($tbd['style'],'',$continuingpage,'L');
22076 $this->Line($x0 + ($tbd['w']/2), $this->y, $x0 + ($tbd['w']/2), $y0 + $h -($tbd['w']/2));
22077 }
22078 else {
22079 $this->y = $y0;
22080 $this->SetLineJoin(0);
22081 $this->SetLineCap(0);
22082 $this->Line($x0 + ($tbd['w']/2), $this->y, $x0 + ($tbd['w']/2), $y0 + $h);
22083 }
22084 $this->y += $tbd['w'];
22085 // Reset Corners and Dash off
22086 $this->SetLineJoin(2);
22087 $this->SetLineCap(2);
22088 $this->SetDash();
22089 }
22090 }
22091 if ($this->blk[$blvl]['border_right']) {
22092 $tbd = $this->blk[$blvl]['border_right'];
22093 if (isset($tbd['s']) && $tbd['s']) {
22094 $this->_setBorderLine($tbd);
22095 // mPDF 5.6.56
22096 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
22097 $this->y = $y0 + ($tbd['w']/2);
22098 $this->_setDashBorder($tbd['style'],'',$continuingpage,'R');
22099 $this->Line($x0 + $w - ($tbd['w']/2), $this->y, $x0 + $w - ($tbd['w']/2), $y0 + $h - ($tbd['w']/2));
22100 }
22101 else {
22102 $this->y = $y0;
22103 $this->SetLineJoin(0);
22104 $this->SetLineCap(0);
22105 $this->Line($x0 + $w - ($tbd['w']/2), $this->y, $x0 + $w - ($tbd['w']/2), $y0 + $h);
22106 }
22107 $this->y += $tbd['w'];
22108 // Reset Corners and Dash off
22109 $this->SetLineJoin(2);
22110 $this->SetLineCap(2);
22111 $this->SetDash();
22112 }
22113 }
22114 if ($this->blk[$blvl]['border_bottom'] && $state > 1) {
22115 $tbd = $this->blk[$blvl]['border_bottom'];
22116 if (isset($tbd['s']) && $tbd['s']) {
22117 $this->_setBorderLine($tbd);
22118 $this->y = $y0 + $h - ($tbd['w']/2);
22119 // mPDF 5.6.56
22120 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
22121 $this->_setDashBorder($tbd['style'],'',$continuingpage,'B');
22122 $this->Line($x0 + ($tbd['w']/2) , $this->y, $x0 + $w - ($tbd['w']/2), $this->y);
22123 }
22124 else {
22125 $this->SetLineJoin(0);
22126 $this->SetLineCap(0);
22127 $this->Line($x0, $this->y, $x0 + $w, $this->y);
22128 }
22129 $this->y += $tbd['w'];
22130 // Reset Corners and Dash off
22131 $this->SetLineJoin(2);
22132 $this->SetLineCap(2);
22133 $this->SetDash();
22134 }
22135 }
22136 $this->SetDash();
22137 $this->y = $save_y;
22138 }
22139
22140
22141 function PaintImgBorder($objattr,$is_table) {
22142 // Borders are disabled in columns - messes up the repositioning in printcolumnbuffer
22143 if ($this->ColActive) { return ; } // *COLUMNS*
22144 if ($is_table) { $k = $this->shrin_k; } else { $k = 1; }
22145 $h = (isset($objattr['BORDER-HEIGHT']) ? $objattr['BORDER-HEIGHT'] : 0);
22146 $w = (isset($objattr['BORDER-WIDTH']) ? $objattr['BORDER-WIDTH'] : 0);
22147 $x0 = (isset($objattr['BORDER-X']) ? $objattr['BORDER-X'] : 0);
22148 $y0 = (isset($objattr['BORDER-Y']) ? $objattr['BORDER-Y'] : 0);
22149
22150 // BORDERS
22151 if ($objattr['border_top']) {
22152 $tbd = $objattr['border_top'];
22153 if (!empty($tbd['s'])) {
22154 $this->_setBorderLine($tbd,$k);
22155 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','T'); }
22156 $this->Line($x0, $y0, $x0 + $w, $y0);
22157 // Reset Corners and Dash off
22158 $this->SetLineJoin(2);
22159 $this->SetLineCap(2);
22160 $this->SetDash();
22161 }
22162 }
22163 if ($objattr['border_left']) {
22164 $tbd = $objattr['border_left'];
22165 if (!empty($tbd['s'])) {
22166 $this->_setBorderLine($tbd,$k);
22167 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','L'); }
22168 $this->Line($x0, $y0, $x0, $y0 + $h);
22169 // Reset Corners and Dash off
22170 $this->SetLineJoin(2);
22171 $this->SetLineCap(2);
22172 $this->SetDash();
22173 }
22174 }
22175 if ($objattr['border_right']) {
22176 $tbd = $objattr['border_right'];
22177 if (!empty($tbd['s'])) {
22178 $this->_setBorderLine($tbd,$k);
22179 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','R'); }
22180 $this->Line($x0 + $w, $y0, $x0 + $w, $y0 + $h);
22181 // Reset Corners and Dash off
22182 $this->SetLineJoin(2);
22183 $this->SetLineCap(2);
22184 $this->SetDash();
22185 }
22186 }
22187 if ($objattr['border_bottom']) {
22188 $tbd = $objattr['border_bottom'];
22189 if (!empty($tbd['s'])) {
22190 $this->_setBorderLine($tbd,$k);
22191 if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','B'); }
22192 $this->Line($x0, $y0 + $h, $x0 + $w, $y0 + $h);
22193 // Reset Corners and Dash off
22194 $this->SetLineJoin(2);
22195 $this->SetLineCap(2);
22196 $this->SetDash();
22197 }
22198 }
22199 $this->SetDash();
22200 $this->SetAlpha(1);
22201 }
22202
22203 /*-- END HTML-CSS --*/
22204
22205
22206
22207
22208 function Reset() {
22209 $this->SetTColor($this->ConvertColor(0));
22210 $this->SetDColor($this->ConvertColor(0));
22211 $this->SetFColor($this->ConvertColor(255));
22212 $this->SetAlpha(1);
22213 $this->colorarray = '';
22214
22215 $this->spanbgcolorarray = '';
22216 $this->spanbgcolor = false;
22217 $this->spanborder = false;
22218 $this->spanborddet = array();
22219
22220 $this->ResetStyles();
22221
22222 $this->HREF = '';
22223 $this->textparam = array();
22224 $this->SetTextOutline();
22225
22226 $this->SUP = false;
22227 $this->SUB = false;
22228 $this->strike = false;
22229 $this->textshadow = '';
22230
22231 $this->SetFont($this->default_font,'',0,false);
22232 $this->SetFontSize($this->default_font_size,false);
22233
22234 $this->currentfontfamily = '';
22235 $this->currentfontsize = '';
22236
22237 /*-- TABLES --*/
22238 if ($this->tableLevel) {
22239 $this->SetLineHeight('',$this->table_lineheight); // *TABLES*
22240 }
22241 else
22242 /*-- END TABLES --*/
22243 /*-- LISTS --*/
22244
22245 if ($this->listlvl && $this->list_lineheight[$this->listlvl][$this->bulletarray['occur']]) {
22246 $this->SetLineHeight('',$this->list_lineheight[$this->listlvl][$this->bulletarray['occur']]); // sets default line height
22247 }
22248 else
22249 /*-- END LISTS --*/
22250 if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
22251 $this->SetLineHeight('',$this->blk[$this->blklvl]['line_height']); // sets default line height
22252 }
22253
22254 $this->toupper = false;
22255 $this->tolower = false;
22256 $this->kerning = false;
22257 $this->lSpacingCSS = '';
22258 $this->wSpacingCSS = '';
22259 $this->fixedlSpacing = false;
22260 $this->minwSpacing = 0;
22261 $this->capitalize = false;
22262 $this->SetDash(); //restore to no dash
22263 $this->dash_on = false;
22264 $this->dotted_on = false;
22265 $this->divwidth = 0;
22266 $this->divheight = 0;
22267 $this->divalign = '';
22268 $this->divrevert = false;
22269 $this->oldy = -1;
22270
22271 $bodystyle = array();
22272 if (isset($this->cssmgr->CSS['BODY']['FONT-STYLE'])) { $bodystyle['FONT-STYLE'] = $this->cssmgr->CSS['BODY']['FONT-STYLE']; }
22273 if (isset($this->cssmgr->CSS['BODY']['FONT-WEIGHT'])) { $bodystyle['FONT-WEIGHT'] = $this->cssmgr->CSS['BODY']['FONT-WEIGHT']; }
22274 if (isset($this->cssmgr->CSS['BODY']['COLOR'])) { $bodystyle['COLOR'] = $this->cssmgr->CSS['BODY']['COLOR']; }
22275 if (isset($bodystyle)) { $this->setCSS($bodystyle,'BLOCK','BODY'); }
22276
22277 }
22278
22279 /*-- HTML-CSS --*/
22280 function ReadMetaTags($html) {
22281 // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)
22282 $regexp = '/ (\\w+?)=([^\\s>"]+)/si';
22283 $html = preg_replace($regexp," \$1=\"\$2\"",$html);
22284 if (preg_match('/<title>(.*?)<\/title>/si',$html,$m)) {
22285 $this->SetTitle($m[1]);
22286 }
22287 preg_match_all('/<meta [^>]*?(name|content)="([^>]*?)" [^>]*?(name|content)="([^>]*?)".*?>/si',$html,$aux);
22288 $firstattr = $aux[1];
22289 $secondattr = $aux[3];
22290 for( $i = 0 ; $i < count($aux[0]) ; $i++) {
22291
22292 $name = ( strtoupper($firstattr[$i]) == "NAME" )? strtoupper($aux[2][$i]) : strtoupper($aux[4][$i]);
22293 $content = ( strtoupper($firstattr[$i]) == "CONTENT" )? $aux[2][$i] : $aux[4][$i];
22294 switch($name) {
22295 case "KEYWORDS": $this->SetKeywords($content); break;
22296 case "AUTHOR": $this->SetAuthor($content); break;
22297 case "DESCRIPTION": $this->SetSubject($content); break;
22298 }
22299 }
22300 }
22301
22302
22303 function ReadCharset($html) {
22304 // Charset conversion
22305 if ($this->allow_charset_conversion) {
22306 if (preg_match('/<head.*charset=([^\'\"\s]*).*<\/head>/si',$html,$m)) {
22307 if (strtoupper($m[1]) != 'UTF-8') {
22308 $this->charset_in = strtoupper($m[1]);
22309 }
22310 }
22311 }
22312 }
22313
22314 function setCSS($arrayaux,$type='',$tag='') { // type= INLINE | BLOCK | LIST // tag= BODY
22315 if (!is_array($arrayaux)) return; //Removes PHP Warning
22316 // mPDF 5.7.3 inline text-decoration parameters
22317 $preceeding_fontkey = $this->FontFamily . $this->FontStyle;
22318 $preceeding_fontsize = $this->FontSize;
22319
22320 // Set font size first so that e.g. MARGIN 0.83em works on font size for this element
22321 if (isset($arrayaux['FONT-SIZE'])) {
22322 $v = $arrayaux['FONT-SIZE'];
22323 if(is_numeric($v[0])) {
22324 if ($type == 'BLOCK' && $this->blklvl>0 && isset($this->blk[$this->blklvl-1]['InlineProperties']) && isset($this->blk[$this->blklvl-1]['InlineProperties']['size'])) {
22325 $mmsize = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['InlineProperties']['size']);
22326 }
22327 else {
22328 $mmsize = $this->ConvertSize($v,$this->FontSize);
22329 }
22330 $this->SetFontSize( $mmsize*(_MPDFK),false ); //Get size in points (pt)
22331 }
22332 else{
22333 $v = strtoupper($v);
22334 if (isset($this->fontsizes[$v])) {
22335 $this->SetFontSize( $this->fontsizes[$v]* $this->default_font_size,false);
22336 }
22337 }
22338 if ($tag == 'BODY') { $this->SetDefaultFontSize($this->FontSizePt); }
22339 }
22340
22341
22342 if ($this->useLang && !$this->usingCoreFont) {
22343 if (isset($arrayaux['LANG']) && $arrayaux['LANG'] && $arrayaux['LANG'] != $this->default_lang && ((strlen($arrayaux['LANG']) == 5 && $arrayaux['LANG'] != 'UTF-8') || strlen($arrayaux['LANG']) == 2)) {
22344 list ($coreSuitable,$mpdf_pdf_unifonts) = GetLangOpts($arrayaux['LANG'], $this->useAdobeCJK);
22345 if ($mpdf_pdf_unifonts) { $this->RestrictUnicodeFonts($mpdf_pdf_unifonts); }
22346 else { $this->RestrictUnicodeFonts($this->default_available_fonts ); }
22347 if ($tag == 'BODY') {
22348 $this->currentLang = $arrayaux['LANG'];
22349 $this->default_lang = $arrayaux['LANG'];
22350 if ($mpdf_pdf_unifonts) { $this->default_available_fonts = $mpdf_pdf_unifonts; }
22351 }
22352 }
22353 else {
22354 $this->RestrictUnicodeFonts($this->default_available_fonts );
22355 }
22356 }
22357
22358 // FOR INLINE and BLOCK OR 'BODY'
22359 if (isset($arrayaux['FONT-FAMILY'])) {
22360 $v = $arrayaux['FONT-FAMILY'];
22361 //If it is a font list, get all font types
22362 $aux_fontlist = explode(",",$v);
22363 $found = 0;
22364 foreach($aux_fontlist AS $f) {
22365 $fonttype = trim($f);
22366 $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype);
22367 $fonttype = preg_replace('/ /','',$fonttype);
22368 $v = strtolower(trim($fonttype));
22369 if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) { $v = $this->fonttrans[$v]; }
22370 if ((!$this->onlyCoreFonts && in_array($v,$this->available_unifonts)) ||
22371 in_array($v,array('ccourier','ctimes','chelvetica')) ||
22372 ($this->onlyCoreFonts && in_array($v,array('courier','times','helvetica','arial'))) ||
22373 in_array($v, array('sjis','uhc','big5','gb'))) {
22374 $fonttype = $v;
22375 $found = 1;
22376 break;
22377 }
22378 }
22379 if (!$found) {
22380 foreach($aux_fontlist AS $f) {
22381 $fonttype = trim($f);
22382 $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype);
22383 $fonttype = preg_replace('/ /','',$fonttype);
22384 $v = strtolower(trim($fonttype));
22385 if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) { $v = $this->fonttrans[$v]; }
22386 if (in_array($v,$this->sans_fonts) || in_array($v,$this->serif_fonts) || in_array($v,$this->mono_fonts) ) {
22387 $fonttype = $v;
22388 break;
22389 }
22390 }
22391 }
22392
22393 if ($tag == 'BODY') {
22394 $this->SetDefaultFont($fonttype);
22395 }
22396 $this->SetFont($fonttype,$this->currentfontstyle,0,false);
22397 }
22398 else {
22399 $this->SetFont($this->currentfontfamily,$this->currentfontstyle,0,false);
22400 }
22401
22402 foreach($arrayaux as $k => $v) {
22403 if ($type != 'INLINE' && $tag != 'BODY' && $type != 'LIST') {
22404 switch($k){
22405 // BORDERS
22406 case 'BORDER-TOP':
22407 $this->blk[$this->blklvl]['border_top'] = $this->border_details($v);
22408 if ($this->blk[$this->blklvl]['border_top']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22409 break;
22410 case 'BORDER-BOTTOM':
22411 $this->blk[$this->blklvl]['border_bottom'] = $this->border_details($v);
22412 if ($this->blk[$this->blklvl]['border_bottom']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22413 break;
22414 case 'BORDER-LEFT':
22415 $this->blk[$this->blklvl]['border_left'] = $this->border_details($v);
22416 if ($this->blk[$this->blklvl]['border_left']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22417 break;
22418 case 'BORDER-RIGHT':
22419 $this->blk[$this->blklvl]['border_right'] = $this->border_details($v);
22420 if ($this->blk[$this->blklvl]['border_right']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
22421 break;
22422
22423 // PADDING
22424 case 'PADDING-TOP':
22425 $this->blk[$this->blklvl]['padding_top'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22426 break;
22427 case 'PADDING-BOTTOM':
22428 $this->blk[$this->blklvl]['padding_bottom'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22429 break;
22430 case 'PADDING-LEFT':
22431 $this->blk[$this->blklvl]['padding_left'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22432 break;
22433 case 'PADDING-RIGHT':
22434 $this->blk[$this->blklvl]['padding_right'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22435 break;
22436
22437 // MARGINS
22438 case 'MARGIN-TOP':
22439 $tmp = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22440 if (isset($this->blk[$this->blklvl]['lastbottommargin'])) {
22441 if ($tmp > $this->blk[$this->blklvl]['lastbottommargin']) {
22442 $tmp -= $this->blk[$this->blklvl]['lastbottommargin'];
22443 }
22444 else {
22445 $tmp = 0;
22446 }
22447 }
22448 $this->blk[$this->blklvl]['margin_top'] = $tmp;
22449 break;
22450 case 'MARGIN-BOTTOM':
22451 $this->blk[$this->blklvl]['margin_bottom'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22452 break;
22453 case 'MARGIN-LEFT':
22454 $this->blk[$this->blklvl]['margin_left'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22455 break;
22456 case 'MARGIN-RIGHT':
22457 $this->blk[$this->blklvl]['margin_right'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22458 break;
22459
22460 /*-- BORDER-RADIUS --*/
22461 case 'BORDER-TOP-LEFT-RADIUS-H':
22462 $this->blk[$this->blklvl]['border_radius_TL_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22463 break;
22464 case 'BORDER-TOP-LEFT-RADIUS-V':
22465 $this->blk[$this->blklvl]['border_radius_TL_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22466 break;
22467 case 'BORDER-TOP-RIGHT-RADIUS-H':
22468 $this->blk[$this->blklvl]['border_radius_TR_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22469 break;
22470 case 'BORDER-TOP-RIGHT-RADIUS-V':
22471 $this->blk[$this->blklvl]['border_radius_TR_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22472 break;
22473 case 'BORDER-BOTTOM-LEFT-RADIUS-H':
22474 $this->blk[$this->blklvl]['border_radius_BL_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22475 break;
22476 case 'BORDER-BOTTOM-LEFT-RADIUS-V':
22477 $this->blk[$this->blklvl]['border_radius_BL_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22478 break;
22479 case 'BORDER-BOTTOM-RIGHT-RADIUS-H':
22480 $this->blk[$this->blklvl]['border_radius_BR_H'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22481 break;
22482 case 'BORDER-BOTTOM-RIGHT-RADIUS-V':
22483 $this->blk[$this->blklvl]['border_radius_BR_V'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22484 break;
22485 /*-- END BORDER-RADIUS --*/
22486
22487 case 'BOX-SHADOW':
22488 $bs = $this->cssmgr->setCSSboxshadow($v);
22489 if ($bs) { $this->blk[$this->blklvl]['box_shadow'] = $bs; }
22490 break;
22491
22492 case 'BACKGROUND-CLIP':
22493 if (strtoupper($v) == 'PADDING-BOX') { $this->blk[$this->blklvl]['background_clip'] = 'padding-box'; }
22494 else if (strtoupper($v) == 'CONTENT-BOX') { $this->blk[$this->blklvl]['background_clip'] = 'content-box'; } // mPDF 5.6.09
22495 break;
22496
22497 case 'PAGE-BREAK-AFTER':
22498 if (strtoupper($v) == 'AVOID') { $this->blk[$this->blklvl]['page_break_after_avoid'] = true; }
22499 else if (strtoupper($v) == 'ALWAYS' || strtoupper($v) == 'LEFT' || strtoupper($v) == 'RIGHT') { $this->blk[$this->blklvl]['page_break_after'] = strtoupper($v) ; }
22500 break;
22501
22502 case 'WIDTH':
22503 if (strtoupper($v) != 'AUTO') {
22504 $this->blk[$this->blklvl]['css_set_width'] = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['inner_width'],$this->FontSize,false);
22505 }
22506 break;
22507
22508 case 'TEXT-INDENT':
22509 // Left as raw value (may include 1% or 2em)
22510 $this->blk[$this->blklvl]['text_indent'] = $v;
22511 break;
22512
22513 }//end of switch($k)
22514 }
22515
22516
22517 if ($type != 'INLINE' && $type != 'LIST') { // includes BODY tag
22518 switch($k){
22519
22520 case 'MARGIN-COLLAPSE': // Custom tag to collapse margins at top and bottom of page
22521 if (strtoupper($v) == 'COLLAPSE') { $this->blk[$this->blklvl]['margin_collapse'] = true; }
22522 break;
22523
22524 case 'LINE-HEIGHT':
22525 $this->blk[$this->blklvl]['line_height'] = $this->fixLineheight($v);
22526 if (!$this->blk[$this->blklvl]['line_height'] ) { $this->blk[$this->blklvl]['line_height'] = $this->normalLineheight; }
22527 break;
22528
22529 case 'TEXT-ALIGN': //left right center justify
22530 switch (strtoupper($v)) {
22531 case 'LEFT':
22532 $this->blk[$this->blklvl]['align']="L";
22533 break;
22534 case 'CENTER':
22535 $this->blk[$this->blklvl]['align']="C";
22536 break;
22537 case 'RIGHT':
22538 $this->blk[$this->blklvl]['align']="R";
22539 break;
22540 case 'JUSTIFY':
22541 $this->blk[$this->blklvl]['align']="J";
22542 break;
22543 }
22544 break;
22545
22546 /*-- BACKGROUNDS --*/
22547 case 'BACKGROUND-GRADIENT':
22548 if ($type == 'BLOCK') {
22549 $this->blk[$this->blklvl]['gradient'] = $v;
22550 }
22551 break;
22552 /*-- END BACKGROUNDS --*/
22553
22554 case 'DIRECTION':
22555 if ($v) { $this->blk[$this->blklvl]['direction'] = strtolower($v); }
22556 break;
22557
22558 }//end of switch($k)
22559 }
22560
22561 // FOR INLINE ONLY
22562 if ($type == 'INLINE' || $type == 'LIST') {
22563 switch($k){
22564 case 'DISPLAY': // Custom tag to collapse margins at top and bottom of page
22565 if (strtoupper($v) == 'NONE') { $this->inlineDisplayOff = true; }
22566 break;
22567 case 'DIRECTION':
22568 break;
22569 }//end of switch($k)
22570 }
22571 // FOR INLINE ONLY
22572 if ($type == 'INLINE') {
22573 switch($k){
22574 // BORDERS
22575 case 'BORDER-TOP':
22576 $this->spanborddet['T'] = $this->border_details($v);
22577 $this->spanborder = true;
22578 break;
22579 case 'BORDER-BOTTOM':
22580 $this->spanborddet['B'] = $this->border_details($v);
22581 $this->spanborder = true;
22582 break;
22583 case 'BORDER-LEFT':
22584 $this->spanborddet['L'] = $this->border_details($v);
22585 $this->spanborder = true;
22586 break;
22587 case 'BORDER-RIGHT':
22588 $this->spanborddet['R'] = $this->border_details($v);
22589 $this->spanborder = true;
22590 break;
22591 // mPDF 5.6.26
22592 case 'VISIBILITY': // block is set in OpenTag
22593 $v = strtolower($v);
22594 if ($v == 'visible' || $v == 'hidden' || $v == 'printonly' || $v == 'screenonly') {
22595 $this->textparam['visibility'] = $v;
22596 }
22597 break;
22598 }//end of switch($k)
22599 }
22600
22601
22602 // FOR INLINE and BLOCK
22603 switch($k){
22604 case 'TEXT-ALIGN': //left right center justify
22605 if (strtoupper($v) == 'NOJUSTIFY' && $this->blk[$this->blklvl]['align']=="J") {
22606 $this->blk[$this->blklvl]['align']="";
22607 }
22608 break;
22609 // bgcolor only - to stay consistent with original html2fpdf
22610 case 'BACKGROUND':
22611 case 'BACKGROUND-COLOR':
22612 $cor = $this->ConvertColor($v);
22613 if ($cor) {
22614 if ($tag == 'BODY') {
22615 $this->bodyBackgroundColor = $cor;
22616 }
22617 else if ($type == 'INLINE' || $type == 'LIST') {
22618 $this->spanbgcolorarray = $cor;
22619 $this->spanbgcolor = true;
22620 }
22621 else {
22622 $this->blk[$this->blklvl]['bgcolorarray'] = $cor;
22623 $this->blk[$this->blklvl]['bgcolor'] = true;
22624 }
22625 }
22626 else if ($type != 'INLINE' && $type != 'LIST') {
22627 if ($this->ColActive || $this->keep_block_together) {
22628 $this->blk[$this->blklvl]['bgcolorarray'] = $this->blk[$this->blklvl-1]['bgcolorarray'] ;
22629 $this->blk[$this->blklvl]['bgcolor'] = $this->blk[$this->blklvl-1]['bgcolor'] ;
22630 }
22631 }
22632 break;
22633
22634 // auto | normal | none
22635 case 'FONT-KERNING':
22636 if ((strtoupper($v) == 'NORMAL' || strtoupper($v) == 'AUTO') && $this->useKerning) { $this->kerning = true; }
22637 else if (strtoupper($v) == 'NONE') { $this->kerning = false; }
22638 break;
22639
22640
22641 // normal | <length>
22642 case 'LETTER-SPACING':
22643 $this->lSpacingCSS = $v;
22644 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
22645 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
22646 }
22647 break;
22648
22649 // normal | <length>
22650 case 'WORD-SPACING':
22651 $this->wSpacingCSS = $v;
22652 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
22653 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
22654 }
22655 break;
22656
22657 case 'FONT-STYLE': // italic normal oblique
22658 switch (strtoupper($v)) {
22659 case 'ITALIC':
22660 case 'OBLIQUE':
22661 $this->SetStyle('I',true);
22662 break;
22663 case 'NORMAL':
22664 $this->SetStyle('I',false);
22665 break;
22666 }
22667 break;
22668
22669 case 'FONT-WEIGHT': // normal bold //Does not support: bolder, lighter, 100..900(step value=100)
22670 switch (strtoupper($v)) {
22671 case 'BOLD':
22672 $this->SetStyle('B',true);
22673 break;
22674 case 'NORMAL':
22675 $this->SetStyle('B',false);
22676 break;
22677 }
22678 break;
22679
22680 case 'VERTICAL-ALIGN': //super and sub only dealt with here e.g. <SUB> and <SUP>
22681 switch (strtoupper($v)) {
22682 case 'SUPER':
22683 $this->SUP=true;
22684 $this->SUB=false; // mPDF 5.6.07
22685 // mPDF 5.7.3 inline text-decoration parameters
22686 if (isset($this->textparam['text-baseline'])) { $this->textparam['text-baseline'] += ($this->baselineSup)*$preceeding_fontsize; }
22687 else { $this->textparam['text-baseline'] = ($this->baselineSup)*$preceeding_fontsize; }
22688 break;
22689 case 'SUB':
22690 $this->SUB=true;
22691 $this->SUP=false; // mPDF 5.6.07
22692 // mPDF 5.7.3 inline text-decoration parameters
22693 if (isset($this->textparam['text-baseline'])) { $this->textparam['text-baseline'] += ($this->baselineSub)*$preceeding_fontsize; }
22694 else { $this->textparam['text-baseline'] = ($this->baselineSub)*$preceeding_fontsize; }
22695 break;
22696 case 'BASELINE': // mPDF 5.6.07
22697 $this->SUB=false;
22698 $this->SUP=false;
22699 // mPDF 5.7.3 inline text-decoration parameters
22700 if (isset($this->textparam['text-baseline'])) { unset($this->textparam['text-baseline']); }
22701 break;
22702 // mPDF 5.7.3 inline text-decoration parameters
22703 default:
22704 $lh = $this->_computeLineheight($this->blk[$this->blklvl]['line_height']);
22705 $sz = $this->ConvertSize($v,$lh,$this->FontSize,false);
22706 $this->SUP=false;
22707 $this->SUB=false;
22708 if ($sz) {
22709 if ($sz > 0) {
22710 $this->SUP=true;
22711 }
22712 else {
22713 $this->SUB=true;
22714 }
22715 if (isset($this->textparam['text-baseline'])) { $this->textparam['text-baseline'] += $sz; }
22716 else { $this->textparam['text-baseline'] = $sz; }
22717 }
22718 }
22719 break;
22720
22721 case 'FONT-VARIANT':
22722 switch (strtoupper($v)) {
22723 case 'SMALL-CAPS':
22724 $this->SetStyle('S',true);
22725 break;
22726 case 'NORMAL':
22727 $this->SetStyle('S',false);
22728 break;
22729 }
22730 break;
22731
22732 case 'TEXT-TRANSFORM': // none uppercase lowercase //Does support: capitalize
22733 switch (strtoupper($v)) { //Not working 100%
22734 case 'CAPITALIZE':
22735 $this->capitalize=true;
22736 break;
22737 case 'UPPERCASE':
22738 $this->toupper=true;
22739 break;
22740 case 'LOWERCASE':
22741 $this->tolower=true;
22742 break;
22743 case 'NONE': break;
22744 }
22745 break;
22746
22747 case 'TEXT-SHADOW':
22748 $ts = $this->cssmgr->setCSStextshadow($v);
22749 if ($ts) { $this->textshadow = $ts; }
22750 break;
22751
22752 case 'HYPHENS': // mPDF 5.6.08
22753 if (strtoupper($v)=='NONE') {
22754 $this->textparam['hyphens'] = 2;
22755 }
22756 else if (strtoupper($v)=='AUTO') {
22757 $this->textparam['hyphens'] = 1;
22758 }
22759 else if (strtoupper($v)=='MANUAL') {
22760 $this->textparam['hyphens'] = 0;
22761 }
22762 break;
22763
22764 case 'TEXT-OUTLINE': // mPDF 5.6.07
22765 if (strtoupper($v)=='NONE') {
22766 $this->textparam['outline-s'] = false;
22767 }
22768 break;
22769
22770 case 'TEXT-OUTLINE-WIDTH': // mPDF 5.6.07
22771 case 'OUTLINE-WIDTH':
22772 switch(strtoupper($v)) {
22773 case 'THIN': $v = '0.03em'; break;
22774 case 'MEDIUM': $v = '0.05em'; break;
22775 case 'THICK': $v = '0.07em'; break;
22776 }
22777 $w = $this->ConvertSize($v,$this->blk[$this->blklvl]['inner_width'],$this->FontSize);
22778 if ($w) {
22779 $this->textparam['outline-WIDTH'] = $w;
22780 $this->textparam['outline-s'] = true;
22781 }
22782 else { $this->textparam['outline-s'] = false; }
22783 break;
22784
22785 case 'TEXT-OUTLINE-COLOR': // mPDF 5.6.07
22786 case 'OUTLINE-COLOR':
22787 if (strtoupper($v) == 'INVERT') {
22788 if ($this->colorarray) {
22789 $cor = $this->colorarray;
22790 $this->textparam['outline-COLOR'] = $this->_invertColor($cor);
22791 }
22792 else {
22793 $this->textparam['outline-COLOR'] = $this->ConvertColor(255);
22794 }
22795 }
22796 else {
22797 $cor = $this->ConvertColor($v);
22798 if ($cor) { $this->textparam['outline-COLOR'] = $cor ; }
22799 }
22800 break;
22801
22802 case 'COLOR': // font color
22803 $cor = $this->ConvertColor($v);
22804 if ($cor) {
22805 $this->colorarray = $cor;
22806 $this->SetTColor($cor);
22807 }
22808 break;
22809
22810
22811 }//end of switch($k)
22812
22813
22814 }//end of foreach
22815
22816
22817 // mPDF 5.7.3 inline text-decoration parameters
22818 // Needs to be set at the end - after vertical-align = super/sub, so that textparam['text-baseline'] is set
22819 if (isset($arrayaux['TEXT-DECORATION'])) {
22820 $v = $arrayaux['TEXT-DECORATION']; // none underline line-through (strikeout) //Does not support: overline, blink
22821 if (stristr($v,'LINE-THROUGH')) {
22822 $this->strike = true;
22823 // mPDF 5.7.3 inline text-decoration parameters
22824 if (isset($this->textparam['text-baseline'])) { $this->textparam['s-decoration']['baseline'] = $this->textparam['text-baseline']; }
22825 else { $this->textparam['s-decoration']['baseline'] = 0; }
22826 $this->textparam['s-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle;
22827 $this->textparam['s-decoration']['fontsize'] = $this->FontSize;
22828 $this->textparam['s-decoration']['color'] = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
22829 }
22830 if (stristr($v,'UNDERLINE')) {
22831 $this->SetStyle('U',true);
22832 // mPDF 5.7.3 inline text-decoration parameters
22833 if (isset($this->textparam['text-baseline'])) { $this->textparam['u-decoration']['baseline'] = $this->textparam['text-baseline']; }
22834 else { $this->textparam['u-decoration']['baseline'] = 0; }
22835 $this->textparam['u-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle;
22836 $this->textparam['u-decoration']['fontsize'] = $this->FontSize;
22837 $this->textparam['u-decoration']['color'] = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
22838 }
22839 if (stristr($v,'NONE')) {
22840 $this->SetStyle('U',false);
22841 $this->strike = false;
22842 // mPDF 5.7.3 inline text-decoration parameters
22843 if (isset($this->textparam['u-decoration'])) { unset($this->textparam['u-decoration']); }
22844 if (isset($this->textparam['s-decoration'])) { unset($this->textparam['s-decoration']); }
22845 }
22846 }
22847
22848 }
22849
22850 /*-- END HTML-CSS --*/
22851
22852
22853 function SetStyle($tag,$enable) {
22854 $this->$tag=$enable;
22855 $style='';
22856 foreach(array('B','I','U','S') as $s) {
22857 if($this->$s) {
22858 $style.=$s;
22859 }
22860 }
22861 if ($this->S && empty($this->upperCase)) { @include(_MPDF_PATH.'includes/upperCase.php'); }
22862 $this->currentfontstyle=$style;
22863 $this->SetFont('',$style,0,false);
22864 }
22865
22866 // Set multiple styles at one $str e.g. "BIS"
22867 function SetStylesArray($arr) {
22868 $style='';
22869 foreach(array('B','I','U','S') as $s) {
22870 if (isset($arr[$s])) {
22871 if ($arr[$s]) {
22872 $this->$s = true;
22873 $style.=$s;
22874 }
22875 else { $this->$s = false; }
22876 }
22877 else if ($this->$s) { $style.=$s; }
22878 }
22879 $this->currentfontstyle=$style;
22880 $this->SetFont('',$style,0,false);
22881 }
22882
22883 // Set multiple styles at one $str e.g. "BIS"
22884 function SetStyles($str) {
22885 $style='';
22886 foreach(array('B','I','U','S') as $s) {
22887 if (strpos($str,$s) !== false) {
22888 $this->$s = true;
22889 $style.=$s;
22890 }
22891 else { $this->$s = false; }
22892 }
22893 $this->currentfontstyle=$style;
22894 $this->SetFont('',$style,0,false);
22895 }
22896
22897 function ResetStyles() {
22898 foreach(array('B','I','U','S') as $s) {
22899 $this->$s = false;
22900 }
22901 $this->currentfontstyle='';
22902 $this->SetFont('','',0,false);
22903 }
22904
22905
22906 function DisableTags($str='')
22907 {
22908 if ($str == '') //enable all tags
22909 {
22910 //Insert new supported tags in the long string below.
22911 $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><main><details><summary><meter><progress><time>"; // mPDF 5.7.3
22912 }
22913 else
22914 {
22915 $str = explode(",",$str);
22916 foreach($str as $v) $this->enabledtags = str_replace(trim($v),'',$this->enabledtags);
22917 }
22918 }
22919
22920
22921 /*-- TABLES --*/
22922
22923 function finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight) {
22924 $af = 0; // Above font
22925 $bf = 0; // Below font
22926 $mta = 0; // Maximum top-aligned
22927 $mba = 0; // Maximum bottom-aligned
22928 if ($lhxt['BS']) {
22929 $af = max($af, ($lhxt['BS'] - ($maxfontsize * (0.5 + $this->baselineC))));
22930 }
22931 if ($lhxt['M']) {
22932 $af = max($af, ($lhxt['M'] - $maxfontsize)/2);
22933 $bf = max($bf, ($lhxt['M'] - $maxfontsize)/2);
22934 }
22935 if ($lhxt['TT']) {
22936 $bf = max($bf, ($lhxt['TT'] - $maxfontsize));
22937 }
22938 if ($lhxt['TB']) {
22939 $af = max($af, ($lhxt['TB'] - $maxfontsize));
22940 }
22941 if ($lhxt['T']) {
22942 $mta = max($mta, $lhxt['T']);
22943 }
22944 if ($lhxt['B']) {
22945 $mba = max($mba, $lhxt['B']);
22946 }
22947 if ((!$lhfixed || !$forceExactLineheight) && ($af > (($maxlineHeight - $maxfontsize)/2) || $bf > (($maxlineHeight - $maxfontsize)/2))) {
22948 $maxlineHeight = $maxfontsize + $af + $bf;
22949 }
22950 else if (!$lhfixed) { $af = $bf = ($maxlineHeight - $maxfontsize)/2; }
22951 if ($mta > $maxlineHeight) {
22952 $bf += ($mta - $maxlineHeight);
22953 $maxlineHeight = $mta;
22954 }
22955 if ($mba > $maxlineHeight) {
22956 $af += ($mba - $maxlineHeight);
22957 $maxlineHeight = $mba;
22958 }
22959 return $maxlineHeight;
22960 }
22961
22962 function TableWordWrap($maxwidth, $forcewrap = 0, $textbuffer = '', $def_fontsize, $returnarray=false) { // NB ** returnarray used in flowchart
22963 $biggestword=0;
22964 $toonarrow=false;
22965
22966 $textbuffer[0][0] = preg_replace('/^[ ]*/','',$textbuffer[0][0]);
22967 if ((count($textbuffer) == 0) or ((count($textbuffer) == 1) && ($textbuffer[0][0] == ''))) { return 0; }
22968
22969 $text = '';
22970 $lhfixed = false;
22971 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight)) { $lhfixed = true; }
22972 if ($lhfixed) { $def_lineheight = $this->_computeLineheight($this->table_lineheight, $def_fontsize);}
22973 else { $def_lineheight = 0; }
22974
22975
22976 // START OF NEW LINE
22977 // Initialise lineheight variables
22978 $maxfontsize = 0;
22979 $forceExactLineheight = true;
22980 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
22981 $maxlineHeight = $def_lineheight ;
22982 $ch = 0;
22983 $width = 0;
22984 $ln = 1; // Counts line number
22985 $mxw = $this->GetCharWidth('W',false);
22986 for($cctr=0;$cctr<count($textbuffer);$cctr++) { // mPDF 5.6.22
22987 $chunk = $textbuffer[$cctr]; // mPDF 5.6.22
22988 $line = $chunk[0];
22989 //IMAGE
22990 if (substr($line,0,3) == "\xbb\xa4\xac") { //identifier has been identified!
22991 $objattr = $this->_getObjAttr($line);
22992 if ($objattr['type'] == 'nestedtable') {
22993 // END OF LINE
22994 // Finalise & add lineheight
22995 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
22996 $level = $objattr['level'];
22997 $ih = $this->table[($level+1)][$objattr['nestedcontent']]['h']; // nested table width
22998 $ch += $ih;
22999 // START OF NEW LINE
23000 // Initialise lineheight variables
23001 $ln++;
23002 $maxfontsize = 0;
23003 $forceExactLineheight = true;
23004 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
23005 $maxlineHeight = $def_lineheight ;
23006 $width = 0;
23007 $text = "";
23008 continue;
23009 }
23010
23011 list($skipln,$iw,$ih) = $this->inlineObject((isset($specialcontent['type']) ? $specialcontent['type'] : null),0,0, $objattr, $this->lMargin,$width,$maxwidth,$maxlineHeight,false,true);
23012 if ($objattr['type'] == 'hr') {
23013 // END OF LINE
23014 // Finalise & add lineheight
23015 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23016 // Add HR height
23017 $ch += $ih;
23018 // START OF NEW LINE
23019 // Initialise lineheight variables
23020 $ln++;
23021 $maxfontsize = 0;
23022 $forceExactLineheight = true;
23023 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
23024 $maxlineHeight = $def_lineheight ;
23025 $width = 0;
23026 $text = "";
23027 continue;
23028 }
23029
23030 if ($skipln==1 || $skipln==-2) {
23031 // Finish last line
23032 // END OF LINE
23033 // Finalise & add lineheight
23034 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23035 // START OF NEW LINE
23036 // Initialise lineheight variables
23037 $maxfontsize = 0;
23038 $forceExactLineheight = true;
23039 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
23040 $maxlineHeight = $def_lineheight ;
23041 $ln++;
23042 $width = 0;
23043 $text = "";
23044 }
23045 $va = (isset($objattr['vertical-align']) ? $objattr['vertical-align'] : null);
23046 if ($va) {
23047 $lhxt[$va] = max($lhxt[$va], $ih);
23048 }
23049 if ($lhfixed && $ih > $def_fontsize) { $forceExactLineheight = false; }
23050 $maxlineHeight = max($maxlineHeight ,$ih);
23051 $width += $iw;
23052 continue;
23053 }
23054
23055 // SET FONT SIZE/STYLE from $chunk[n]
23056 // FONTSIZE
23057 if(isset($chunk[11]) and $chunk[11] != '') {
23058 if ($this->shrin_k) {
23059 $this->SetFontSize($chunk[11]/$this->shrin_k,false);
23060 }
23061 else {
23062 $this->SetFontSize($chunk[11],false);
23063 }
23064 }
23065 if ($line == "\n") {
23066 // END OF LINE
23067 $maxfontsize = max($maxfontsize,$this->FontSize);
23068 $fh = $this->_computeLineheight($this->table_lineheight);
23069 if ($lhfixed && $this->FontSize > $def_fontsize) {
23070 $fh = $this->FontSize;
23071 $forceExactLineheight = false;
23072 }
23073 $maxlineHeight = max($maxlineHeight,$fh);
23074
23075 // Finalise & add lineheight
23076 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23077 // START OF NEW LINE
23078 // Initialise lineheight variables
23079 $maxfontsize = 0;
23080 $forceExactLineheight = true;
23081 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
23082 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
23083 $ln++;
23084 $text = "";
23085 $width = 0;
23086 if(isset($chunk[11]) and $chunk[11] != '') {
23087 $this->SetFontSize($this->default_font_size,false);
23088 }
23089 continue;
23090 }
23091
23092 $lbw = $rbw = 0; // Border widths
23093 if(isset($chunk[16]) && !empty($chunk[16])) { //Border
23094 $this->spanborddet = $chunk[16];
23095 if (isset($this->spanborddet['L'])) $lbw = $this->spanborddet['L']['w'];
23096 if (isset($this->spanborddet['R'])) $rbw = $this->spanborddet['R']['w'];
23097 }
23098 if(isset($chunk[15])) { // Word spacing
23099 $this->wSpacingCSS = $chunk[15];
23100 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
23101 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize)/$this->shrin_k; // mPDF 5.7.3
23102 }
23103 }
23104 if(isset($chunk[14])) { // Letter spacing
23105 $this->lSpacingCSS = $chunk[14];
23106 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
23107 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize)/$this->shrin_k; // mPDF 5.7.3
23108 }
23109 }
23110 if(isset($chunk[13])) { // Font Kerning
23111 $this->kerning = $chunk[13];
23112 }
23113 if(isset($chunk[9])) { // Text params - Outline, hyphens // mPDF 5.6.08
23114 $this->textparam = $chunk[9];
23115 }
23116 // FONTFAMILY
23117 if(isset($chunk[4]) and $chunk[4] != '') { $font = $this->SetFont($chunk[4],$this->FontStyle,0,false); }
23118
23119 // FONT STYLE B I U
23120 if(isset($chunk[2]) and $chunk[2] != '') {
23121 $this->SetStyles($chunk[2]);
23122 }
23123
23124 $space = $this->GetCharWidth(' ',false);
23125
23126 if (mb_substr($line,0,1,$this->mb_enc ) == ' ') { // line (chunk) starts with a space
23127 $width += $space;
23128 $text .= ' ';
23129 }
23130
23131 if (mb_substr($line,(mb_strlen($line,$this->mb_enc )-1),1,$this->mb_enc ) == ' ') { $lsend = true; } // line (chunk) ends with a space
23132 else { $lsend = false; }
23133 $line= trim($line);
23134 if ($line == '') { continue; }
23135
23136 // mPDF ITERATION
23137 if ($this->iterationCounter) $line = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/','\\1', $line);
23138
23139 $words = explode(' ', $line);
23140
23141 foreach ($words as $k=>$word) {
23142 $word = trim($word);
23143 $wordwidth = $this->GetStringWidth($word);
23144 if ($k==0) { $wordwidth += $lbw; }
23145 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
23146 //maxwidth is insufficient for one word
23147 if ($wordwidth > $maxwidth + 0.0001) {
23148 $firstchunk=true;
23149 while($wordwidth > $maxwidth + 0.0001) {
23150 $chw = 0; // check width
23151 $oneCJKorphan = false;
23152 $mlen = mb_strlen($word, $this->mb_enc );
23153 for ( $i = 0; $i < $mlen; $i++ ) {
23154 $chw = $this->GetStringWidth(mb_substr($word,0,$i+1,$this->mb_enc ));
23155 if ($k==0) { $chw += $lbw; }
23156 if ($k==(count($words)-1)) { $chw += $rbw; }
23157 if ($chw > $maxwidth) {
23158 if ($i==0 && $firstchunk) {
23159 // If first letter of line does not fit
23160 $wordwidth = $maxwidth - 0.0001;
23161 if ($this->debug) { $this->Error("Table cell width calculated less than that needed for one character!"); }
23162 break;
23163 }
23164 /*-- CJK-FONTS --*/
23165 // mPDF 5.6.40 mPDF 5.6.44
23166 if ($this->checkCJK && !$this->usingCoreFont && preg_match("/[".$this->pregCJKchars."]/u", $word)) { // mPDF 5.6.44
23167 if (!$oneCJKorphan && preg_match('/['.$this->CJKoverflow.']$/u',mb_substr($word,0,$i+1,$this->mb_enc )) && $this->allowCJKorphans) {
23168 $wordwidth = $maxwidth - 0.0001;
23169 $oneCJKorphan = true;
23170 continue;
23171 }
23172 $cjkfix = 0;
23173 // Last character that fits is not allowed to end a line - move lastchar(s) to start of next line
23174 if ($i>0 && preg_match("/[".$this->CJKleading."$]/u", mb_substr($word,0,$i,$this->mb_enc ))) {
23175 $cjkfix = 1;
23176 }
23177 // Next character is not allowed to start a new line
23178 else if (preg_match("/[".$this->CJKfollowing."]/u", mb_substr($word,$i,1,$this->mb_enc ))) {
23179 // try squeezing another character(s) onto this line = Oikomi
23180 if ($this->allowCJKorphans && !$oneCJKorphan) {
23181 //if lookahead is not another following char
23182 if ($i==($mlen-1) || ($i<($mlen-1) && !preg_match("/[".$this->CJKfollowing."]/u", mb_substr($word,$i+1,1,$this->mb_enc )))) {
23183 $wordwidth = $maxwidth - 0.0001;
23184 $oneCJKorphan = true;
23185 continue;
23186 }
23187 }
23188 // or move lastchar(s) to next line
23189 $cjkfix = 2;
23190 }
23191 // mPDF 5.6.42
23192 // CJK numerals kept together
23193 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 ))) {
23194 $cjkfix = 3;
23195 }
23196 if ($cjkfix) {
23197 //move lastchar(s) to next line
23198 $m0 = mb_substr($word,$i-1,1,$this->mb_enc ); // chars to move
23199 $m1 = mb_substr($word,0,$i-1,$this->mb_enc ); // str after stripped chars to move
23200 $mi = $i - 1;
23201 if ($cjkfix == 3) { $match = "0-9\x{ff10}-\x{ff19}"; }
23202 else { $match = $this->CJKleading; }
23203 while(preg_match("/[".$match."$]/u", $m1) && mb_strlen($m1, $this->mb_enc)>2) {
23204 $m0 = mb_substr($m1,$mi-1,1,$this->mb_enc ).$m0; // chars to move
23205 $m1 = mb_substr($m1,0,$mi-1,$this->mb_enc ); // str after stripped chars to move
23206 $mi--;
23207 }
23208 // Insert $m0 into $word at $i
23209 $word = mb_substr($word,0,$i,$this->mb_enc ) . $m0 . mb_substr($word,$i,mb_strlen($word, $this->mb_enc )-$i,$this->mb_enc );
23210 $mlen = mb_strlen($word, $this->mb_enc ); // increment max for loop counter
23211 }
23212
23213
23214
23215 }
23216 /*-- END CJK-FONTS --*/
23217
23218 if ($text && $firstchunk) {
23219 // END OF LINE
23220 // Finalise & add lineheight
23221 $maxfontsize = max($maxfontsize,$this->FontSize);
23222 $fh = $this->_computeLineheight($this->table_lineheight);
23223 if ($lhfixed && $this->FontSize > $def_fontsize) {
23224 $fh = $this->FontSize;
23225 $forceExactLineheight = false;
23226 }
23227 $maxlineHeight = max($maxlineHeight,$fh);
23228 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23229 // START OF NEW LINE
23230 // Initialise lineheight variables
23231 $maxfontsize = $this->FontSize;
23232 $forceExactLineheight = true;
23233 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
23234 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
23235 $ln++;
23236 }
23237 // END OF LINE
23238 // Finalise & add lineheight
23239 $maxfontsize = max($maxfontsize,$this->FontSize);
23240 $fh = $this->_computeLineheight($this->table_lineheight);
23241 if ($lhfixed && $this->FontSize > $def_fontsize) {
23242 $fh = $this->FontSize;
23243 $forceExactLineheight = false;
23244 }
23245 $maxlineHeight = max($maxlineHeight,$fh);
23246 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23247 // START OF NEW LINE
23248 // Initialise lineheight variables
23249 $maxfontsize = $this->FontSize;
23250 $forceExactLineheight = true;
23251 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
23252 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
23253 $ln++;
23254 $mxw = $maxwidth;
23255 $text = mb_substr($word,0,$i,$this->mb_enc );
23256 $word = mb_substr($word,$i,mb_strlen($word, $this->mb_enc )-$i,$this->mb_enc );
23257 $wordwidth = $this->GetStringWidth($word);
23258 $width = 0;
23259 $firstchunk=false;
23260 break;
23261 }
23262 }
23263 if (mb_strlen($word, $this->mb_enc )<2 && $wordwidth > $maxwidth + 0.0001) {
23264 $wordwidth = $maxwidth - 0.0001;
23265 if ($this->debug) { $this->Error("Table cell width calculated less than that needed for single character!"); }
23266 }
23267 $firstchunk=false;
23268 }
23269 }
23270 // Word fits on line...
23271 if ($width + $wordwidth < $maxwidth + 0.0001) {
23272 $mxw = max($mxw, ($width+$wordwidth));
23273 $width += $wordwidth + $space;
23274 $text .= $word.' ';
23275 }
23276 // Word does not fit on line...
23277 else {
23278 // mPDF 5.6.21 hard hyphens
23279 if ($this->textparam['hyphens'] != 2 && preg_match('/\-/',$word)) {
23280 list($hardsuccess,$pre,$post,$prelength) = $this->hardHyphenate($word, ($maxwidth - $width)-$this->GetCharWidth("-", false));
23281 if ($hardsuccess) {
23282 $text .= $pre.'-';
23283 $word = $post;
23284 $wordwidth = $this->GetStringWidth($word);
23285 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
23286 }
23287 }
23288 /*-- HYPHENATION --*/
23289 // Soft Hyphens chr(173)
23290 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
23291 list($success,$pre,$post,$prelength) = $this->softHyphenate($word, ($maxwidth - $width));
23292 if ($success) {
23293 $text .= $pre.'-';
23294 $word = $post;
23295 $wordwidth = $this->GetStringWidth($word);
23296 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
23297 }
23298 }
23299 else if ($this->textparam['hyphens'] == 1) { // mPDF 5.6.06 5.6.08
23300 list($success,$pre,$post,$prelength) = $this->hyphenateWord($word, ($maxwidth - $width));
23301 if ($success) {
23302 $text .= $pre.'-';
23303 $word = $post;
23304 $wordwidth = $this->GetStringWidth($word);
23305 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
23306 }
23307 }
23308 /*-- END HYPHENATION --*/
23309
23310
23311 // mPDF 5.6.22
23312 if ( count($textbuffer)>1 && $cctr > 0 && $k==0
23313 && (substr($textbuffer[$cctr][0],0,3) != "\xbb\xa4\xac")
23314 && (substr($textbuffer[$cctr-1][0],0,3) != "\xbb\xa4\xac")
23315 && substr($textbuffer[$cctr-1][0],-1,1) != ' '
23316 && substr($textbuffer[$cctr][0],0,1) != ' '
23317 ) {
23318 // Go back to find a space in a previous chunk of content
23319 $found = false;
23320 for ($ix=$cctr-1;$ix>=0;$ix--) {
23321 if (preg_match('/[ ]/',$textbuffer[$ix][0])) { $found = $ix; break; }
23322 }
23323 if ($found !== false) {
23324 $charpos = strrpos($textbuffer[$found][0],' ');
23325 // mPDF 5.6.24
23326 $a1 = $a2 = $textbuffer[$found];
23327 $a1[0] = "\n";
23328 $a2[0] = substr($textbuffer[$found][0], $charpos+1, strlen($textbuffer[$found][0])-$charpos);
23329 $textbuffer[$found][0] = substr($textbuffer[$found][0], 0, $charpos);
23330 array_insert($textbuffer, $a1, $found+1);
23331 array_insert($textbuffer, $a2, $found+2);
23332 // Initialise all variables
23333 $biggestword=0;
23334 $toonarrow=false;
23335 $lhfixed = false;
23336 if (preg_match('/([0-9.,]+)mm/',$this->table_lineheight)) { $lhfixed = true; }
23337 if ($lhfixed) { $def_lineheight = $this->_computeLineheight($this->table_lineheight, $def_fontsize);}
23338 else { $def_lineheight = 0; }
23339 $maxfontsize = 0;
23340 $forceExactLineheight = true;
23341 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
23342 $maxlineHeight = $def_lineheight ;
23343 $ch = 0;
23344 $width = 0;
23345 $ln = 1; // Counts line number
23346 $mxw = $this->GetCharWidth('W',false);
23347 $text = '';
23348
23349 $cctr = -1;
23350 break;
23351 }
23352 }
23353
23354 // END OF LINE
23355 // Finalise & add lineheight
23356 $maxfontsize = max($maxfontsize,$this->FontSize);
23357 $fh = $this->_computeLineheight($this->table_lineheight);
23358 if ($lhfixed && $this->FontSize > $def_fontsize) {
23359 $fh = $this->FontSize;
23360 $forceExactLineheight = false;
23361 }
23362 $maxlineHeight = max($maxlineHeight,$fh);
23363 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23364 $mxw = $maxwidth;
23365 // START OF NEW LINE
23366 // Initialise lineheight variables
23367 $maxfontsize = $this->FontSize;
23368 $forceExactLineheight = true;
23369 $lhxt = array('BS'=>0, 'M'=>0, 'TT'=>0, 'TB'=>0, 'T'=>0, 'B'=>0);
23370 $maxlineHeight = $this->_computeLineheight($this->table_lineheight);
23371 $ln++;
23372 $width = $wordwidth + $space;
23373 $text = $word.' ';
23374 }
23375 $maxfontsize = max($maxfontsize,$this->FontSize);
23376 $fh = $this->_computeLineheight($this->table_lineheight);
23377 if ($lhfixed && $this->FontSize > $def_fontsize) {
23378 $fh = $this->FontSize;
23379 $forceExactLineheight = false;
23380 }
23381 $maxlineHeight = max($maxlineHeight,$fh);
23382 }
23383
23384 // End of textbuffer chunk
23385 if (!$lsend) {
23386 $width -= $space;
23387 $text = rtrim($text);
23388 }
23389
23390 // RESET FONT SIZE/STYLE
23391 // RESETTING VALUES
23392 //Now we must deactivate what we have used
23393 if(isset($chunk[2]) and $chunk[2] != '') {
23394 $this->ResetStyles();
23395 }
23396 if(isset($chunk[4]) and $chunk[4] != '') {
23397 $this->SetFont($this->default_font,$this->FontStyle,0,false);
23398 }
23399 if(isset($chunk[11]) and $chunk[11] != '') {
23400 $this->SetFontSize($this->default_font_size,false);
23401 }
23402 $this->spanborddet = array();
23403 $this->kerning = false;
23404 $this->lSpacingCSS = '';
23405 $this->wSpacingCSS = '';
23406 $this->fixedlSpacing = false;
23407 $this->minwSpacing = 0;
23408 }
23409 // Finalise lineheight if something output on line and add
23410 if ($width) {
23411 $ch += $this->finaliseCellLineHeight($lhxt, $maxfontsize, $maxlineHeight, $lhfixed, $forceExactLineheight);
23412 }
23413 if ($returnarray) { return array($ch,$ln,$mxw); }
23414 else { return $ch; }
23415
23416 }
23417
23418
23419 function TableCheckMinWidth($maxwidth, $forcewrap = 0, $textbuffer) {
23420 $biggestword=0;
23421 $toonarrow=false;
23422 if ((count($textbuffer) == 0) or ((count($textbuffer) == 1) && ($textbuffer[0][0] == ''))) { return 0; }
23423
23424 foreach ($textbuffer as $chunk) {
23425
23426 $line = $chunk[0];
23427 // mPDF ITERATION
23428 if ($this->iterationCounter) $line = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/','\\1', $line);
23429
23430 // IMAGES & FORM ELEMENTS
23431 if (substr($line,0,3) == "\xbb\xa4\xac") { //inline object - FORM element or IMAGE!
23432 $objattr = $this->_getObjAttr($line);
23433 if ($objattr['type']!='hr' && isset($objattr['width']) && ($objattr['width']/$this->shrin_k) > ($maxwidth + 0.0001) ) {
23434 if (($objattr['width']/$this->shrin_k) > $biggestword) { $biggestword = ($objattr['width']/$this->shrin_k); }
23435 $toonarrow=true;
23436 }
23437 continue;
23438 }
23439
23440 if ($line == "\n") {
23441 continue;
23442 }
23443 $line = trim($line );
23444 // SET FONT SIZE/STYLE from $chunk[n]
23445
23446 // FONTSIZE
23447 if(isset($chunk[11]) and $chunk[11] != '') {
23448 if ($this->shrin_k) {
23449 $this->SetFontSize($chunk[11]/$this->shrin_k,false);
23450 }
23451 else {
23452 $this->SetFontSize($chunk[11],false);
23453 }
23454 }
23455 // FONTFAMILY
23456 if(isset($chunk[4]) and $chunk[4] != '') { $font = $this->SetFont($chunk[4],$this->FontStyle,0,false); }
23457 // B I U
23458 if(isset($chunk[2]) and $chunk[2] != '') {
23459 $this->SetStyles($chunk[2]);
23460 }
23461
23462 $lbw = $rbw = 0; // Border widths
23463 if(isset($chunk[16]) && !empty($chunk[16])) { //Border
23464 $this->spanborddet = $chunk[16];
23465 $lbw = $this->spanborddet['L']['w'];
23466 $rbw = $this->spanborddet['R']['w'];
23467 }
23468 if(isset($chunk[15])) { // Word spacing
23469 $this->wSpacingCSS = $chunk[15];
23470 if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
23471 $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize)/$this->shrin_k; // mPDF 5.7.3
23472 }
23473 }
23474 if(isset($chunk[14])) { // Letter spacing
23475 $this->lSpacingCSS = $chunk[14];
23476 if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
23477 $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize)/$this->shrin_k; // mPDF 5.7.3
23478 }
23479 }
23480 if(isset($chunk[13])) { // Font Kerning
23481 $this->kerning = $chunk[13];
23482 }
23483
23484 $words = explode(' ', $line);
23485 foreach ($words as $k=>$word) {
23486 $word = trim($word);
23487 $wordwidth = $this->GetStringWidth($word);
23488 if ($k==0) { $wordwidth += $lbw; }
23489 if ($k==(count($words)-1)) { $wordwidth += $rbw; }
23490
23491 //Warn user that maxwidth is insufficient
23492 if ($wordwidth > $maxwidth + 0.0001) {
23493 if ($wordwidth > $biggestword) { $biggestword = $wordwidth; }
23494 $toonarrow=true;
23495 }
23496 }
23497
23498 // RESET FONT SIZE/STYLE
23499 // RESETTING VALUES
23500 //Now we must deactivate what we have used
23501 if(isset($chunk[2]) and $chunk[2] != '') {
23502 $this->ResetStyles();
23503 }
23504 if(isset($chunk[4]) and $chunk[4] != '') {
23505 $this->SetFont($this->default_font,$this->FontStyle,0,false);
23506 }
23507 if(isset($chunk[11]) and $chunk[11] != '') {
23508 $this->SetFontSize($this->default_font_size,false);
23509 }
23510 $this->spanborddet = array();
23511 $this->kerning = false;
23512 $this->lSpacingCSS = '';
23513 $this->wSpacingCSS = '';
23514 $this->fixedlSpacing = false;
23515 $this->minwSpacing = 0;
23516 }
23517
23518 //Return -(wordsize) if word is bigger than maxwidth
23519 // ADDED
23520 if (($toonarrow) && ($this->table_error_report)) {
23521 $this->Error("Word is too long to fit in table - ".$this->table_error_report_param);
23522 }
23523 if ($toonarrow) return -$biggestword;
23524 else return 1;
23525 }
23526
23527 function shrinkTable(&$table,$k) {
23528 $table['border_spacing_H'] /= $k;
23529 $table['border_spacing_V'] /= $k;
23530
23531 $table['padding']['T'] /= $k;
23532 $table['padding']['R'] /= $k;
23533 $table['padding']['B'] /= $k;
23534 $table['padding']['L'] /= $k;
23535
23536 $table['margin']['T'] /= $k;
23537 $table['margin']['R'] /= $k;
23538 $table['margin']['B'] /= $k;
23539 $table['margin']['L'] /= $k;
23540
23541 $table['border_details']['T']['w'] /= $k;
23542 $table['border_details']['R']['w'] /= $k;
23543 $table['border_details']['B']['w'] /= $k;
23544 $table['border_details']['L']['w'] /= $k;
23545
23546 if (isset($table['max_cell_border_width']['T'])) $table['max_cell_border_width']['T'] /= $k;
23547 if (isset($table['max_cell_border_width']['R'])) $table['max_cell_border_width']['R'] /= $k;
23548 if (isset($table['max_cell_border_width']['B'])) $table['max_cell_border_width']['B'] /= $k;
23549 if (isset($table['max_cell_border_width']['L'])) $table['max_cell_border_width']['L'] /= $k;
23550
23551 if ($this->simpleTables){
23552 $table['simple']['border_details']['T']['w'] /= $k;
23553 $table['simple']['border_details']['R']['w'] /= $k;
23554 $table['simple']['border_details']['B']['w'] /= $k;
23555 $table['simple']['border_details']['L']['w'] /= $k;
23556 }
23557
23558 $table['miw'] /= $k;
23559 $table['maw'] /= $k;
23560
23561 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
23562
23563 for($j = 0 ; $j < $table['nc'] ; $j++ ) { //columns
23564
23565 $table['wc'][$j]['miw'] /= $k;
23566 $table['wc'][$j]['maw'] /= $k;
23567
23568 // mPDF 5.6.13
23569 if (isset($table['decimal_align'][$j]['maxs0']) && $table['decimal_align'][$j]['maxs0']) { $table['decimal_align'][$j]['maxs0'] /= $k; }
23570 if (isset($table['decimal_align'][$j]['maxs1']) && $table['decimal_align'][$j]['maxs1']) { $table['decimal_align'][$j]['maxs1'] /= $k; }
23571
23572 if (isset($table['wc'][$j]['absmiw']) && $table['wc'][$j]['absmiw'] ) $table['wc'][$j]['absmiw'] /= $k;
23573
23574 for($i = 0 ; $i < $table['nr']; $i++ ) { //rows
23575 if ($this->cacheTables) {
23576 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
23577 }
23578 else
23579 $c = &$table['cells'][$i][$j];
23580 if (isset($c) && $c) {
23581 if (!$this->simpleTables){
23582 if ($this->packTableData) {
23583 $cell = $this->_unpackCellBorder($c['borderbin'] );
23584 $cell['border_details']['T']['w'] /= $k;
23585 $cell['border_details']['R']['w'] /= $k;
23586 $cell['border_details']['B']['w'] /= $k;
23587 $cell['border_details']['L']['w'] /= $k;
23588 $cell['border_details']['mbw']['TL'] /= $k;
23589 $cell['border_details']['mbw']['TR'] /= $k;
23590 $cell['border_details']['mbw']['BL'] /= $k;
23591 $cell['border_details']['mbw']['BR'] /= $k;
23592 $cell['border_details']['mbw']['LT'] /= $k;
23593 $cell['border_details']['mbw']['LB'] /= $k;
23594 $cell['border_details']['mbw']['RT'] /= $k;
23595 $cell['border_details']['mbw']['RB'] /= $k;
23596 $c['borderbin'] = $this->_packCellBorder($cell);
23597 }
23598 else {
23599 $c['border_details']['T']['w'] /= $k;
23600 $c['border_details']['R']['w'] /= $k;
23601 $c['border_details']['B']['w'] /= $k;
23602 $c['border_details']['L']['w'] /= $k;
23603 $c['border_details']['mbw']['TL'] /= $k;
23604 $c['border_details']['mbw']['TR'] /= $k;
23605 $c['border_details']['mbw']['BL'] /= $k;
23606 $c['border_details']['mbw']['BR'] /= $k;
23607 $c['border_details']['mbw']['LT'] /= $k;
23608 $c['border_details']['mbw']['LB'] /= $k;
23609 $c['border_details']['mbw']['RT'] /= $k;
23610 $c['border_details']['mbw']['RB'] /= $k;
23611 }
23612 }
23613 $c['padding']['T'] /= $k;
23614 $c['padding']['R'] /= $k;
23615 $c['padding']['B'] /= $k;
23616 $c['padding']['L'] /= $k;
23617 $c['maxs'] /= $k;
23618 if (isset($c['w'])) { $c['w'] /= $k; }
23619 $c['s'] /= $k;
23620 $c['maw'] /= $k;
23621 $c['miw'] /= $k;
23622 if (isset($c['h'])) { $c['h'] /= $k; } // mPDF 5.7.4
23623 if (isset($c['absmiw'])) $c['absmiw'] /= $k;
23624 if (isset($c['nestedmaw'])) $c['nestedmaw'] /= $k;
23625 if (isset($c['nestedmiw'])) $c['nestedmiw'] /= $k;
23626 if (isset($c['textbuffer'])) {
23627 foreach($c['textbuffer'] AS $n=>$tb) {
23628 if (!empty($tb[16])) {
23629 $c['textbuffer'][$n][16]['T']['w'] /= $k;
23630 $c['textbuffer'][$n][16]['B']['w'] /= $k;
23631 $c['textbuffer'][$n][16]['L']['w'] /= $k;
23632 $c['textbuffer'][$n][16]['R']['w'] /= $k;
23633 }
23634 }
23635 }
23636 if ($this->cacheTables) {
23637 $this->_cacheCell($c, '', "W", $fh, $table['cells'][$i][$j]);
23638 }
23639 unset($c);
23640 }
23641 }//rows
23642 }//columns
23643 if ($this->cacheTables) { fclose($fh); }
23644 }
23645
23646 function _cacheCell($c, $file, $mode="A", $fh=null, $offset=0) { // mode = Append or (over)Write (needs offset and fh)
23647 // Requires either $file OR $fh (file_handle)
23648 if (!is_array($c) || !isset($c)) { return ''; }
23649
23650 if(isset($c['w'])) { $cw = $c['w']; } else { $cw = -1; }
23651 if(isset($c['w0'])) { $cw0 = $c['w0']; } else { $cw0 = -1; }
23652 if(isset($c['h0'])) { $ch0 = $c['h0']; } else { $ch0 = -1; }
23653
23654 $data = pack("n2d19A1A1n2sA32A128",
23655 $c['colspan'], /* n (16 bit; 2 bytes) [pos 0] */
23656 $c['rowspan'], /* n (16 bit; 2 bytes) [pos 2] */
23657 $c['s'], /* d NB machine-dependent size (64 bit; 8 bytes on test winOS) [pos 4] */
23658 $c['maxs'], /* d NB machine-dependent size [pos 4 + 1*D] */
23659 $c['nestedmaw'], /* d NB machine-dependent size [pos 4 + 2*D] */
23660 $c['nestedmiw'], /* d NB machine-dependent size [pos 4 + 3*D] */
23661 $c['padding']['L'], /* d NB machine-dependent size [pos 4 + 4*D] */
23662 $c['padding']['R'], /* d NB machine-dependent size [pos 4 + 5*D] */
23663 $c['padding']['T'], /* d NB machine-dependent size [pos 4 + 6*D] */
23664 $c['padding']['B'], /* d NB machine-dependent size [pos 4 + 7*D] */
23665 $c['dfs'], /* d NB machine-dependent size [pos 4 + 8*D] */
23666 $cw, /* d NB machine-dependent size [pos 4 + 9*D] */
23667 $c['h'], /* d NB machine-dependent size [pos 4 + 10*D] */
23668 $c['absmiw'], /* d NB machine-dependent size [pos 4 + 11*D] */
23669 $c['maw'], /* d NB machine-dependent size [pos 4 + 12*D] */
23670 $c['miw'], /* d NB machine-dependent size [pos 4 + 13*D] */
23671 $c['mih'], /* d NB machine-dependent size [pos 4 + 14*D] */
23672 $c['x0'], /* d NB machine-dependent size [pos 4 + 15*D] */
23673 $cw0, /* d NB machine-dependent size [pos 4 + 16*D] */
23674 $c['y0'], /* d NB machine-dependent size [pos 4 + 17*D] */
23675 $ch0, /* d NB machine-dependent size [pos 4 + 18*D] */
23676 $c['a'], /* A1 (1 byte) [pos 4 + 19*D] */
23677 $c['va'], /* A1 (1 byte) [pos 5 + 19*D] */
23678 $c['nowrap'], /* 1 or blank n (16 bit; 2 bytes) [pos 6 + 19*D] */
23679 $c['wpercent'], /* 0 - 100 n (16 bit; 2 bytes) [pos 8 + 19*D] */
23680 $c['R'], /* 90 or -90 s (16 bit; 2 bytes) [pos 10 + 19*D] */
23681 $c['bgcolor'], /* A32 (32 bytes) [pos 12 + 19*D] */
23682 $c['gradient'] /* A128 (128 bytes) [pos 44 + 19*D] */
23683 );
23684
23685 if ($c['background-image']) {
23686 $data .= pack("n2d2A6A6n3dA4A128",
23687 strlen($data), /* offset in main data to start of bgimage data */
23688 $c['background-image']['image_id'], /* n */
23689 $c['background-image']['orig_w'], /* d NB machine-dependent size */
23690 $c['background-image']['orig_h'], /* d NB machine-dependent size */
23691 $c['background-image']['x_pos'], /* A6 calc size or "50%" */
23692 $c['background-image']['y_pos'], /* A6 calc size or "50%" */
23693 $c['background-image']['x_repeat'], /* n true or false*/
23694 $c['background-image']['y_repeat'], /* n true or false */
23695 $c['background-image']['resize'], /* n 0 - 6 */
23696 $c['background-image']['opacity'], /* d 0-1 */
23697 $c['background-image']['itype'], /* A4 jpg etc */
23698 $c['background-image']['gradient'] /* A128 CSS string */
23699 );
23700 }
23701 else $data .= pack("n",0);
23702 $tb_offset = 2 + 186 + 2 + strlen($data);
23703 $stb = serialize($c['textbuffer']).' '; // buffer to allow updating in reverseTableDir
23704 $lentb = strlen($stb);
23705 $data2 = pack("nA".$lentb, $lentb, $stb);
23706
23707 $tempfh = true;
23708 if ($mode=="W" && $offset) {
23709 if (!$fh) { $fh = fopen($file, "r+b"); } // Overwrite (but not truncate)
23710 else $tempfh = false;
23711 fseek($fh, $offset);
23712 }
23713 else {
23714 $fh = fopen($file, "ab"); // APPEND
23715 }
23716 fwrite($fh, pack("n",$tb_offset)); // Offset to Text buffer 2 bytes
23717 fwrite($fh, $c['borderbin']); // border details 186 bytes
23718 fwrite($fh, pack("n",strlen($data))); // Length of Main data
23719 fwrite($fh, $data); // Main data
23720 fwrite($fh, $data2); // Text buffer (starts with "n" length of text buffer)
23721 if ($tempfh) fclose($fh);
23722 return ($tb_offset + 2 + $lentb);
23723 }
23724
23725 function _cacheUpdateTxB($c, $fh, $offset) {
23726 fseek($fh, $offset);
23727 $tb_offset = $this->read_short($fh); // First entry = Offset to Text buffer 2 bytes
23728 fseek($fh, ($tb_offset-2), SEEK_CUR);
23729 $lentb = $this->read_short($fh); // First entry in textbuffer = Length of serialized textbuffer - do not update
23730 $stb = serialize($c['textbuffer']);
23731 fwrite($fh, pack("A".$lentb, $stb));
23732 }
23733
23734 function _cacheUpdateBorder($c, $fh, $offset) {
23735 $offset += 2;
23736 fseek($fh, $offset);
23737 fwrite($fh, $c['borderbin']);
23738 }
23739
23740 function _cacheUpdateMtx($c, $fh, $offset, $var) {
23741 if ($var=='mih') { $offset += (2 + 186 + 2 + 4 + 14*_DSIZE); }
23742 else if ($var=='x0') { $offset += (2 + 186 + 2 + 4 + 15*_DSIZE); } // x0 and w0
23743 else if ($var=='y0') { $offset += (2 + 186 + 2 + 4 + 17*_DSIZE); } // y0 and h0
23744 fseek($fh, $offset);
23745 if ($var=='mih') { fwrite($fh, pack("d",$c['mih'])); }
23746 else if ($var=='x0') { fwrite($fh, pack("d2",$c['x0'],$c['w0'])); }
23747 else if ($var=='y0') { fwrite($fh, pack("d2",$c['y0'],$c['h0'])); }
23748 }
23749
23750 function _uncacheCell($ptr, $file, $fh) {
23751 // Requires either $file or $fh (file_handle)
23752 if ($ptr==0) { return null; }
23753 if (is_array($ptr)) { $this->Error("Probable cause - missing end tag &lt;/td&gt;. You may be able to change the configurable variable: allow_html_optional_endtags "); }
23754 $tempfh = true;
23755 if (!$fh) { $fh = fopen($file, "rb"); }
23756 else $tempfh = false;
23757 fseek($fh, $ptr);
23758 $c = array();
23759 $tb_offset = $this->read_short($fh); // First entry = Offset to Text buffer 2 bytes
23760 $c['borderbin'] = fread($fh,186); // border details 186 bytes
23761 $maindatalen = $this->read_short($fh); // Length of Main data (2 bytes)
23762 $str = fread($fh,$maindatalen ); // Main data
23763 $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);
23764
23765 if ($data['colspan']>0) $c['colspan'] = $data['colspan']; /* n */
23766 if ($data['rowspan']>0) $c['rowspan'] = $data['rowspan']; /* n */
23767 $c['s'] = $data['s']; /* d NB machine-dependent size */
23768 $c['maxs'] = $data['maxs']; /* d NB machine-dependent size */
23769 if ($data['nmaw']>0) $c['nestedmaw'] = $data['nmaw']; /* d NB machine-dependent size */
23770 if ($data['nmiw']>0) $c['nestedmiw'] = $data['nmiw']; /* d NB machine-dependent size */
23771 $c['padding']['L'] = $data['pl']; /* d NB machine-dependent size */
23772 $c['padding']['R'] = $data['pr']; /* d NB machine-dependent size */
23773 $c['padding']['T'] = $data['pt']; /* d NB machine-dependent size */
23774 $c['padding']['B'] = $data['pb']; /* d NB machine-dependent size */
23775 $c['dfs'] = $data['dfs']; /* d NB machine-dependent size */
23776 if ($data['w']>=0) $c['w'] = $data['w']; /* d NB machine-dependent size */
23777 if ($data['h']>0) $c['h'] = $data['h']; /* d NB machine-dependent size */
23778 if ($data['absmiw']>0) $c['absmiw'] = $data['absmiw']; /* d NB machine-dependent size */
23779 if ($data['maw']>0) $c['maw'] = $data['maw']; /* d NB machine-dependent size */
23780 if ($data['miw']>0) $c['miw'] = $data['miw']; /* d NB machine-dependent size */
23781 if ($data['mih']>0) $c['mih'] = $data['mih']; /* d NB machine-dependent size */
23782 if ($data['w0']>=0) { $c['w0'] = $data['w0']; /* d NB machine-dependent size */
23783 $c['x0'] = $data['x0']; } /* d NB machine-dependent size */
23784 if ($data['h0']>=0) { $c['h0'] = $data['h0']; /* d NB machine-dependent size */
23785 $c['y0'] = $data['y0']; } /* d NB machine-dependent size */
23786 $c['a'] = trim($data['a']); /* A1 */
23787 $c['va'] = trim($data['va']); /* A1 */
23788 if ($data['nowrap']) $c['nowrap'] = $data['nowrap']; /* 1 or blank n */
23789 else $c['nowrap'] = false;
23790 if ($data['wpercent']>0) $c['wpercent'] = $data['wpercent']; /* 0 - 100 n */
23791 if ($data['R']<>0) $c['R'] = $data['R']; /* 90 or -90 s */
23792 else $c['R'] = false;
23793 $c['bgcolor'] = trim($data['bgcol']); /* A32 */
23794 if (trim($data['grad']))
23795 $c['gradient'] = trim($data['grad']); /* A128 */
23796 else $c['gradient'] = false;
23797 if ($data['bgimage']>0) {
23798 $bgidata = substr($str, ($data['bgimage']+2));
23799 $c['background-image'] = unpack("nimage_id/dorig_w/dorig_h/A6x_pos/A6y_pos/nx_repeat/ny_repeat/nresize/dopacity/A4itype/A128gradient", $bgidata);
23800 }
23801
23802 $tblen = $this->read_short($fh); // Length of Textbuffer
23803 $tbsp = fread($fh,$tblen); // Textbuffer (serialised and packed)
23804 $tbs = unpack("A".$tblen."textbuffer",$tbsp); // Textbuffer unpacked
23805 $c['textbuffer'] = unserialize(trim($tbs['textbuffer'])); // Textbuffer unserialized
23806
23807 if ($tempfh) { fclose($fh); }
23808 return ($c);
23809 }
23810 function read_short(&$fh) {
23811 $s = fread($fh,2);
23812 $a = (ord($s[0])<<8) + ord($s[1]);
23813 if ($a & (1 << 15) ) {
23814 $a = ($a - (1 << 16));
23815 }
23816 return $a;
23817 }
23818 function _backupCacheFiles() {
23819 foreach($this->table AS $lvl=>$t) {
23820 foreach($this->table[$lvl] AS $c=>$t2) {
23821 ///////////////////////////if (!file_exists($t2['cache'])) { echo $lvl; echo $c; print_r($this->table); exit; }
23822 copy( $t2['cache'], $t2['cache'].'.bak');
23823 }
23824 }
23825 }
23826 function _restoreCacheFiles() {
23827 foreach($this->table AS $lvl=>$t) {
23828 foreach($this->table[$lvl] AS $c=>$t2) {
23829 copy( $t2['cache'].'.bak', $t2['cache']);
23830 }
23831 }
23832 }
23833
23834
23835 function _packCellBorder($cell) {
23836 if (!is_array($cell) || !isset($cell)) { return ''; }
23837
23838 if (!$this->packTableData) { return $cell; }
23839 // = 186 bytes
23840 $bindata = pack("nnda6A10nnda6A10nnda6A10nnda6A10nd9",
23841 $cell['border'],
23842 $cell['border_details']['R']['s'],
23843 $cell['border_details']['R']['w'],
23844 $cell['border_details']['R']['c'],
23845 $cell['border_details']['R']['style'],
23846 $cell['border_details']['R']['dom'],
23847
23848 $cell['border_details']['L']['s'],
23849 $cell['border_details']['L']['w'],
23850 $cell['border_details']['L']['c'],
23851 $cell['border_details']['L']['style'],
23852 $cell['border_details']['L']['dom'],
23853
23854 $cell['border_details']['T']['s'],
23855 $cell['border_details']['T']['w'],
23856 $cell['border_details']['T']['c'],
23857 $cell['border_details']['T']['style'],
23858 $cell['border_details']['T']['dom'],
23859
23860 $cell['border_details']['B']['s'],
23861 $cell['border_details']['B']['w'],
23862 $cell['border_details']['B']['c'],
23863 $cell['border_details']['B']['style'],
23864 $cell['border_details']['B']['dom'],
23865
23866 $cell['border_details']['mbw']['BL'],
23867 $cell['border_details']['mbw']['BR'],
23868 $cell['border_details']['mbw']['RT'],
23869 $cell['border_details']['mbw']['RB'],
23870 $cell['border_details']['mbw']['TL'],
23871 $cell['border_details']['mbw']['TR'],
23872 $cell['border_details']['mbw']['LT'],
23873 $cell['border_details']['mbw']['LB'],
23874
23875 $cell['border_details']['cellposdom']
23876 );
23877 return $bindata;
23878 }
23879
23880
23881
23882 function _getBorderWidths($bindata) {
23883 if (!$bindata) { return array(0,0,0,0); }
23884 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']); }
23885
23886 $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);
23887 $cell['border_details']['R']['w'] = $bd['rw'];
23888 $cell['border_details']['L']['w'] = $bd['lw'];
23889 $cell['border_details']['T']['w'] = $bd['tw'];
23890 $cell['border_details']['B']['w'] = $bd['bw'];
23891 return array($bd['tw'], $bd['rw'], $bd['bw'], $bd['lw']);
23892 }
23893
23894
23895 function _unpackCellBorder($bindata) {
23896 if (!$bindata) { return array(); }
23897 if (!$this->packTableData) { return $bindata; }
23898
23899 $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);
23900
23901 $cell['border'] = $bd['bord'];
23902 $cell['border_details']['R']['s'] = $bd['rs'];
23903 $cell['border_details']['R']['w'] = $bd['rw'];
23904 $cell['border_details']['R']['c'] = $bd['rca'];
23905 $cell['border_details']['R']['style'] = trim($bd['rst']);
23906 $cell['border_details']['R']['dom'] = $bd['rd'];
23907
23908 $cell['border_details']['L']['s'] = $bd['ls'];
23909 $cell['border_details']['L']['w'] = $bd['lw'];
23910 $cell['border_details']['L']['c'] = $bd['lca'];
23911 $cell['border_details']['L']['style'] = trim($bd['lst']);
23912 $cell['border_details']['L']['dom'] = $bd['ld'];
23913
23914 $cell['border_details']['T']['s'] = $bd['ts'];
23915 $cell['border_details']['T']['w'] = $bd['tw'];
23916 $cell['border_details']['T']['c'] = $bd['tca'];
23917 $cell['border_details']['T']['style'] = trim($bd['tst']);
23918 $cell['border_details']['T']['dom'] = $bd['td'];
23919
23920 $cell['border_details']['B']['s'] = $bd['bs'];
23921 $cell['border_details']['B']['w'] = $bd['bw'];
23922 $cell['border_details']['B']['c'] = $bd['bca'];
23923 $cell['border_details']['B']['style'] = trim($bd['bst']);
23924 $cell['border_details']['B']['dom'] = $bd['bd'];
23925
23926 $cell['border_details']['mbw']['BL'] = $bd['mbl'];
23927 $cell['border_details']['mbw']['BR'] = $bd['mbr'];
23928 $cell['border_details']['mbw']['RT'] = $bd['mrt'];
23929 $cell['border_details']['mbw']['RB'] = $bd['mrb'];
23930 $cell['border_details']['mbw']['TL'] = $bd['mtl'];
23931 $cell['border_details']['mbw']['TR'] = $bd['mtr'];
23932 $cell['border_details']['mbw']['LT'] = $bd['mlt'];
23933 $cell['border_details']['mbw']['LB'] = $bd['mlb'];
23934 $cell['border_details']['cellposdom'] = $bd['cpd'];
23935
23936 return($cell);
23937 }
23938
23939
23940 ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23941 ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23942 ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
23943 //table Array of (w, h, bc, nr, wc, hr, cells)
23944 //w Width of table
23945 //h Height of table
23946 //nc Number column
23947 //nr Number row
23948 //hr List of height of each row
23949 //wc List of width of each column
23950 //cells List of cells of each rows, cells[i][j] is a cell in the table
23951 function _tableColumnWidth(&$table,$firstpass=false){
23952 $cs = &$table['cells'];
23953
23954 $nc = $table['nc'];
23955 $nr = $table['nr'];
23956 $listspan = array();
23957
23958 if ($table['borders_separate']) {
23959 $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'];
23960 }
23961 else { $tblbw = $table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2 + $table['margin']['L'] + $table['margin']['R']; }
23962
23963 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
23964 else { $fh = null; }
23965
23966 // ADDED table['l'][colno]
23967 // = total length of text approx (using $c['s']) in that column - used to approximately distribute col widths in _tableWidth
23968 //
23969 for($j = 0 ; $j < $nc ; $j++ ) { //columns
23970 $wc = &$table['wc'][$j];
23971 for($i = 0 ; $i < $nr ; $i++ ) { //rows
23972 if (isset($cs[$i][$j]) && $cs[$i][$j]) {
23973 if ($this->cacheTables) {
23974 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
23975 }
23976 else
23977 $c = &$cs[$i][$j];
23978
23979 if ($this->simpleTables){
23980 if ($table['borders_separate']) { // NB twice border width
23981 $extrcw = $table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'] + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
23982 }
23983 else {
23984 $extrcw = $table['simple']['border_details']['L']['w']/2 + $table['simple']['border_details']['R']['w']/2 + $c['padding']['L'] + $c['padding']['R'];
23985 }
23986 }
23987 else {
23988 if ($this->packTableData) {
23989 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
23990 }
23991 else {
23992 $br = $c['border_details']['R']['w'];
23993 $bl = $c['border_details']['L']['w'];
23994 }
23995 if ($table['borders_separate']) { // NB twice border width
23996 $extrcw = $bl + $br + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
23997 }
23998 else {
23999 $extrcw = $bl/2 + $br/2 + $c['padding']['L'] + $c['padding']['R'];
24000 }
24001 }
24002 //$mw = $this->GetStringWidth('W') + $extrcw ;
24003 $mw = 0;
24004 // mPDF 5.6.13 Decimal point alignment
24005 if(substr($c['a'],0,1) == 'D') {
24006 $mw = $table['decimal_align'][$j]['maxs0'] + $table['decimal_align'][$j]['maxs1'] + $extrcw ;
24007 }
24008
24009 $c['absmiw'] = $mw;
24010
24011 if (isset($c['R']) && $c['R']) {
24012 $c['maw'] = $c['miw'] = $this->FontSize + $extrcw ;
24013 if (isset($c['w'])) { // If cell width is specified
24014 if ($c['miw'] <$c['w']) { $c['miw'] = $c['w']; }
24015 }
24016 if (!isset($c['colspan'])) {
24017 if ($wc['miw'] < $c['miw']) { $wc['miw'] = $c['miw']; }
24018 if ($wc['maw'] < $c['maw']) { $wc['maw'] = $c['maw']; }
24019
24020 if ($firstpass) {
24021 if (isset($table['l'][$j]) ) {
24022 $table['l'][$j] += $c['miw'] ;
24023 }
24024 else {
24025 $table['l'][$j] = $c['miw'] ;
24026 }
24027 }
24028 }
24029 if ($c['miw'] > $wc['miw']) { $wc['miw'] = $c['miw']; }
24030 if ($wc['miw'] > $wc['maw']) { $wc['maw'] = $wc['miw']; }
24031 continue;
24032 }
24033
24034 if ($firstpass) {
24035 if (isset($c['s'])) { $c['s'] += $extrcw; }
24036 if (isset($c['maxs'])) { $c['maxs'] += $extrcw; }
24037 if (isset($c['nestedmiw'])) { $c['nestedmiw'] += $extrcw; }
24038 if (isset($c['nestedmaw'])) { $c['nestedmaw'] += $extrcw; }
24039 }
24040
24041 // If minimum width has already been set by a nested table or inline object (image/form), use it
24042 if (isset($c['nestedmiw']) && $this->table[1][1]['overflow']!='visible') { $miw = $c['nestedmiw']; }
24043 else { $miw = $mw; }
24044
24045 if (isset($c['maxs']) && $c['maxs'] != '') { $c['s'] = $c['maxs']; }
24046
24047 // If maximum width has already been set by a nested table, use it
24048 if (isset($c['nestedmaw'])) { $c['maw'] = $c['nestedmaw']; }
24049 else $c['maw'] = $c['s'];
24050
24051 if (isset($table['overflow']) && $table['overflow']=='visible' && $table['level']==1) {
24052 if (($c['maw'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
24053 $c['maw'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw;
24054 }
24055 }
24056
24057 if (isset($c['nowrap']) && $c['nowrap']) { $miw = $c['maw']; }
24058
24059 if (isset($c['wpercent']) && $firstpass) {
24060 if (isset($c['colspan'])) { // Not perfect - but % set on colspan is shared equally on cols.
24061 for($k=0;$k<$c['colspan'];$k++) {
24062 $table['wc'][($j+$k)]['wpercent'] = $c['wpercent'] / $c['colspan'];
24063 }
24064 }
24065 else {
24066 if (isset($table['w']) && $table['w']) { $c['w'] = $c['wpercent']/100 * ($table['w'] - $tblbw ); }
24067 $wc['wpercent'] = $c['wpercent'];
24068 }
24069 }
24070
24071 if (isset($table['overflow']) && $table['overflow']=='visible' && $table['level']==1) {
24072 if (($c['w'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
24073 $c['w'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw;
24074 }
24075 }
24076
24077
24078 if (isset($c['w'])) { // If cell width is specified
24079 if ($miw<$c['w']) { $c['miw'] = $c['w']; } // Cell min width = that specified
24080 if ($miw>$c['w']) { $c['miw'] = $c['w'] = $miw; } // If width specified is less than minimum allowed (W) increase it
24081 // mPDF 5.7.4 Do not set column width in colspan
24082 // cf. http://www.mpdf1.com/forum/discussion/2221/colspan-bug
24083 if (!isset($c['colspan'])) {
24084 if (!isset($wc['w'])) { $wc['w'] = 1; } // If the Col width is not specified = set it to 1
24085 }
24086 // mPDF 5.7.3 cf. http://www.mpdf1.com/forum/discussion/1648/nested-table-bug-
24087 $c['maw'] = $c['w'];
24088 }
24089 else { $c['miw'] = $miw; } // If cell width not specified -> set Cell min width it to minimum allowed (W)
24090
24091 if ($c['maw'] < $c['miw']) { $c['maw'] = $c['miw']; } // If Cell max width < Minwidth - increase it to =
24092 if (!isset($c['colspan'])) {
24093 if ($wc['miw'] < $c['miw']) { $wc['miw'] = $c['miw']; } // Update Col Minimum and maximum widths
24094 if ($wc['maw'] < $c['maw']) { $wc['maw'] = $c['maw']; }
24095 if ((isset($wc['absmiw']) && $wc['absmiw'] < $c['absmiw']) || !isset($wc['absmiw'])) { $wc['absmiw'] = $c['absmiw']; } // Update Col Minimum and maximum widths
24096
24097 if (isset($table['l'][$j]) ) {
24098 $table['l'][$j] += $c['s'];
24099 }
24100 else {
24101 $table['l'][$j] = $c['s'];
24102 }
24103
24104 }
24105 else {
24106 $listspan[] = array($i,$j);
24107 }
24108
24109 //Check if minimum width of the whole column is big enough for largest word to fit
24110 if (isset($c['textbuffer']) && (!isset($table['overflow']) || $table['overflow']!='wrap')) { // mPDF 5.5.11
24111 $minwidth = $this->TableCheckMinWidth($wc['miw']- $extrcw ,0,$c['textbuffer']);
24112 }
24113 else { $minwidth = 0; }
24114 if ($minwidth < 0) {
24115 //increase minimum width
24116 if (!isset($c['colspan'])) {
24117 $wc['miw'] = max($wc['miw'],((-$minwidth) + $extrcw) );
24118 }
24119 else {
24120 $c['miw'] = max($c['miw'],((-$minwidth) + $extrcw) );
24121 }
24122 }
24123 if (!isset($c['colspan'])) {
24124 if ($wc['miw'] > $wc['maw']) { $wc['maw'] = $wc['miw']; } //update maximum width, if needed
24125 }
24126 if ($this->cacheTables) {
24127 $this->_cacheCell($c, '', "W", $fh, $table['cells'][$i][$j]);
24128 }
24129 }
24130 unset($c);
24131 }//rows
24132 }//columns
24133
24134 // COLUMN SPANS
24135 $wc = &$table['wc'];
24136 foreach ($listspan as $span) {
24137 list($i,$j) = $span;
24138 if ($this->cacheTables) {
24139 $c = $this->_uncacheCell($cs[$i][$j], '', $fh);
24140 }
24141 else
24142 $c = &$cs[$i][$j];
24143 $lc = $j + $c['colspan'];
24144 if ($lc > $nc) { $lc = $nc; }
24145 $wis = $wisa = 0;
24146 $was = $wasa = 0;
24147 $list = array();
24148 for($k=$j;$k<$lc;$k++) {
24149 if (isset($table['l'][$k]) ) {
24150 if ($c['R']) { $table['l'][$k] += $c['miw']/$c['colspan'] ; }
24151 else { $table['l'][$k] += $c['s']/$c['colspan']; }
24152 }
24153 else {
24154 if ($c['R']) { $table['l'][$k] = $c['miw']/$c['colspan'] ; }
24155 else { $table['l'][$k] = $c['s']/$c['colspan']; }
24156 }
24157 $wis += $wc[$k]['miw']; // $wis is the sum of the column miw in the colspan
24158 $was += $wc[$k]['maw']; // $was is the sum of the column maw in the colspan
24159 if (!isset($c['w'])) {
24160 $list[] = $k;
24161 $wisa += $wc[$k]['miw']; // $wisa is the sum of the column miw in cells with no width specified in the colspan
24162 $wasa += $wc[$k]['maw']; // $wasa is the sum of the column maw in cells with no width specified in the colspan
24163 }
24164 }
24165 if ($c['miw'] > $wis) {
24166 if (!$wis) {
24167 for($k=$j;$k<$lc;$k++) { $wc[$k]['miw'] = $c['miw']/$c['colspan']; }
24168 }
24169 else if (!count($list)) {
24170 $wi = $c['miw'] - $wis;
24171 for($k=$j;$k<$lc;$k++) { $wc[$k]['miw'] += ($wc[$k]['miw']/$wis)*$wi; }
24172 }
24173 else {
24174 $wi = $c['miw'] - $wis;
24175 // mPDF 5.7.2 Extra min width distributed proportionately to all cells in colspan without a specified width
24176 // cf. http://www.mpdf1.com/forum/discussion/1607#Item_4
24177 foreach ($list as $k) { if (!isset($wc[$k]['w']) || !$wc[$k]['w']) $wc[$k]['miw'] += ($wc[$k]['miw']/$wisa)*$wi; } // mPDF 5.7.2
24178 }
24179 }
24180 if ($c['maw'] > $was) {
24181 if (!$wis) {
24182 for($k=$j;$k<$lc;$k++) { $wc[$k]['maw'] = $c['maw']/$c['colspan']; }
24183 }
24184 else if (!count($list)) {
24185 $wi = $c['maw'] - $was;
24186 for($k=$j;$k<$lc;$k++) { $wc[$k]['maw'] += ($wc[$k]['maw']/$was)*$wi; }
24187 }
24188 else {
24189 $wi = $c['maw'] - $was;
24190 // mPDF 5.7.4 Extra max width distributed evenly to all cells in colspan without a specified width
24191 // cf. http://www.mpdf1.com/forum/discussion/2221/colspan-bug
24192 foreach ($list as $k) { $wc[$k]['maw'] += $wi/count($list); }
24193 }
24194 }
24195 unset($c);
24196 }
24197
24198 if ($this->cacheTables) { fclose($fh); }
24199
24200 $checkminwidth = 0;
24201 $checkmaxwidth = 0;
24202 $totallength = 0;
24203
24204 for( $i = 0 ; $i < $nc ; $i++ ) {
24205 $checkminwidth += $table['wc'][$i]['miw'];
24206 $checkmaxwidth += $table['wc'][$i]['maw'];
24207 $totallength += $table['l'][$i];
24208 }
24209
24210 if (!isset($table['w']) && $firstpass) {
24211 $sumpc = 0;
24212 $notset = 0;
24213 for( $i = 0 ; $i < $nc ; $i++ ) {
24214 if (isset($table['wc'][$i]['wpercent']) && $table['wc'][$i]['wpercent']) {
24215 $sumpc += $table['wc'][$i]['wpercent'];
24216 }
24217 else { $notset++; }
24218 }
24219
24220 // If sum of widths as % >= 100% and not all columns are set
24221 // Set a nominal width of 1% for unset columns
24222 if ($sumpc >= 100 && $notset) {
24223 for( $i = 0 ; $i < $nc ; $i++ ) {
24224 if ((!isset($table['wc'][$i]['wpercent']) || !$table['wc'][$i]['wpercent']) &&
24225 (!isset($table['wc'][$i]['w']) || !$table['wc'][$i]['w'])) {
24226 $table['wc'][$i]['wpercent'] = 1;
24227 }
24228 }
24229 }
24230
24231
24232 if ($sumpc) { // if any percents are set
24233 $sumnonpc = (100 - $sumpc);
24234 $sumpc = max($sumpc,100);
24235 $miwleft = 0;
24236 $miwleftcount = 0;
24237 $miwsurplusnonpc = 0;
24238 $maxcalcmiw = 0;
24239 $mawleft = 0;
24240 $mawleftcount = 0;
24241 $mawsurplusnonpc = 0;
24242 $maxcalcmaw = 0;
24243 for( $i = 0 ; $i < $nc ; $i++ ) {
24244 if (isset($table['wc'][$i]['wpercent'])) {
24245 $maxcalcmiw = max($maxcalcmiw, ($table['wc'][$i]['miw'] * $sumpc /$table['wc'][$i]['wpercent']) );
24246 $maxcalcmaw = max($maxcalcmaw, ($table['wc'][$i]['maw'] * $sumpc /$table['wc'][$i]['wpercent']) );
24247 }
24248 else {
24249 $miwleft += $table['wc'][$i]['miw'];
24250 $mawleft += $table['wc'][$i]['maw'];
24251 if (!isset($table['wc'][$i]['w'])) { $miwleftcount++; $mawleftcount++; }
24252 }
24253 }
24254 if ($miwleft && $sumnonpc > 0) { $miwnon = $miwleft * 100 / $sumnonpc; }
24255 if ($mawleft && $sumnonpc > 0) { $mawnon = $mawleft * 100 / $sumnonpc; }
24256 if (($miwnon > $checkminwidth || $maxcalcmiw > $checkminwidth) && $this->keep_table_proportions) {
24257 if ($miwnon > $maxcalcmiw) {
24258 $miwsurplusnonpc = round((($miwnon * $sumnonpc / 100) - $miwleft),3);
24259 $checkminwidth = $miwnon;
24260 }
24261 else { $checkminwidth = $maxcalcmiw; }
24262 for( $i = 0 ; $i < $nc ; $i++ ) {
24263 if (isset($table['wc'][$i]['wpercent'])) {
24264 $newmiw = $checkminwidth * $table['wc'][$i]['wpercent']/100;
24265 if ($table['wc'][$i]['miw'] < $newmiw) {
24266 $table['wc'][$i]['miw'] = $newmiw;
24267 }
24268 $table['wc'][$i]['w'] = 1;
24269 }
24270 else if ($miwsurplusnonpc && !$table['wc'][$i]['w']) {
24271 $table['wc'][$i]['miw'] += $miwsurplusnonpc / $miwleftcount;
24272 }
24273 }
24274 }
24275 if (($mawnon > $checkmaxwidth || $maxcalcmaw > $checkmaxwidth )) {
24276 if ($mawnon > $maxcalcmaw) {
24277 $mawsurplusnonpc = round((($mawnon * $sumnonpc / 100) - $mawleft),3);
24278 $checkmaxwidth = $mawnon;
24279 }
24280 else { $checkmaxwidth = $maxcalcmaw; }
24281 for( $i = 0 ; $i < $nc ; $i++ ) {
24282 if (isset($table['wc'][$i]['wpercent'])) {
24283 $newmaw = $checkmaxwidth * $table['wc'][$i]['wpercent']/100;
24284 if ($table['wc'][$i]['maw'] < $newmaw) {
24285 $table['wc'][$i]['maw'] = $newmaw;
24286 }
24287 $table['wc'][$i]['w'] = 1;
24288 }
24289 else if ($mawsurplusnonpc && !$table['wc'][$i]['w']) {
24290 $table['wc'][$i]['maw'] += $mawsurplusnonpc / $mawleftcount;
24291 }
24292 if ($table['wc'][$i]['maw'] < $table['wc'][$i]['miw']) { $table['wc'][$i]['maw'] = $table['wc'][$i]['miw']; }
24293 }
24294 }
24295 if ($checkminwidth > $checkmaxwidth) { $checkmaxwidth = $checkminwidth; }
24296 }
24297 }
24298
24299 if (isset($table['wpercent']) && $table['wpercent']) {
24300 $checkminwidth *= (100 / $table['wpercent']);
24301 $checkmaxwidth *= (100 / $table['wpercent']);
24302 }
24303
24304
24305 $checkminwidth += $tblbw ;
24306 $checkmaxwidth += $tblbw ;
24307
24308 // Table['miw'] set by percent in first pass may be larger than sum of column miw
24309 if ((isset($table['miw']) && $checkminwidth > $table['miw']) || !isset($table['miw'])) { $table['miw'] = $checkminwidth; }
24310 if ((isset($table['maw']) && $checkmaxwidth > $table['maw']) || !isset($table['maw'])) { $table['maw'] = $checkmaxwidth; }
24311 $table['tl'] = $totallength ;
24312
24313 if (!$this->tableCJK) {
24314 if ($this->table_rotate) {
24315 $mxw = $this->tbrot_maxw;
24316 }
24317 else {
24318 $mxw = $this->blk[$this->blklvl]['inner_width'];
24319 }
24320 if(!isset($table['overflow'])) { $table['overflow'] = null; }
24321 if ($table['overflow']=='visible') {
24322 return array(0,0);
24323 }
24324 else if ($table['overflow']=='hidden' && !$this->table_rotate && !$this->ColActive && $checkminwidth > $mxw) {
24325 $table['w'] = $table['miw'];
24326 return array(0,0);
24327 }
24328 else if ($table['overflow']=='wrap') { return array(0,0); }
24329
24330 if (isset($table['w']) && $table['w'] ) {
24331 if ($table['w'] >= $checkminwidth && $table['w'] <= $mxw) { $table['maw'] = $mxw = $table['w']; }
24332 else if ($table['w'] >= $checkminwidth && $table['w'] > $mxw && $this->keep_table_proportions) { $checkminwidth = $table['w']; }
24333 else if ($table['w'] < $checkminwidth && $checkminwidth < $mxw && $this->keep_table_proportions) { $table['maw'] = $table['w'] = $checkminwidth; } // mPDF 5.7.4
24334 else {
24335 unset($table['w']);
24336 }
24337 }
24338 $ratio = $checkminwidth/$mxw;
24339 if ($checkminwidth > $mxw) { return array(($ratio +0.001),$checkminwidth); } // 0.001 to allow for rounded numbers when resizing
24340 }
24341 unset($cs);
24342 return array(0,0);
24343 }
24344
24345
24346
24347 function _tableWidth(&$table){
24348 $widthcols = &$table['wc'];
24349 $numcols = $table['nc'];
24350 $tablewidth = 0;
24351 if ($table['borders_separate']) {
24352 $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'];
24353 }
24354 else { $tblbw = $table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2 + $table['margin']['L'] + $table['margin']['R']; }
24355
24356 if ($table['level']>1 && isset($table['w'])) {
24357 if (isset($table['wpercent']) && $table['wpercent']) {
24358 $table['w'] = $temppgwidth = (($table['w']-$tblbw) * $table['wpercent'] / 100) + $tblbw ;
24359 }
24360 else {
24361 $temppgwidth = $table['w'] ;
24362 }
24363 }
24364 else if ($this->table_rotate) {
24365 $temppgwidth = $this->tbrot_maxw;
24366 // If it is less than 1/20th of the remaining page height to finish the DIV (i.e. DIV padding + table bottom margin)
24367 // then allow for this
24368 $enddiv = $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'];
24369 if ($enddiv/$temppgwidth <0.05) { $temppgwidth -= $enddiv; }
24370 }
24371 else {
24372 if (isset($table['w']) && $table['w']< $this->blk[$this->blklvl]['inner_width']) {
24373 $notfullwidth = 1;
24374 $temppgwidth = $table['w'] ;
24375 }
24376 else if ($table['overflow']=='visible' && $table['level'] ==1) {
24377 $temppgwidth = null;
24378 }
24379 else if ($table['overflow']=='hidden' && !$this->ColActive && isset($table['w']) && $table['w'] > $this->blk[$this->blklvl]['inner_width'] && $table['w']==$table['miw']) {
24380 //$temppgwidth = $this->blk[$this->blklvl]['inner_width'];
24381 $temppgwidth = $table['w'] ;
24382 }
24383 else { $temppgwidth = $this->blk[$this->blklvl]['inner_width']; }
24384 }
24385
24386
24387 $totaltextlength = 0; // Added - to sum $table['l'][colno]
24388 $totalatextlength = 0; // Added - to sum $table['l'][colno] for those columns where width not set
24389 $percentages_set = 0;
24390 for ( $i = 0 ; $i < $numcols ; $i++ ) {
24391 if (isset($widthcols[$i]['wpercent'])) { $tablewidth += $widthcols[$i]['maw']; $percentages_set = 1; }
24392 else if (isset($widthcols[$i]['w'])) { $tablewidth += $widthcols[$i]['miw']; }
24393 else { $tablewidth += $widthcols[$i]['maw']; }
24394 $totaltextlength += $table['l'][$i];
24395 }
24396 if (!$totaltextlength) { $totaltextlength =1; }
24397 $tablewidth += $tblbw; // Outer half of table borders
24398
24399 if ($tablewidth > $temppgwidth) {
24400 $table['w'] = $temppgwidth;
24401 }
24402 // if any widths set as percentages and max width fits < page width
24403 else if ($tablewidth < $temppgwidth && !isset($table['w']) && $percentages_set) {
24404 $table['w'] = $table['maw'];
24405 }
24406 // if table width is set and is > allowed width
24407 if (isset($table['w']) && $table['w'] > $temppgwidth) { $table['w'] = $temppgwidth; }
24408
24409 // IF the table width is now set - Need to distribute columns widths
24410 // mPDF 5.7.3
24411 // If the table width is already set to the maximum width (e.g. nested table), then use maximum column widths exactly
24412 if (isset($table['w']) && ($table['w'] == $tablewidth) && !$percentages_set) {
24413 // This sets the columns all to maximum width
24414 for ($i=0;$i<$numcols;$i++) {
24415 $widthcols[$i] = $widthcols[$i]['maw'];
24416 }
24417 }
24418 // Else If the table width is set distribute width using algorithm
24419 else if (isset($table['w'])) {
24420 $wis = $wisa = 0;
24421 $list = array();
24422 $notsetlist = array();
24423 for( $i = 0 ; $i < $numcols ; $i++ ) {
24424 $wis += $widthcols[$i]['miw'];
24425 if (!isset($widthcols[$i]['w']) || ($widthcols[$i]['w'] && $table['w'] > $temppgwidth && !$this->keep_table_proportions && !$notfullwidth )){
24426 $list[] = $i;
24427 $wisa += $widthcols[$i]['miw'];
24428 $totalatextlength += $table['l'][$i];
24429 }
24430 }
24431 if (!$totalatextlength) { $totalatextlength =1; }
24432
24433 // Allocate spare (more than col's minimum width) across the cols according to their approx total text length
24434 // Do it by setting minimum width here
24435 if ($table['w'] > $wis + $tblbw) {
24436 // First set any cell widths set as percentages
24437 if ($table['w'] < $temppgwidth || $this->keep_table_proportions) {
24438 for($k=0;$k<$numcols;$k++) {
24439 if (isset($widthcols[$k]['wpercent'])) {
24440 $curr = $widthcols[$k]['miw'];
24441 $widthcols[$k]['miw'] = ($table['w']-$tblbw) * $widthcols[$k]['wpercent']/100;
24442 $wis += $widthcols[$k]['miw'] - $curr;
24443 $wisa += $widthcols[$k]['miw'] - $curr;
24444 }
24445 }
24446 }
24447 // Now allocate surplus up to maximum width of each column
24448 $surplus = 0; $ttl = 0; // number of surplus columns
24449 if (!count($list)) {
24450 $wi = ($table['w']-($wis + $tblbw)); // i.e. extra space to distribute
24451 for($k=0;$k<$numcols;$k++) {
24452 $spareratio = ($table['l'][$k] / $totaltextlength); // gives ratio to divide up free space
24453 // Don't allocate more than Maximum required width - save rest in surplus
24454 if ($widthcols[$k]['miw'] + ($wi * $spareratio) >= $widthcols[$k]['maw']) { // mPDF 5.7.3
24455 $surplus += ($wi * $spareratio) - ($widthcols[$k]['maw']-$widthcols[$k]['miw']);
24456 $widthcols[$k]['miw'] = $widthcols[$k]['maw'];
24457 }
24458 else {
24459 $notsetlist[] = $k;
24460 $ttl += $table['l'][$k];
24461 $widthcols[$k]['miw'] += ($wi * $spareratio);
24462 }
24463
24464 }
24465 }
24466 else {
24467 $wi = ($table['w'] - ($wis + $tblbw)); // i.e. extra space to distribute
24468 foreach ($list as $k) {
24469 $spareratio = ($table['l'][$k] / $totalatextlength); // gives ratio to divide up free space
24470 // Don't allocate more than Maximum required width - save rest in surplus
24471 if ($widthcols[$k]['miw'] + ($wi * $spareratio) >= $widthcols[$k]['maw']) { // mPDF 5.7.3
24472 $surplus += ($wi * $spareratio) - ($widthcols[$k]['maw']-$widthcols[$k]['miw']);
24473 $widthcols[$k]['miw'] = $widthcols[$k]['maw'];
24474 }
24475 else {
24476 $notsetlist[] = $k;
24477 $ttl += $table['l'][$k];
24478 $widthcols[$k]['miw'] += ($wi * $spareratio);
24479 }
24480 }
24481 }
24482 // If surplus still left over apportion it across columns
24483 if ($surplus) {
24484 // if some are set only add to remaining - otherwise add to all of them
24485 if (count($notsetlist) && count($notsetlist) < $numcols) {
24486 foreach ($notsetlist AS $i) {
24487 if ($ttl) $widthcols[$i]['miw'] += $surplus * $table['l'][$i] / $ttl ;
24488 }
24489 }
24490 // If some widths are defined, and others have been added up to their maxmum
24491 else if (count($list) && count($list) < $numcols) {
24492 foreach ($list AS $i) {
24493 $widthcols[$i]['miw'] += $surplus / count($list) ;
24494 }
24495 }
24496 else if ($numcols) { // If all columns
24497 $ttl = array_sum($table['l']);
24498 for ($i=0;$i<$numcols;$i++) {
24499 $widthcols[$i]['miw'] += $surplus * $table['l'][$i] / $ttl;
24500 }
24501 }
24502 }
24503
24504 }
24505
24506 // This sets the columns all to minimum width (which has been increased above if appropriate)
24507 for ($i=0;$i<$numcols;$i++) {
24508 $widthcols[$i] = $widthcols[$i]['miw'];
24509 }
24510
24511 // TABLE NOT WIDE ENOUGH EVEN FOR MINIMUM CONTENT WIDTH
24512 // If sum of column widths set are too wide for table
24513 $checktablewidth = 0;
24514 for ( $i = 0 ; $i < $numcols ; $i++ ) {
24515 $checktablewidth += $widthcols[$i];
24516 }
24517 if ($checktablewidth > ($temppgwidth + 0.001 - $tblbw)) {
24518 $usedup = 0; $numleft = 0;
24519 for ($i=0;$i<$numcols;$i++) {
24520 if ((isset($widthcols[$i]) && $widthcols[$i] > (($temppgwidth - $tblbw) / $numcols)) && (!isset($widthcols[$i]['w']))) {
24521 $numleft++;
24522 unset($widthcols[$i]);
24523 }
24524 else { $usedup += $widthcols[$i]; }
24525 }
24526 for ($i=0;$i<$numcols;$i++) {
24527 if (!isset($widthcols[$i]) || !$widthcols[$i]) {
24528 $widthcols[$i] = ((($temppgwidth - $tblbw) - $usedup)/ ($numleft));
24529 }
24530 }
24531 }
24532 }
24533 else { //table has no width defined
24534 $table['w'] = $tablewidth;
24535 for ( $i = 0 ; $i < $numcols ; $i++) {
24536 if (isset($widthcols[$i]['wpercent']) && $this->keep_table_proportions) { $colwidth = $widthcols[$i]['maw']; }
24537 else if (isset($widthcols[$i]['w'])) { $colwidth = $widthcols[$i]['miw']; }
24538 else { $colwidth = $widthcols[$i]['maw']; }
24539 unset($widthcols[$i]);
24540 $widthcols[$i] = $colwidth;
24541 }
24542 }
24543
24544 if ($table['overflow']=='visible' && $table['level'] ==1) {
24545 if ($tablewidth > $this->blk[$this->blklvl]['inner_width']) {
24546 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
24547 else { $fh = null; }
24548 for ($j = 0 ; $j < $numcols; $j++) { //columns
24549 for ($i = 0 ; $i < $table['nr']; $i++) { //rows
24550 if (isset($table['cells'][$i][$j]) && $table['cells'][$i][$j]) {
24551 if ($this->cacheTables) {
24552 $cc = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24553 $colspan = $cc['colspan'];
24554 }
24555 else
24556 $colspan = $table['cells'][$i][$j]['colspan'];
24557 if ($colspan > 1) {
24558 $w = 0;
24559 for ($c = $j; $c < ($j + $colspan); $c++) {
24560 $w += $widthcols[$c];
24561 }
24562 if ($w > $this->blk[$this->blklvl]['inner_width']) {
24563 $diff = $w - ($this->blk[$this->blklvl]['inner_width'] - $tblbw);
24564 for ($c = $j; $c < ($j + $colspan); $c++) {
24565 $widthcols[$c] -= $diff * ($widthcols[$c]/$w);
24566 }
24567 $table['w'] -= $diff;
24568 $table['csp'][$j] = $w - $diff;
24569 }
24570 }
24571 }
24572
24573 }
24574 }
24575 if ($this->cacheTables) { fclose($fh); }
24576 }
24577 $pgNo = 0;
24578 $currWc = 0;
24579 for ($i = 0 ; $i < $numcols; $i++) { //columns
24580 if (isset($table['csp'][$i])) {
24581 $w = $table['csp'][$i];
24582 unset($table['csp'][$i]);
24583 }
24584 else { $w = $widthcols[$i]; }
24585 if (($currWc + $w + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
24586 $pgNo++;
24587 $currWc = $widthcols[$i] ;
24588 }
24589 else { $currWc += $widthcols[$i] ; }
24590 $table['colPg'][$i] = $pgNo;
24591 }
24592 }
24593 }
24594
24595
24596
24597 function _tableHeight(&$table){
24598 $level = $table['level'];
24599 $levelid = $table['levelid'];
24600 $cells = &$table['cells'];
24601 $numcols = $table['nc'];
24602 $numrows = $table['nr'];
24603 $listspan = array();
24604 $checkmaxheight = 0;
24605 $headerrowheight = 0;
24606 $checkmaxheightplus = 0;
24607 $headerrowheightplus = 0;
24608 $firstrowheight = 0;
24609
24610 $footerrowheight = 0;
24611 $footerrowheightplus = 0;
24612 if ($this->table_rotate) {
24613 $temppgheight = $this->tbrot_maxh;
24614 $remainingpage = $this->tbrot_maxh;
24615 }
24616 else {
24617 $temppgheight = ($this->h - $this->bMargin - $this->tMargin) - $this->kwt_height;
24618 $remainingpage = ($this->h - $this->bMargin - $this->y) - $this->kwt_height;
24619
24620 // If it is less than 1/20th of the remaining page height to finish the DIV (i.e. DIV padding + table bottom margin)
24621 // then allow for this
24622 $enddiv = $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $table['margin']['B'];
24623 if ($remainingpage > $enddiv && $enddiv/$remainingpage <0.05) { $remainingpage -= $enddiv; }
24624 else if ($remainingpage == 0) { $remainingpage = 0.001; }
24625 if ($temppgheight > $enddiv && $enddiv/$temppgheight <0.05) { $temppgheight -= $enddiv; }
24626 else if ($temppgheight == 0) { $temppgheight = 0.001; }
24627 }
24628 if ($remainingpage < 0) { $remainingpage = 0.001; } // mPDF 5.6.64
24629 if ($temppgheight < 0) { $temppgheight = 0.001; } // mPDF 5.6.64
24630
24631 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
24632 else { $fh = null; }
24633
24634 for( $i = 0 ; $i < $numrows ; $i++ ) { //rows
24635 $heightrow = &$table['hr'][$i];
24636 for( $j = 0 ; $j < $numcols ; $j++ ) { //columns
24637 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
24638 if ($this->cacheTables) {
24639 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24640 }
24641 else
24642 $c = &$cells[$i][$j];
24643
24644 if ($this->simpleTables){
24645 if ($table['borders_separate']) { // NB twice border width
24646 $extraWLR = ($table['simple']['border_details']['L']['w']+$table['simple']['border_details']['R']['w']) + ($c['padding']['L']+$c['padding']['R'])+$table['border_spacing_H'];
24647 $extrh = ($table['simple']['border_details']['T']['w']+$table['simple']['border_details']['B']['w']) + ($c['padding']['T']+$c['padding']['B'])+$table['border_spacing_V'];
24648 }
24649 else {
24650 $extraWLR = ($table['simple']['border_details']['L']['w']+$table['simple']['border_details']['R']['w'])/2 + ($c['padding']['L']+$c['padding']['R']);
24651 $extrh = ($table['simple']['border_details']['T']['w']+$table['simple']['border_details']['B']['w'])/2 + ($c['padding']['T']+$c['padding']['B']);
24652 }
24653 }
24654 else {
24655 if ($this->packTableData) {
24656 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
24657 }
24658 else {
24659 $bt = $c['border_details']['T']['w'];
24660 $bb = $c['border_details']['B']['w'];
24661 $br = $c['border_details']['R']['w'];
24662 $bl = $c['border_details']['L']['w'];
24663 }
24664 if ($table['borders_separate']) { // NB twice border width
24665 $extraWLR = $bl + $br + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
24666 $extrh = $bt + $bb + $c['padding']['T'] + $c['padding']['B'] + $table['border_spacing_V'];
24667 }
24668 else {
24669 $extraWLR = $bl/2 + $br/2 + $c['padding']['L'] + $c['padding']['R'];
24670 $extrh = $bt/2 + $bb/2 + $c['padding']['T']+$c['padding']['B'];
24671 }
24672 }
24673
24674 if ($table['overflow']=='visible' && $level==1)
24675 list($x,$cw) = $this->_splitTableGetWidth($table, $i,$j, $fh);
24676 else
24677 list($x,$cw) = $this->_tableGetWidth($table, $i,$j, $fh);
24678
24679 // Get CELL HEIGHT
24680 // ++ extra parameter forces wrap to break word
24681 if ($c['R'] && isset($c['textbuffer'])) { // mPDF 5.4.01
24682 $str = '';
24683 foreach($c['textbuffer'] AS $t) { $str .= $t[0].' '; }
24684 $str = trim($str);
24685 $s_fs = $this->FontSizePt;
24686 $s_f = $this->FontFamily;
24687 $s_st = $this->FontStyle;
24688 $this->SetFont($c['textbuffer'][0][4],$c['textbuffer'][0][2],$c['textbuffer'][0][11] / $this->shrin_k,true,true);
24689 $tempch = $this->GetStringWidth($str);
24690 if ($c['R'] >= 45 && $c['R'] < 90) {
24691 $tempch = ((sin(deg2rad($c['R']))) * $tempch ) + ((sin(deg2rad($c['R']))) * (($c['textbuffer'][0][11]/_MPDFK) / $this->shrin_k));
24692 }
24693 $this->SetFont($s_f,$s_st,$s_fs,true,true);
24694 $ch = ($tempch ) + $extrh ;
24695 }
24696 else {
24697 if (isset($c['textbuffer'])) {
24698 $tempch = $this->TableWordWrap(($cw-$extraWLR),1,$c['textbuffer'], $c['dfs']);
24699 }
24700 else { $tempch = 0; }
24701 // Added cellpadding top and bottom. (Lineheight already adjusted to table_lineheight)
24702 $ch = $tempch + $extrh ;
24703 }
24704 //If height is defined and it is bigger than calculated $ch then update values
24705 if (isset($c['h']) && $c['h'] > $ch) {
24706 $c['mih'] = $ch; //in order to keep valign working
24707 $ch = $c['h'];
24708 }
24709 else $c['mih'] = $ch;
24710 if ($this->cacheTables) {
24711 $this->_cacheUpdateMtx($c, $fh, $table['cells'][$i][$j], 'mih');
24712 }
24713 if (isset($c['rowspan'])) $listspan[] = array($i,$j);
24714 elseif ($heightrow < $ch) $heightrow = $ch;
24715
24716 // this is the extra used in _tableWrite to determine whether to trigger a page change
24717 if ($table['borders_separate']) {
24718 if ($i == ($numrows-1) || (isset($c['rowspan']) && ($i+$c['rowspan']) == ($numrows)) ) {
24719 $extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
24720 }
24721 else {
24722 $extra = $table['border_spacing_V']/2;
24723 }
24724 }
24725 else {
24726 if (!$this->simpleTables){
24727 $extra = $bb/2;
24728 }
24729 else if ($this->simpleTables){
24730 $extra = $table['simple']['border_details']['B']['w'] /2;
24731 }
24732 }
24733 if (isset($table['is_thead'][$i]) && $table['is_thead'][$i]) {
24734 if ($j==0) {
24735 $headerrowheight += $ch;
24736 $headerrowheightplus += $ch+$extra;
24737 }
24738 }
24739 else if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i]) {
24740 if ($j==0) {
24741 $footerrowheight += $ch;
24742 $footerrowheightplus += $ch+$extra;
24743 }
24744 }
24745 else {
24746 $checkmaxheight = max($checkmaxheight,$ch);
24747 $checkmaxheightplus = max($checkmaxheightplus,$ch+$extra);
24748 }
24749 if ($this->tableLevel==1 && $i == $table['headernrows']) { $firstrowheight = max($ch,$firstrowheight); }
24750 unset($c);
24751 }
24752 }//end of columns
24753 }//end of rows
24754
24755 $heightrow = &$table['hr'];
24756 foreach ($listspan as $span) {
24757 list($i,$j) = $span;
24758 if ($this->cacheTables) {
24759 $c = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24760 }
24761 else
24762 $c = &$cells[$i][$j];
24763 $lr = $i + $c['rowspan'];
24764 if ($lr > $numrows) $lr = $numrows;
24765 $hs = $hsa = 0;
24766 $list = array();
24767 for($k=$i;$k<$lr;$k++) {
24768 $hs += $heightrow[$k];
24769 if (!isset($c['h'])) {
24770 $list[] = $k;
24771 $hsa += $heightrow[$k];
24772 }
24773 }
24774
24775 if ($table['borders_separate']) {
24776 if ($i == ($numrows-1) || ($i+$c['rowspan']) == ($numrows) ) {
24777 $extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
24778 }
24779 else {
24780 $extra = $table['border_spacing_V']/2;
24781 }
24782 }
24783 else {
24784 if (!$this->simpleTables){
24785 if ($this->packTableData) {
24786 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
24787 }
24788 else {
24789 $bb = $c['border_details']['B']['w'];
24790 }
24791 $extra = $bb/2;
24792 }
24793 else if ($this->simpleTables){
24794 $extra = $table['simple']['border_details']['B']['w'] /2;
24795 }
24796 }
24797 if (!empty($table['is_thead'][$i])) {
24798 $headerrowheight = max($headerrowheight,$hs);
24799 $headerrowheightplus = max($headerrowheightplus,$hs+$extra);
24800 }
24801 else if (!empty($table['is_tfoot'][$i])) {
24802 $footerrowheight = max($footerrowheight,$hs);
24803 $footerrowheightplus = max($footerrowheightplus,$hs+$extra);
24804 }
24805 else {
24806 $checkmaxheight = max($checkmaxheight,$hs);
24807 $checkmaxheightplus = max($checkmaxheightplus,$hs+$extra);
24808 }
24809 if ($this->tableLevel==1 && $i == $table['headernrows']) { $firstrowheight = max($hs,$firstrowheight); }
24810
24811 if ($c['mih'] > $hs) {
24812 if (!$hs) {
24813 for($k=$i;$k<$lr;$k++) $heightrow[$k] = $c['mih']/$c['rowspan'];
24814 }
24815 elseif (!count($list)) {
24816 $hi = $c['mih'] - $hs;
24817 for($k=$i;$k<$lr;$k++) $heightrow[$k] += ($heightrow[$k]/$hs)*$hi;
24818 }
24819 else {
24820 $hi = $c['mih'] - $hsa;
24821 foreach ($list as $k) $heightrow[$k] += ($heightrow[$k]/$hsa)*$hi;
24822 }
24823 }
24824 unset($c);
24825
24826 // If rowspans overlap so that one or more rows do not have a height set...
24827 // i.e. for one or more rows, the only cells (explicit) in that row have rowspan>1
24828 // so heightrow is still == 0
24829 if ($heightrow[$i]==0) {
24830 // Get row extent to analyse above and below
24831 $top = $i;
24832 foreach ($listspan as $checkspan) {
24833 list($cki,$ckj) = $checkspan;
24834 if ($this->cacheTables) {
24835 $c = $this->_uncacheCell($table['cells'][$cki][$ckj], '', $fh);
24836 }
24837 else
24838 $c = &$cells[$cki][$ckj];
24839 if (isset($c['rowspan']) && $c['rowspan']>1) {
24840 if (($cki + $c['rowspan']-1) >= $i) { $top = min($top, $cki); }
24841 }
24842 }
24843 $bottom = $i + $c['rowspan']-1;
24844 // Check for overconstrained conditions
24845 for ($k=$top; $k<=$bottom; $k++) {
24846 // if ['hr'] for any of the others is also 0, then abort (too complicated)
24847 if ($k != $i && $heightrow[$k]==0) { break(1); }
24848 // check again that top and bottom are not crossed by rowspans - or abort (too complicated)
24849 if ($k==$top) {
24850 // ???? take account of colspan as well???
24851 for( $m = 0 ; $m < $numcols ; $m++ ) { //columns
24852 if (!isset($cells[$k][$m]) || $cells[$k][$m]==0) {
24853 break(2);
24854 }
24855 }
24856 }
24857 else if ($k==$bottom) {
24858 // ???? take account of colspan as well???
24859 for( $m = 0 ; $m < $numcols ; $m++ ) { //columns
24860 if ($this->cacheTables) {
24861 $c = $this->_uncacheCell($table['cells'][$k][$m], '', $fh);
24862 }
24863 else
24864 $c = &$cells[$k][$m];
24865 if (isset($c['rowspan']) && $c['rowspan']>1) {
24866 break(2);
24867 }
24868 }
24869 }
24870 }
24871 // By columns add up col height using ['h'] if set or ['mih'] if not
24872 // Intentionally do not substract border-spacing
24873 $colH = array();
24874 $extH = 0;
24875 $newhr = array();
24876 for( $m = 0 ; $m < $numcols ; $m++ ) { //columns
24877 for ($k=$top; $k<=$bottom; $k++) {
24878 if (isset($cells[$k][$m]) && $cells[$k][$m]!=0) {
24879 if ($this->cacheTables) {
24880 $c = $this->_uncacheCell($table['cells'][$k][$m], '', $fh);
24881 }
24882 else
24883 $c = &$cells[$k][$m];
24884 if (isset($c['h']) && $c['h']) {
24885 $useh = $c['h'];
24886 }
24887 // ???? take account of colspan as well???
24888 else {
24889 $useh = $c['mih'];
24890 }
24891 $colH[$m] += $useh;
24892 if (!isset($c['rowspan']) || $c['rowspan']<2) { $newhr[$k] = max($newhr[$k], $useh); }
24893 }
24894 }
24895 $extH = max($tabH, $colH[$m]);
24896 }
24897 $newhr[$i] = $extH - array_sum($newhr);
24898 for ($k=$top; $k<=$bottom; $k++) { $heightrow[$k] = $newhr[$k]; }
24899 }
24900
24901
24902 unset($c);
24903 }
24904
24905 $table['h'] = array_sum($heightrow);
24906 unset($heightrow);
24907
24908 if ($this->cacheTables) { fclose($fh); }
24909
24910 if ($table['borders_separate']) {
24911 $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'];
24912 }
24913 else {
24914 $table['h'] += $table['margin']['T'] + $table['margin']['B'] + $table['max_cell_border_width']['T']/2 + $table['max_cell_border_width']['B']/2;
24915 }
24916
24917 $maxrowheight = $checkmaxheightplus + $headerrowheightplus + $footerrowheightplus;
24918 $maxfirstrowheight = $firstrowheight + $headerrowheightplus + $footerrowheightplus; // includes thead, 1st row and tfoot
24919 return array($table['h'],$maxrowheight,$temppgheight,$remainingpage,$maxfirstrowheight);
24920 }
24921
24922 function _tableGetWidth(&$table, $i,$j, $fh){
24923 if ($this->cacheTables) {
24924 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24925 }
24926 else
24927 $cell = &$table['cells'][$i][$j];
24928 if ($cell) {
24929 if (isset($cell['x0'])) { return array($cell['x0'], $cell['w0']); }
24930 $x = 0;
24931 $widthcols = &$table['wc'];
24932 for( $k = 0 ; $k < $j ; $k++ ) $x += $widthcols[$k];
24933 $w = $widthcols[$j];
24934 if (isset($cell['colspan'])) {
24935 for ( $k = $j+$cell['colspan']-1 ; $k > $j ; $k-- ) $w += $widthcols[$k];
24936 }
24937 $cell['x0'] = $x;
24938 $cell['w0'] = $w;
24939 if ($this->cacheTables) {
24940 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'x0');
24941 }
24942 return array($x, $w);
24943 }
24944 return array(0,0);
24945 }
24946
24947 function _splitTableGetWidth(&$table, $i,$j, $fh){
24948 if ($this->cacheTables) {
24949 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24950 }
24951 else
24952 $cell = &$table['cells'][$i][$j];
24953 if ($cell) {
24954 if (isset($cell['x0'])) return array($cell['x0'], $cell['w0']);
24955 $x = 0;
24956 $widthcols = &$table['wc'];
24957 $pg = $table['colPg'][$j];
24958 for( $k = 0 ; $k < $j ; $k++ ) {
24959 if ($table['colPg'][$k]==$pg) $x += $widthcols[$k];
24960 }
24961 $w = $widthcols[$j];
24962 if (isset($cell['colspan'])) {
24963 for ( $k = $j+$cell['colspan']-1 ; $k > $j ; $k-- ) if ($table['colPg'][$k]==$pg) $w += $widthcols[$k];
24964 }
24965 $cell['x0'] = $x;
24966 $cell['w0'] = $w;
24967 if ($this->cacheTables) {
24968 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'x0');
24969 }
24970 return array($x, $w);
24971 }
24972 return array(0,0);
24973 }
24974
24975
24976 function _tableGetHeight(&$table, $i,$j, $fh){
24977 if ($this->cacheTables) {
24978 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
24979 }
24980 else
24981 $cell = &$table['cells'][$i][$j];
24982 if ($cell){
24983 if (isset($cell['y0'])) return array($cell['y0'], $cell['h0']);
24984 $y = 0;
24985 $heightrow = &$table['hr'];
24986 for ($k=0;$k<$i;$k++) $y += $heightrow[$k];
24987 $h = $heightrow[$i];
24988 if (isset($cell['rowspan'])){
24989 for ($k=$i+$cell['rowspan']-1;$k>$i;$k--)
24990 $h += $heightrow[$k];
24991 }
24992 $cell['y0'] = $y;
24993 $cell['h0'] = $h;
24994 if ($this->cacheTables) {
24995 $this->_cacheUpdateMtx($cell, $fh, $table['cells'][$i][$j], 'y0');
24996 }
24997 return array($y, $h);
24998 }
24999 return array(0,0);
25000 }
25001
25002 function _tableGetMaxRowHeight($table, $row, $fh) {
25003 if ($row==$table['nc']-1) { return $table['hr'][$row]; }
25004 $maxrowheight = $table['hr'][$row];
25005 for ($i=$row+1;$i<$table['nr'];$i++) {
25006 $cellsset = 0;
25007 for ($j=0;$j<$table['nc'];$j++) {
25008 if ($this->cacheTables) {
25009 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25010 if ($cell) {
25011 if (isset($cell['colspan'])) { $cellsset += $cell['colspan']; }
25012 else $cellsset += 1;
25013 }
25014 }
25015 else {
25016 if ($table['cells'][$i][$j]) {
25017 if (isset($table['cells'][$i][$j]['colspan'])) { $cellsset += $table['cells'][$i][$j]['colspan']; }
25018 else $cellsset += 1;
25019 }
25020 }
25021 }
25022 if ($cellsset == $table['nc']) { return $maxrowheight; }
25023 else { $maxrowheight += $table['hr'][$i]; }
25024 }
25025 return $maxrowheight;
25026 }
25027
25028
25029 // CHANGED TO ALLOW TABLE BORDER TO BE SPECIFIED CORRECTLY - added border_details
25030 function _tableRect($x, $y, $w, $h, $bord=-1, $details=array(), $buffer=false, $bSeparate=false, $cort='cell', $tablecorner='', $bsv=0, $bsh=0) {
25031 $cellBorderOverlay = array();
25032
25033 if ($bord==-1) { $this->Rect($x, $y, $w, $h); }
25034 else if ($this->simpleTables && ($cort=='cell')) {
25035 $this->SetLineWidth($details['L']['w']);
25036 if ($details['L']['c']) {
25037 $this->SetDColor($details['L']['c']);
25038 }
25039 else { $this->SetDColor($this->ConvertColor(0)); }
25040 $this->SetLineJoin(0);
25041 $this->Rect($x, $y, $w, $h);
25042 }
25043 else if ($bord){
25044 if (!$bSeparate && $buffer) {
25045 $priority = 'LRTB';
25046 for($p=0;$p<strlen($priority);$p++) {
25047 $side = $priority[$p];
25048 $details['p'] = $side ;
25049
25050 $dom = 0;
25051 if (isset($details[$side]['w'])) { $dom += ($details[$side]['w'] * 100000); }
25052 if (isset($details[$side]['style'])) { $dom += (array_search($details[$side]['style'],$this->borderstyles)*100) ; }
25053 if (isset($details[$side]['dom'])) { $dom += ($details[$side]['dom']*10); }
25054
25055 // Precedence to darker colours at joins
25056 $coldom = 0;
25057 if (isset($details[$side]['c']) && is_array($details[$side]['c'])) {
25058 if ($details[$side]['c']{0}==3) { // RGB
25059 $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);
25060 }
25061 } // 10 black - 0 white
25062 if ($coldom) { $dom += $coldom; }
25063 // Lastly precedence to RIGHT and BOTTOM cells at joins
25064 if (isset($details['cellposdom'])) { $dom += $details['cellposdom']; }
25065
25066 $save = false;
25067 if ($side == 'T' && $this->issetBorder($bord, _BORDER_TOP)) { $cbord = _BORDER_TOP; $save = true; }
25068 else if ($side == 'L' && $this->issetBorder($bord, _BORDER_LEFT)) { $cbord = _BORDER_LEFT; $save = true; }
25069 else if ($side == 'R' && $this->issetBorder($bord, _BORDER_RIGHT)) { $cbord = _BORDER_RIGHT; $save = true; }
25070 else if ($side == 'B' && $this->issetBorder($bord, _BORDER_BOTTOM)) { $cbord = _BORDER_BOTTOM; $save = true; }
25071
25072 if ($save) {
25073 $this->cellBorderBuffer[] = pack("A16nCnda6A10d14",
25074 str_pad(sprintf("%08.7f", $dom),16,"0",STR_PAD_LEFT),
25075 $cbord,
25076 ord($side),
25077 $details[$side]['s'],
25078 $details[$side]['w'],
25079 $details[$side]['c'],
25080 $details[$side]['style'],
25081 $x, $y, $w, $h,
25082 $details['mbw']['BL'],
25083 $details['mbw']['BR'],
25084 $details['mbw']['RT'],
25085 $details['mbw']['RB'],
25086 $details['mbw']['TL'],
25087 $details['mbw']['TR'],
25088 $details['mbw']['LT'],
25089 $details['mbw']['LB'],
25090 $details['cellposdom'],
25091 0
25092 );
25093 if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'groove' || $details[$side]['style'] == 'inset' || $details[$side]['style'] == 'outset' || $details[$side]['style'] == 'double' ) {
25094 $details[$side]['overlay'] = true;
25095 $this->cellBorderBuffer[] = pack("A16nCnda6A10d14",
25096 str_pad(sprintf("%08.7f", ($dom+4)),16,"0",STR_PAD_LEFT),
25097 $cbord,
25098 ord($side),
25099 $details[$side]['s'],
25100 $details[$side]['w'],
25101 $details[$side]['c'],
25102 $details[$side]['style'],
25103 $x, $y, $w, $h,
25104 $details['mbw']['BL'],
25105 $details['mbw']['BR'],
25106 $details['mbw']['RT'],
25107 $details['mbw']['RB'],
25108 $details['mbw']['TL'],
25109 $details['mbw']['TR'],
25110 $details['mbw']['LT'],
25111 $details['mbw']['LB'],
25112 $details['cellposdom'],
25113 1
25114 );
25115 }
25116 }
25117 }
25118 return;
25119 }
25120
25121 if (isset($details['p']) && strlen($details['p'])>1) { $priority = $details['p']; }
25122 else { $priority='LTRB'; }
25123 $Tw = 0;
25124 $Rw = 0;
25125 $Bw = 0;
25126 $Lw = 0;
25127 if (isset($details['T']['w'])) { $Tw = $details['T']['w']; }
25128 if (isset($details['R']['w'])) { $Rw = $details['R']['w']; }
25129 if (isset($details['B']['w'])) { $Bw = $details['B']['w']; }
25130 if (isset($details['L']['w'])) { $Lw = $details['L']['w']; }
25131
25132 $x2 = $x + $w; $y2 = $y + $h;
25133 $oldlinewidth = $this->LineWidth;
25134
25135 for($p=0;$p<strlen($priority);$p++) {
25136 $side = $priority[$p];
25137 $xadj = 0;
25138 $xadj2 = 0;
25139 $yadj = 0;
25140 $yadj2 = 0;
25141 $print = false;
25142 if ($Tw && $side=='T' && $this->issetBorder($bord, _BORDER_TOP)) { // TOP
25143 $ly1 = $y;
25144 $ly2 = $y;
25145 $lx1 = $x;
25146 $lx2 = $x2;
25147 $this->SetLineWidth($Tw);
25148 if ($cort == 'cell' || strpos($tablecorner,'L')!==false) {
25149 if ($Tw > $Lw) $xadj = ($Tw - $Lw)/2;
25150 if ($Tw < $Lw) $xadj = ($Tw + $Lw)/2;
25151 }
25152 else { $xadj = $Tw/2 - $bsh/2; }
25153 if ($cort == 'cell' || strpos($tablecorner,'R')!==false) {
25154 if ($Tw > $Rw) $xadj2 = ($Tw - $Rw)/2;
25155 if ($Tw < $Rw) $xadj2 = ($Tw + $Rw)/2;
25156 }
25157 else { $xadj2 = $Tw/2 - $bsh/2; }
25158 if (!$bSeparate && $details['mbw']['TL']) {
25159 $xadj = ($Tw - $details['mbw']['TL'])/2 ;
25160 }
25161 if (!$bSeparate && $details['mbw']['TR']) {
25162 $xadj2 = ($Tw - $details['mbw']['TR'])/2;
25163 }
25164 $print = true;
25165 }
25166 if ($Lw && $side=='L' && $this->issetBorder($bord, _BORDER_LEFT)) { // LEFT
25167 $ly1 = $y;
25168 $ly2 = $y2;
25169 $lx1 = $x;
25170 $lx2 = $x;
25171 $this->SetLineWidth($Lw);
25172 if ($cort == 'cell' || strpos($tablecorner,'T')!==false) {
25173 if ($Lw > $Tw) $yadj = ($Lw - $Tw)/2;
25174 if ($Lw < $Tw) $yadj = ($Lw + $Tw)/2;
25175 }
25176 else { $yadj = $Lw/2 - $bsv/2; }
25177 if ($cort == 'cell' || strpos($tablecorner,'B')!==false) {
25178 if ($Lw > $Bw) $yadj2 = ($Lw - $Bw)/2;
25179 if ($Lw < $Bw) $yadj2 = ($Lw + $Bw)/2;
25180 }
25181 else { $yadj2 = $Lw/2 - $bsv/2; }
25182 if (!$bSeparate && $details['mbw']['LT']) {
25183 $yadj = ($Lw - $details['mbw']['LT'])/2;
25184 }
25185 if (!$bSeparate && $details['mbw']['LB']) {
25186 $yadj2 = ($Lw - $details['mbw']['LB'])/2;
25187 }
25188 $print = true;
25189 }
25190 if ($Rw && $side=='R' && $this->issetBorder($bord, _BORDER_RIGHT)) { // RIGHT
25191 $ly1 = $y;
25192 $ly2 = $y2;
25193 $lx1 = $x2;
25194 $lx2 = $x2;
25195 $this->SetLineWidth($Rw);
25196 if ($cort == 'cell' || strpos($tablecorner,'T')!==false) {
25197 if ($Rw < $Tw) $yadj = ($Rw + $Tw)/2;
25198 if ($Rw > $Tw) $yadj = ($Rw - $Tw)/2;
25199 }
25200 else { $yadj = $Rw/2 - $bsv/2; }
25201
25202 if ($cort == 'cell' || strpos($tablecorner,'B')!==false) {
25203 if ($Rw > $Bw) $yadj2 = ($Rw - $Bw)/2;
25204 if ($Rw < $Bw) $yadj2 = ($Rw + $Bw)/2;
25205 }
25206 else { $yadj2 = $Rw/2 - $bsv/2; }
25207
25208 if (!$bSeparate && $details['mbw']['RT']) {
25209 $yadj = ($Rw - $details['mbw']['RT'])/2;
25210 }
25211 if (!$bSeparate && $details['mbw']['RB']) {
25212 $yadj2 = ($Rw - $details['mbw']['RB'])/2;
25213 }
25214 $print = true;
25215 }
25216 if ($Bw && $side=='B' && $this->issetBorder($bord, _BORDER_BOTTOM)) { // BOTTOM
25217 $ly1 = $y2;
25218 $ly2 = $y2;
25219 $lx1 = $x;
25220 $lx2 = $x2;
25221 $this->SetLineWidth($Bw);
25222 if ($cort == 'cell' || strpos($tablecorner,'L')!==false) {
25223 if ($Bw > $Lw) $xadj = ($Bw - $Lw)/2;
25224 if ($Bw < $Lw) $xadj = ($Bw + $Lw)/2;
25225 }
25226 else { $xadj = $Bw/2 - $bsh/2; }
25227 if ($cort == 'cell' || strpos($tablecorner,'R')!==false) {
25228 if ($Bw > $Rw) $xadj2 = ($Bw - $Rw)/2;
25229 if ($Bw < $Rw) $xadj2 = ($Bw + $Rw)/2;
25230 }
25231 else { $xadj2 = $Bw/2 - $bsh/2; }
25232 if (!$bSeparate && $details['mbw']['BL']) {
25233 $xadj = ($Bw - $details['mbw']['BL'])/2;
25234 }
25235 if (!$bSeparate && $details['mbw']['BR']) {
25236 $xadj2 = ($Bw - $details['mbw']['BR'])/2;
25237 }
25238 $print = true;
25239 }
25240
25241 // Now draw line
25242 if ($print) {
25243 /*-- TABLES-ADVANCED-BORDERS --*/
25244 if ($details[$side]['style'] == 'double') {
25245 if (!isset($details[$side]['overlay']) || !$details[$side]['overlay'] || $bSeparate) {
25246 if ($details[$side]['c']) {
25247 $this->SetDColor($details[$side]['c']);
25248 }
25249 else { $this->SetDColor($this->ConvertColor(0)); }
25250 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
25251 }
25252 if ((isset($details[$side]['overlay']) && $details[$side]['overlay']) || $bSeparate) {
25253 if ($bSeparate && $cort=='table') {
25254 if ($side=='T') {
25255 $xadj -= $this->LineWidth/2;
25256 $xadj2 -= $this->LineWidth;
25257 if ($this->issetBorder($bord, _BORDER_LEFT)) {
25258 $xadj += $this->LineWidth/2;
25259 }
25260 if ($this->issetBorder($bord, _BORDER_RIGHT)) {
25261 $xadj2 += $this->LineWidth;
25262 }
25263 }
25264 if ($side=='L') {
25265 $yadj -= $this->LineWidth/2;
25266 $yadj2 -= $this->LineWidth;
25267 if ($this->issetBorder($bord, _BORDER_TOP)) {
25268 $yadj += $this->LineWidth/2;
25269 }
25270 if ($this->issetBorder($bord, _BORDER_BOTTOM)) {
25271 $yadj2 += $this->LineWidth;
25272 }
25273 }
25274 if ($side=='B') {
25275 $xadj -= $this->LineWidth/2;
25276 $xadj2 -= $this->LineWidth;
25277 if ($this->issetBorder($bord, _BORDER_LEFT)) {
25278 $xadj += $this->LineWidth/2;
25279 }
25280 if ($this->issetBorder($bord, _BORDER_RIGHT)) {
25281 $xadj2 += $this->LineWidth;
25282 }
25283 }
25284 if ($side=='R') {
25285 $yadj -= $this->LineWidth/2;
25286 $yadj2 -= $this->LineWidth;
25287 if ($this->issetBorder($bord, _BORDER_TOP)) {
25288 $yadj += $this->LineWidth/2;
25289 }
25290 if ($this->issetBorder($bord, _BORDER_BOTTOM)) {
25291 $yadj2 += $this->LineWidth;
25292 }
25293 }
25294 }
25295
25296 $this->SetLineWidth($this->LineWidth/3);
25297
25298 $tbcol = $this->ConvertColor(255);
25299 for($l=0; $l <= $this->blklvl; $l++) {
25300 if ($this->blk[$l]['bgcolor']) {
25301 $tbcol = ($this->blk[$l]['bgcolorarray']); // mPDF 5.6.53
25302 }
25303 }
25304
25305 if ($bSeparate) {
25306 $cellBorderOverlay[] = array(
25307 'x' => $lx1 + $xadj,
25308 'y' => $ly1 + $yadj,
25309 'x2' => $lx2 - $xadj2,
25310 'y2' => $ly2 - $yadj2,
25311 'col' => $tbcol,
25312 'lw' => $this->LineWidth,
25313 );
25314 }
25315 else {
25316 $this->SetDColor($tbcol);
25317 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
25318 }
25319 }
25320 }
25321
25322
25323 else if (isset($details[$side]['style']) && ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'groove' || $details[$side]['style'] == 'inset' || $details[$side]['style'] == 'outset')) {
25324 if (!isset($details[$side]['overlay']) || !$details[$side]['overlay'] || $bSeparate) {
25325 if ($details[$side]['c']) {
25326 $this->SetDColor($details[$side]['c']);
25327 }
25328 else { $this->SetDColor($this->ConvertColor(0)); }
25329 if ($details[$side]['style'] == 'outset' || $details[$side]['style'] == 'groove') {
25330 $nc = $this->_darkenColor($details[$side]['c']);
25331 $this->SetDColor($nc);
25332 }
25333 else if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'inset') {
25334 $nc = $this->_lightenColor($details[$side]['c']);
25335 $this->SetDColor($nc);
25336 }
25337 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
25338 }
25339 if ((isset($details[$side]['overlay']) && $details[$side]['overlay']) || $bSeparate) {
25340 if ($details[$side]['c']) {
25341 $this->SetDColor($details[$side]['c']);
25342 }
25343 else { $this->SetDColor($this->ConvertColor(0)); }
25344 $doubleadj = ($this->LineWidth)/3;
25345 $this->SetLineWidth($this->LineWidth/2);
25346 $xadj3 = $yadj3 = $wadj3 = $hadj3 = 0;
25347
25348 if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'inset') {
25349 $nc = $this->_darkenColor($details[$side]['c']);
25350
25351 if ($bSeparate && $cort=='table') {
25352 if ($side=='T') {
25353 $yadj3 = $this->LineWidth/2;
25354 $xadj3 = -$this->LineWidth/2;
25355 $wadj3 = $this->LineWidth;
25356 if ($this->issetBorder($bord, _BORDER_LEFT)) {
25357 $xadj3 += $this->LineWidth; $wadj3 -= $this->LineWidth;
25358 }
25359 if ($this->issetBorder($bord, _BORDER_RIGHT)) {
25360 $wadj3 -= $this->LineWidth*2;
25361 }
25362 }
25363 if ($side=='L') {
25364 $xadj3 = $this->LineWidth/2;
25365 $yadj3 = -$this->LineWidth/2;
25366 $hadj3 = $this->LineWidth;
25367 if ($this->issetBorder($bord, _BORDER_TOP)) {
25368 $yadj3 += $this->LineWidth; $hadj3 -= $this->LineWidth;
25369 }
25370 if ($this->issetBorder($bord, _BORDER_BOTTOM)) {
25371 $hadj3 -= $this->LineWidth*2;
25372 }
25373 }
25374 if ($side=='B') {
25375 $yadj3 = $this->LineWidth/2;
25376 $xadj3 = -$this->LineWidth/2;
25377 $wadj3 = $this->LineWidth;
25378 }
25379 if ($side=='R') {
25380 $xadj3 = $this->LineWidth/2;
25381 $yadj3 = -$this->LineWidth/2;
25382 $hadj3 = $this->LineWidth;
25383 }
25384 }
25385
25386 else if ($side=='T') { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; $wadj3 = -$this->LineWidth*2; }
25387 else if ($side=='L') { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; $hadj3 = -$this->LineWidth*2; }
25388
25389 else if ($side=='B' && $bSeparate) { $yadj3 = $this->LineWidth/2; $wadj3 = $this->LineWidth/2; }
25390 else if ($side=='R' && $bSeparate) { $xadj3 = $this->LineWidth/2; $hadj3 = $this->LineWidth/2; }
25391
25392 else if ($side=='B') { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; }
25393 else if ($side=='R') { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; }
25394 }
25395 else {
25396 $nc = $this->_lightenColor($details[$side]['c']);
25397
25398 if ($bSeparate && $cort=='table') {
25399 if ($side=='T') {
25400 $yadj3 = $this->LineWidth/2;
25401 $xadj3 = -$this->LineWidth/2;
25402 $wadj3 = $this->LineWidth;
25403 if ($this->issetBorder($bord, _BORDER_LEFT)) {
25404 $xadj3 += $this->LineWidth; $wadj3 -= $this->LineWidth;
25405 }
25406 }
25407 if ($side=='L') {
25408 $xadj3 = $this->LineWidth/2;
25409 $yadj3 = -$this->LineWidth/2;
25410 $hadj3 = $this->LineWidth;
25411 if ($this->issetBorder($bord, _BORDER_TOP)) {
25412 $yadj3 += $this->LineWidth; $hadj3 -= $this->LineWidth;
25413 }
25414 }
25415 if ($side=='B') {
25416 $yadj3 = $this->LineWidth/2;
25417 $xadj3 = -$this->LineWidth/2;
25418 $wadj3 = $this->LineWidth;
25419 if ($this->issetBorder($bord, _BORDER_LEFT)) {
25420 $xadj3 += $this->LineWidth; $wadj3 -= $this->LineWidth;
25421 }
25422 }
25423 if ($side=='R') {
25424 $xadj3 = $this->LineWidth/2;
25425 $yadj3 = -$this->LineWidth/2;
25426 $hadj3 = $this->LineWidth;
25427 if ($this->issetBorder($bord, _BORDER_TOP)) {
25428 $yadj3 += $this->LineWidth; $hadj3 -= $this->LineWidth;
25429 }
25430 }
25431 }
25432
25433 else if ($side=='T') { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; }
25434 else if ($side=='L') { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; }
25435
25436 else if ($side=='B' && $bSeparate) { $yadj3 = $this->LineWidth/2; $xadj3 = $this->LineWidth/2; }
25437 else if ($side=='R' && $bSeparate) { $xadj3 = $this->LineWidth/2; $yadj3 = $this->LineWidth/2; }
25438
25439 else if ($side=='B') { $yadj3 = $this->LineWidth/2; $xadj3 = -$this->LineWidth/2; $wadj3 = $this->LineWidth; }
25440 else if ($side=='R') { $xadj3 = $this->LineWidth/2; $yadj3 = -$this->LineWidth/2; $hadj3 = $this->LineWidth; }
25441
25442 }
25443
25444 if ($bSeparate) {
25445 $cellBorderOverlay[] = array(
25446 'x' => $lx1 + $xadj + $xadj3,
25447 'y' => $ly1 + $yadj + $yadj3,
25448 'x2' => $lx2 - $xadj2 + $xadj3 + $wadj3,
25449 'y2' => $ly2 - $yadj2 + $yadj3 + $hadj3,
25450 'col' => $nc,
25451 'lw' => $this->LineWidth,
25452 );
25453 }
25454 else {
25455 $this->SetDColor($nc);
25456 $this->Line($lx1 + $xadj + $xadj3, $ly1 + $yadj + $yadj3, $lx2 - $xadj2 + $xadj3 + $wadj3, $ly2 - $yadj2 + $yadj3 + $hadj3);
25457 }
25458 }
25459 }
25460
25461
25462 else {
25463 /*-- END TABLES-ADVANCED-BORDERS --*/
25464 if ($details[$side]['style'] == 'dashed') {
25465 $dashsize = 2; // final dash will be this + 1*linewidth
25466 $dashsizek = 1.5; // ratio of Dash/Blank
25467 $this->SetDash($dashsize,($dashsize/$dashsizek)+($this->LineWidth*2));
25468 }
25469 else if ($details[$side]['style'] == 'dotted') {
25470 $this->SetLineJoin(1);
25471 $this->SetLineCap(1);
25472 $this->SetDash(0.001,($this->LineWidth*2));
25473 }
25474 if ($details[$side]['c']) {
25475 $this->SetDColor($details[$side]['c']);
25476 }
25477 else { $this->SetDColor($this->ConvertColor(0)); }
25478 $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2);
25479 /*-- TABLES-ADVANCED-BORDERS --*/
25480 }
25481 /*-- END TABLES-ADVANCED-BORDERS --*/
25482
25483 // Reset Corners
25484 $this->SetDash();
25485 //BUTT style line cap
25486 $this->SetLineCap(2);
25487 }
25488 }
25489
25490 if ($bSeparate && count($cellBorderOverlay)) {
25491 foreach($cellBorderOverlay AS $cbo) {
25492 $this->SetLineWidth($cbo['lw']);
25493 $this->SetDColor($cbo['col']);
25494 $this->Line($cbo['x'], $cbo['y'], $cbo['x2'], $cbo['y2']);
25495 }
25496 }
25497
25498 // $this->SetLineWidth($oldlinewidth);
25499 // $this->SetDColor($this->ConvertColor(0));
25500 }
25501 }
25502
25503
25504 /*-- TABLES --*/
25505 /*-- TABLES-ADVANCED-BORDERS --*/
25506 function _lightenColor($c) {
25507 if (is_array($c)) { die('Color error in _lightencolor'); }
25508 if ($c{0}==3 || $c{0}==5) { // RGB
25509 list($h,$s,$l) = $this->rgb2hsl(ord($c{1})/255,ord($c{2})/255,ord($c{3})/255);
25510 $l += ((1 - $l)*0.8);
25511 list($r,$g,$b) = $this->hsl2rgb($h,$s,$l);
25512 $ret = array(3,$r,$g,$b);
25513 }
25514 else if ($c{0}==4 || $c{0}==6) { // CMYK
25515 $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)) );
25516 }
25517 else if ($c{0}==1) { // Grayscale
25518 $ret = array(1,min(255,(ord($c{1})+32)));
25519 }
25520 $c = array_pad($ret, 6, 0);
25521 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
25522 return $cstr;
25523 }
25524
25525
25526 function _darkenColor($c) {
25527 if (is_array($c)) { die('Color error in _darkenColor'); }
25528 if ($c{0}==3 || $c{0}==5) { // RGB
25529 list($h,$s,$l) = $this->rgb2hsl(ord($c{1})/255,ord($c{2})/255,ord($c{3})/255);
25530 $s *= 0.25;
25531 $l *= 0.75;
25532 list($r,$g,$b) = $this->hsl2rgb($h,$s,$l);
25533 $ret = array(3,$r,$g,$b);
25534 }
25535 else if ($c{0}==4 || $c{0}==6) { // CMYK
25536 $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)) );
25537 }
25538 else if ($c{0}==1) { // Grayscale
25539 $ret = array(1,max(0,(ord($c{1})-32)));
25540 }
25541 $c = array_pad($ret, 6, 0);
25542 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
25543 return $cstr;
25544 }
25545
25546 /*-- END TABLES-ADVANCED-BORDERS --*/
25547
25548
25549
25550 function setBorder(&$var, $flag, $set = true) {
25551 $flag = intval($flag);
25552 if ($set) { $set = true; }
25553 $var = intval($var);
25554 $var = $set ? ($var | $flag) : ($var & ~$flag);
25555 }
25556 function issetBorder($var, $flag) {
25557 $flag = intval($flag);
25558 $var = intval($var);
25559 return (($var & $flag) == $flag);
25560 }
25561
25562
25563 function _table2cellBorder(&$tableb, &$cbdb, &$cellb, $bval) {
25564 if ($tableb && $tableb['w'] > $cbdb['w']) {
25565 $cbdb = $tableb;
25566 $this->setBorder($cellb, $bval);
25567 }
25568 else if ($tableb && $tableb['w'] == $cbdb['w']
25569 && array_search($tableb['style'],$this->borderstyles) > array_search($cbdb['style'],$this->borderstyles)) {
25570 $cbdb = $tableb;
25571 $this->setBorder($cellb, $bval);
25572 }
25573 }
25574
25575 // FIX BORDERS ********************************************
25576 function _fixTableBorders(&$table){
25577 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
25578 else { $fh = null; }
25579
25580 if (!$table['borders_separate'] && $table['border_details']['L']['w']) {
25581 $table['max_cell_border_width']['L'] = $table['border_details']['L']['w'];
25582 }
25583 if (!$table['borders_separate'] && $table['border_details']['R']['w']) {
25584 $table['max_cell_border_width']['R'] = $table['border_details']['R']['w'];
25585 }
25586 if (!$table['borders_separate'] && $table['border_details']['T']['w']) {
25587 $table['max_cell_border_width']['T'] = $table['border_details']['T']['w'];
25588 }
25589 if (!$table['borders_separate'] && $table['border_details']['B']['w']) {
25590 $table['max_cell_border_width']['B'] = $table['border_details']['B']['w'];
25591 }
25592 if ($this->simpleTables) { return; }
25593 $cells = &$table['cells'];
25594 $numcols = $table['nc'];
25595 $numrows = $table['nr'];
25596 /*-- TABLES-ADVANCED-BORDERS --*/
25597 if (isset($table['topntail']) && $table['topntail']) { $tntborddet = $this->border_details($table['topntail']); }
25598 if (isset($table['thead-underline']) && $table['thead-underline']) { $thuborddet = $this->border_details($table['thead-underline']); }
25599 /*-- END TABLES-ADVANCED-BORDERS --*/
25600
25601 for( $i = 0 ; $i < $numrows ; $i++ ) { //Rows
25602 for( $j = 0 ; $j < $numcols ; $j++ ) { //Columns
25603 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
25604 if ($this->cacheTables) {
25605 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
25606 }
25607 else
25608 $cell = &$cells[$i][$j];
25609 if ($this->packTableData) { // includes $this->cacheTables
25610 $cbord = $this->_unpackCellBorder($cell['borderbin']);
25611 }
25612 else {
25613 $cbord = &$cells[$i][$j];
25614 }
25615 // mPDF 5.7.3
25616 if (!$cbord['border'] && $cbord['border']!==0 && isset($table['border']) && $table['border'] && $this->table_border_attr_set) {
25617 $cbord['border'] = $table['border'];
25618 $cbord['border_details'] = $table['border_details'];
25619 }
25620
25621 if (isset($cell['colspan']) && $cell['colspan']>1) { $ccolsp = $cell['colspan']; }
25622 else { $ccolsp = 1; }
25623 if (isset($cell['rowspan']) && $cell['rowspan']>1) { $crowsp = $cell['rowspan']; }
25624 else { $crowsp = 1; }
25625
25626 $cbord['border_details']['cellposdom'] = ((($i+1)/$numrows) / 10000 ) + ((($j+1)/$numcols) / 10 );
25627 // Inherit Cell border from Table border
25628 if ($this->table_border_css_set && !$table['borders_separate']) {
25629 if ($i == 0) {
25630 $this->_table2cellBorder($table['border_details']['T'], $cbord['border_details']['T'], $cbord['border'], _BORDER_TOP);
25631 }
25632 if ($i == ($numrows-1) || ($i+$crowsp) == ($numrows) ) {
25633 $this->_table2cellBorder($table['border_details']['B'], $cbord['border_details']['B'], $cbord['border'], _BORDER_BOTTOM);
25634 }
25635 if ($j == 0) {
25636 $this->_table2cellBorder($table['border_details']['L'], $cbord['border_details']['L'], $cbord['border'], _BORDER_LEFT);
25637 }
25638 if ($j == ($numcols-1) || ($j+$ccolsp) == ($numcols) ) {
25639 $this->_table2cellBorder($table['border_details']['R'], $cbord['border_details']['R'], $cbord['border'], _BORDER_RIGHT);
25640 }
25641 }
25642
25643 /*-- TABLES-ADVANCED-BORDERS --*/
25644 $fixbottom = true;
25645 if (isset($table['topntail']) && $table['topntail']) {
25646 if ($i == 0) {
25647 $cbord['border_details']['T'] = $tntborddet;
25648 $this->setBorder($cbord['border'], _BORDER_TOP);
25649 }
25650 if ($this->tableLevel==1 && $table['headernrows']>0 && $i == $table['headernrows']-1) {
25651 $cbord['border_details']['B'] = $tntborddet;
25652 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25653 $fixbottom = false;
25654 }
25655 else if ($this->tableLevel==1 && $table['headernrows']>0 && $i == $table['headernrows']) {
25656 if (!$table['borders_separate']) {
25657 $cbord['border_details']['T'] = $tntborddet;
25658 $this->setBorder($cbord['border'], _BORDER_TOP);
25659 }
25660 }
25661 if ($this->tableLevel==1 && $table['footernrows']>0 && $i == ($numrows-$table['footernrows']-1)) {
25662 if (!$table['borders_separate']) {
25663 $cbord['border_details']['B'] = $tntborddet;
25664 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25665 $fixbottom = false;
25666 }
25667 }
25668 else if ($this->tableLevel==1 && $table['footernrows']>0 && $i == ($numrows-$table['footernrows'])) {
25669 $cbord['border_details']['T'] = $tntborddet;
25670 $this->setBorder($cbord['border'], _BORDER_TOP);
25671 }
25672 if ($this->tabletheadjustfinished) { // $this->tabletheadjustfinished called from tableheader
25673 if (!$table['borders_separate']) {
25674 $cbord['border_details']['T'] = $tntborddet;
25675 $this->setBorder($cbord['border'], _BORDER_TOP);
25676 }
25677 }
25678 if ($i == ($numrows-1) || ($i+$crowsp) == ($numrows) ) {
25679 $cbord['border_details']['B'] = $tntborddet;
25680 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25681 }
25682 }
25683 if (isset($table['thead-underline']) && $table['thead-underline']) {
25684 if ($table['borders_separate']) {
25685 if ($i == 0) {
25686 $cbord['border_details']['B'] = $thuborddet;
25687 $this->setBorder($cbord['border'], _BORDER_BOTTOM);
25688 $fixbottom = false;
25689 }
25690 }
25691 else {
25692 if ($this->tableLevel==1 && $table['headernrows']>0 && $i == $table['headernrows']-1) {
25693 $cbord['border_details']['T'] = $thuborddet;
25694 $this->setBorder($cbord['border'], _BORDER_TOP);
25695 }
25696 else if ($this->tabletheadjustfinished) { // $this->tabletheadjustfinished called from tableheader
25697 $cbord['border_details']['T'] = $thuborddet;
25698 $this->setBorder($cbord['border'], _BORDER_TOP);
25699 }
25700 }
25701 }
25702
25703 // Collapse Border - Algorithm for conflicting borders
25704 // Hidden >> Width >> double>solid>dashed>dotted... >> style set on cell>table >> top/left>bottom/right
25705 // Do not turn off border which is overridden
25706 // Needed for page break for TOP/BOTTOM both to be defined in Collapsed borders
25707 // Means it is painted twice. (Left/Right can still disable overridden border)
25708 if (!$table['borders_separate']) {
25709 if (($i < ($numrows-1) || ($i+$crowsp) < $numrows ) && $fixbottom ) { // Bottom
25710 for ($cspi = 0; $cspi<$ccolsp; $cspi++) {
25711 // already defined Top for adjacent cell below
25712 if (isset($cells[($i+$crowsp)][$j+$cspi])) {
25713 if ($this->packTableData) {
25714 if ($this->cacheTables) {
25715 $adjc = $this->_uncacheCell($table['cells'][$i+$crowsp][$j+$cspi], '', $fh);
25716 }
25717 else { $adjc = $cells[($i+$crowsp)][$j+$cspi]; }
25718 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25719 }
25720 else { $celladj =& $cells[($i+$crowsp)][$j+$cspi]; }
25721 }
25722 else { $celladj = false; }
25723 if ($celladj && $celladj['border_details']['T']['s'] == 1) {
25724 $csadj = $celladj['border_details']['T']['w'];
25725 $csthis = $cbord['border_details']['B']['w'];
25726 // Hidden
25727 if ($cbord['border_details']['B']['style']=='hidden') {
25728 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25729 $this->setBorder($celladj['border'] , _BORDER_TOP, false);
25730 $this->setBorder($cbord['border'] , _BORDER_BOTTOM , false);
25731 }
25732 else if ($celladj['border_details']['T']['style']=='hidden') {
25733 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25734 $this->setBorder($cbord['border'] , _BORDER_BOTTOM , false);
25735 $this->setBorder($celladj['border'] , _BORDER_TOP, false);
25736 }
25737 // Width
25738 else if ($csthis > $csadj) {
25739 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
25740 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25741 $this->setBorder($cbord['border'] , _BORDER_BOTTOM);
25742 }
25743 }
25744 else if ($csadj > $csthis) {
25745 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25746 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25747 $this->setBorder($celladj['border'] , _BORDER_TOP);
25748 }
25749 }
25750
25751 // double>solid>dashed>dotted...
25752 else if (array_search($cbord['border_details']['B']['style'],$this->borderstyles) > array_search($celladj['border_details']['T']['style'],$this->borderstyles)) {
25753 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
25754 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25755 $this->setBorder($cbord['border'] , _BORDER_BOTTOM );
25756 }
25757 }
25758 else if (array_search($celladj['border_details']['T']['style'],$this->borderstyles) > array_search($cbord['border_details']['B']['style'],$this->borderstyles)) {
25759 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25760 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25761 $this->setBorder($celladj['border'] , _BORDER_TOP);
25762 }
25763 }
25764
25765
25766
25767 // Style set on cell vs. table
25768 else if ($celladj['border_details']['T']['dom'] > $cbord['border_details']['B']['dom']) {
25769 if ($ccolsp < 2) { // don't overwrite this cell if it spans
25770 $cbord['border_details']['B'] = $celladj['border_details']['T'];
25771 $this->setBorder($celladj['border'] , _BORDER_TOP);
25772 }
25773 }
25774 // Style set on cell vs. table - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT
25775 else {
25776 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
25777 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25778 $this->setBorder($cbord['border'] , _BORDER_BOTTOM );
25779 }
25780 }
25781 }
25782 else if ($celladj) {
25783 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
25784 $celladj['border_details']['T'] = $cbord['border_details']['B'];
25785 }
25786 }
25787 // mPDF 5.7.4
25788 if ($celladj && $this->packTableData) {
25789 $cells[$i+$crowsp][$j+$cspi]['borderbin'] = $this->_packCellBorder($celladj);
25790 }
25791 if ($this->cacheTables) {
25792 $this->_cacheUpdateBorder($celladj, $fh, $table['cells'][$i+$crowsp][$j+$cspi]);
25793 }
25794 unset($celladj);
25795 }
25796 }
25797
25798 if ($j < ($numcols-1) || ($j+$ccolsp) < $numcols ) { // Right-Left
25799 for ($cspi = 0; $cspi<$crowsp; $cspi++) {
25800 // already defined Left for adjacent cell to R
25801 if (isset($cells[($i+$cspi)][$j+$ccolsp])) {
25802 if ($this->packTableData) {
25803 if ($this->cacheTables) {
25804 $adjc = $this->_uncacheCell($table['cells'][$i+$cspi][$j+$ccolsp], '', $fh);
25805 }
25806 else { $adjc = $cells[($i+$cspi)][$j+$ccolsp]; }
25807 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25808 }
25809 else { $celladj =& $cells[$i+$cspi][$j+$ccolsp]; }
25810 }
25811 else { $celladj = false; }
25812 if ($celladj && $celladj['border_details']['L']['s'] == 1) {
25813 $csadj = $celladj['border_details']['L']['w'];
25814 $csthis = $cbord['border_details']['R']['w'];
25815 // Hidden
25816 if ($cbord['border_details']['R']['style']=='hidden') {
25817 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25818 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25819 $this->setBorder($cbord['border'] , _BORDER_RIGHT , false);
25820 }
25821 else if ($celladj['border_details']['L']['style']=='hidden') {
25822 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25823 $this->setBorder($cbord['border'] , _BORDER_RIGHT , false);
25824 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25825 }
25826 // Width
25827 else if ($csthis > $csadj) {
25828 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
25829 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25830 $this->setBorder($cbord['border'] , _BORDER_RIGHT);
25831 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25832 }
25833 }
25834 else if ($csadj > $csthis) {
25835 if ($crowsp < 2) { // don't overwrite this cell if it spans
25836 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25837 $this->setBorder($cbord['border'] , _BORDER_RIGHT, false);
25838 $this->setBorder($celladj['border'] , _BORDER_LEFT);
25839 }
25840 }
25841
25842 // double>solid>dashed>dotted...
25843 else if (array_search($cbord['border_details']['R']['style'],$this->borderstyles) > array_search($celladj['border_details']['L']['style'],$this->borderstyles)) {
25844 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
25845 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25846 $this->setBorder($celladj['border'] , _BORDER_LEFT, false);
25847 $this->setBorder($cbord['border'] , _BORDER_RIGHT);
25848 }
25849 }
25850 else if (array_search($celladj['border_details']['L']['style'],$this->borderstyles) > array_search($cbord['border_details']['R']['style'],$this->borderstyles)) {
25851 if ($crowsp < 2) { // don't overwrite this cell if it spans
25852 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25853 $this->setBorder($cbord['border'] , _BORDER_RIGHT , false);
25854 $this->setBorder($celladj['border'] , _BORDER_LEFT);
25855 }
25856 }
25857
25858
25859 // Style set on cell vs. table
25860 else if ($celladj['border_details']['L']['dom'] > $cbord['border_details']['R']['dom']) {
25861 if ($crowsp < 2) { // don't overwrite this cell if it spans
25862 $cbord['border_details']['R'] = $celladj['border_details']['L'];
25863 $this->setBorder($celladj['border'] , _BORDER_LEFT);
25864 }
25865 }
25866 // Style set on cell vs. table - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT
25867 else {
25868 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
25869 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25870 $this->setBorder($cbord['border'] , _BORDER_RIGHT);
25871 }
25872 }
25873 }
25874 else if ($celladj) {
25875 // if right-cell border is not set
25876 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
25877 $celladj['border_details']['L'] = $cbord['border_details']['R'];
25878 }
25879 }
25880 // mPDF 5.7.4
25881 if ($celladj && $this->packTableData) {
25882 $cells[$i+$cspi][$j+$ccolsp]['borderbin'] = $this->_packCellBorder($celladj);
25883 }
25884 if ($this->cacheTables) {
25885 $this->_cacheUpdateBorder($celladj, $fh, $table['cells'][$i+$cspi][$j+$ccolsp]);
25886 }
25887 unset($celladj);
25888 }
25889 }
25890 }
25891
25892
25893 // Set maximum cell border width meeting at LRTB edges of cell - used for extended cell border
25894 // ['border_details']['mbw']['LT'] = meeting border width - Left border - Top end
25895 if (!$table['borders_separate']) {
25896 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $cbord['border_details']['L']['w']);
25897 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $cbord['border_details']['R']['w']);
25898 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $cbord['border_details']['T']['w']);
25899 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $cbord['border_details']['B']['w']);
25900 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $cbord['border_details']['L']['w']);
25901 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $cbord['border_details']['R']['w']);
25902 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $cbord['border_details']['T']['w']);
25903 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $cbord['border_details']['B']['w']);
25904 if (($i+$crowsp) < $numrows && isset($cells[$i+$crowsp][$j])) { // Has Bottom adjoining cell
25905 if ($this->packTableData) {
25906 if ($this->cacheTables) {
25907 $adjc = $this->_uncacheCell($table['cells'][$i+$crowsp][$j], '', $fh);
25908 }
25909 else { $adjc = $cells[$i+$crowsp][$j]; }
25910 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25911 }
25912 else { $celladj =& $cells[$i+$crowsp][$j]; }
25913 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $celladj['border_details']['L']['w'], $celladj['border_details']['mbw']['TL']);
25914 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $celladj['border_details']['R']['w'], $celladj['border_details']['mbw']['TR']);
25915 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $celladj['border_details']['mbw']['LT']);
25916 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $celladj['border_details']['mbw']['RT']);
25917 unset($celladj);
25918 }
25919 if (($j+$ccolsp) < $numcols && isset($cells[$i][$j+$ccolsp])) { // Has Right adjoining cell
25920 if ($this->packTableData) {
25921 if ($this->cacheTables) {
25922 $adjc = $this->_uncacheCell($table['cells'][$i][$j+$ccolsp], '', $fh);
25923 }
25924 else { $adjc = $cells[$i][$j+$ccolsp]; }
25925 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25926 }
25927 else { $celladj =& $cells[$i][$j+$ccolsp]; }
25928 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $celladj['border_details']['T']['w'], $celladj['border_details']['mbw']['LT']);
25929 $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $celladj['border_details']['B']['w'], $celladj['border_details']['mbw']['LB']);
25930 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $celladj['border_details']['mbw']['TL']);
25931 $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $celladj['border_details']['mbw']['BL']);
25932 unset($celladj);
25933 }
25934
25935 if ($i > 0 && isset($cells[$i-1][$j]) && (($this->packTableData && $cells[$i-1][$j]['borderbin']) || $cells[$i-1][$j]['border'])) { // Has Top adjoining cell
25936 if ($this->packTableData) {
25937 if ($this->cacheTables) {
25938 $adjc = $this->_uncacheCell($table['cells'][$i-1][$j], '', $fh);
25939 }
25940 else { $adjc = $cells[$i-1][$j]; }
25941 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25942 }
25943 else { $celladj =& $cells[$i-1][$j]; }
25944 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['L']['w'], $celladj['border_details']['mbw']['BL']);
25945 $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $celladj['border_details']['R']['w'], $celladj['border_details']['mbw']['BR']);
25946 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $celladj['border_details']['mbw']['LB']);
25947 $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $celladj['border_details']['mbw']['RB']);
25948
25949 if ($celladj['border_details']['mbw']['BL']) {
25950 $celladj['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['mbw']['BL']);
25951 }
25952 if ($celladj['border_details']['mbw']['BR'] ) {
25953 $celladj['border_details']['mbw']['BR'] = max($celladj['border_details']['mbw']['BR'], $cbord['border_details']['mbw']['TR']);
25954 }
25955 if ($this->packTableData) { $cells[$i-1][$j]['borderbin'] = $this->_packCellBorder($celladj); }
25956 unset($celladj);
25957 }
25958 if ($j > 0 && isset($cells[$i][$j-1]) && (($this->packTableData && $cells[$i][$j-1]['borderbin']) || $cells[$i][$j-1]['border'])) { // Has Left adjoining cell
25959 if ($this->packTableData) {
25960 if ($this->cacheTables) {
25961 $adjc = $this->_uncacheCell($table['cells'][$i][$j-1], '', $fh);
25962 }
25963 else { $adjc = $cells[$i][$j-1]; }
25964 $celladj = $this->_unpackCellBorder($adjc['borderbin']);
25965 }
25966 else { $celladj =& $cells[$i][$j-1]; }
25967 $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $celladj['border_details']['T']['w'], $celladj['border_details']['mbw']['RT']);
25968 $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $celladj['border_details']['B']['w'], $celladj['border_details']['mbw']['RB']);
25969 $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $celladj['border_details']['mbw']['BR']);
25970 $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['mbw']['TR']);
25971
25972 if ($celladj['border_details']['mbw']['RT']) {
25973 $celladj['border_details']['mbw']['RT'] = max($celladj['border_details']['mbw']['RT'], $cbord['border_details']['mbw']['LT']);
25974 }
25975 if ($celladj['border_details']['mbw']['RB']) {
25976 $celladj['border_details']['mbw']['RB'] = max($celladj['border_details']['mbw']['RB'], $cbord['border_details']['mbw']['LB']);
25977 }
25978 if ($this->packTableData) { $cells[$i][$j-1]['borderbin'] = $this->_packCellBorder($celladj); }
25979 unset($celladj);
25980 }
25981
25982
25983 // Update maximum cell border width at LRTB edges of table - used for overall table width
25984 if ($j == 0 && $cbord['border_details']['L']['w']) {
25985 $table['max_cell_border_width']['L'] = max($table['max_cell_border_width']['L'],$cbord['border_details']['L']['w']);
25986 }
25987 if (($j == ($numcols-1) || ($j+$ccolsp) == $numcols ) && $cbord['border_details']['R']['w']) {
25988 $table['max_cell_border_width']['R'] = max($table['max_cell_border_width']['R'],$cbord['border_details']['R']['w']);
25989 }
25990 if ($i == 0 && $cbord['border_details']['T']['w']) {
25991 $table['max_cell_border_width']['T'] = max($table['max_cell_border_width']['T'],$cbord['border_details']['T']['w']);
25992 }
25993 if (($i == ($numrows-1) || ($i+$crowsp) == $numrows ) && $cbord['border_details']['B']['w']) {
25994 $table['max_cell_border_width']['B'] = max($table['max_cell_border_width']['B'],$cbord['border_details']['B']['w']);
25995 }
25996 }
25997 /*-- END TABLES-ADVANCED-BORDERS --*/
25998
25999 if ($this->packTableData) { $cell['borderbin'] = $this->_packCellBorder($cbord); }
26000
26001 if ($this->cacheTables) {
26002 $this->_cacheUpdateBorder($cell, $fh, $table['cells'][$i][$j]);
26003 }
26004 unset($cbord );
26005 unset($cell );
26006 }
26007 }
26008 }
26009 if ($this->cacheTables) { fclose($fh); }
26010 unset($cell );
26011 }
26012 // END FIX BORDERS ************************************************************************************
26013
26014
26015 function _reverseTableDir(&$table) {
26016 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
26017 $cells = &$table['cells'];
26018 $numcols = $table['nc'];
26019 $numrows = $table['nr'];
26020 for( $i = 0 ; $i < $numrows ; $i++ ) { //Rows
26021 $row = array();
26022 for( $j = ($numcols-1) ; $j >= 0 ; $j-- ) { //Columns
26023 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
26024 if ($this->cacheTables) {
26025 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
26026 }
26027 else
26028 $cell = &$cells[$i][$j];
26029 $col = $numcols - $j - 1;
26030 if (isset($cell['colspan']) && $cell['colspan'] > 1) { $col -= ($cell['colspan']-1); }
26031 // Nested content
26032 for ($n=0; $n < count($cell['textbuffer']); $n++) {
26033 $t = $cell['textbuffer'][$n][0];
26034 if (substr($t,0,19) == "\xbb\xa4\xactype=nestedtable") {
26035 $objattr = $this->_getObjAttr($t);
26036 $objattr['col'] = $col;
26037 $cell['textbuffer'][$n][0] = "\xbb\xa4\xactype=nestedtable,objattr=".serialize($objattr)."\xbb\xa4\xac";
26038 $this->table[($this->tableLevel+1)][$objattr['nestedcontent']]['nestedpos'][1] = $col;
26039 if ($this->cacheTables) {
26040 $this->_cacheUpdateTxB($cell, $fh, $table['cells'][$i][$j]);
26041 }
26042 }
26043 }
26044 $row[$col] = $cells[$i][$j];
26045 unset($cell);
26046 }
26047 }
26048 for($f=0; $f < $numcols; $f++) {
26049 if (!isset($row[$f])) { $row[$f] = 0; }
26050 }
26051 $table['cells'][$i] = $row;
26052 }
26053 if ($this->cacheTables) { fclose($fh); }
26054 }
26055
26056
26057 function _tableWrite(&$table, $split=false, $startrow=0, $startcol=0, $splitpg=0, $rety = 0){
26058 $level = $table['level'];
26059 $levelid = $table['levelid'];
26060
26061 $cells = &$table['cells'];
26062 $numcols = $table['nc'];
26063 $numrows = $table['nr'];
26064
26065 if ($this->ColActive && $level==1) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
26066
26067 if (!$split || ($startrow==0 && $splitpg==0) || $startrow>0){
26068 // TABLE TOP MARGIN
26069 if ($table['margin']['T']) {
26070 if (!$this->table_rotate && $level==1) {
26071 $this->DivLn($table['margin']['T'],$this->blklvl,true,1); // collapsible
26072 }
26073 else {
26074 $this->y += ($table['margin']['T']);
26075 }
26076 }
26077 // Advance down page by half width of top border
26078 if ($table['borders_separate']) {
26079 if ($startrow>0 && (!isset($table['is_thead']) || count($table['is_thead'])==0))
26080 $adv = $table['border_spacing_V']/2;
26081 else
26082 $adv = $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2;
26083 }
26084 else {
26085 $adv = $table['max_cell_border_width']['T']/2;
26086 }
26087 if (!$this->table_rotate && $level==1) { $this->DivLn($adv); }
26088 else { $this->y += $adv; }
26089 }
26090
26091 if ($level==1) {
26092 $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'];
26093 $x0 = $this->x;
26094 $y0 = $this->y;
26095 $right = $x0 + $this->blk[$this->blklvl]['inner_width'];
26096 $outerfilled = $this->y; // Keep track of how far down the outer DIV bgcolor is painted (NB rowspans)
26097 $this->outerfilled = $this->y;
26098 $this->colsums = array();
26099 }
26100 else {
26101 $x0 = $this->x;
26102 $y0 = $this->y;
26103 $right = $x0 + $table['w'];
26104 }
26105
26106 if ($this->table_rotate) {
26107 $temppgwidth = $this->tbrot_maxw;
26108 $this->PageBreakTrigger = $pagetrigger = $y0 + ($this->blk[$this->blklvl]['inner_width']);
26109 if ($level==1) {
26110 $this->tbrot_y0 = $this->y - $adv - $table['margin']['T'] ;
26111 $this->tbrot_x0 = $this->x;
26112 $this->tbrot_w = $table['w'];
26113 if ($table['borders_separate']) { $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2; }
26114 else { $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['max_cell_border_width']['T']; }
26115 }
26116 }
26117 else {
26118 $this->PageBreakTrigger = $pagetrigger = ($this->h - $this->bMargin);
26119 if ($level==1) {
26120 $temppgwidth = $this->blk[$this->blklvl]['inner_width'];
26121 if (isset($table['a']) and ($table['w'] < $this->blk[$this->blklvl]['inner_width'])) {
26122 if ($table['a']=='C') { $x0 += ((($right-$x0) - $table['w'])/2); }
26123 else if ($table['a']=='R') { $x0 = $right - $table['w']; }
26124 }
26125 }
26126 else {
26127 $temppgwidth = $table['w'];
26128 }
26129 }
26130 if(!isset($table['overflow'])) { $table['overflow'] = null; }
26131 if ($table['overflow']=='hidden' && $level==1 && !$this->table_rotate && !$this->ColActive) {
26132 //Bounding rectangle to clip
26133 $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);
26134 $this->_out($this->tableClipPath);
26135 }
26136 else { $this->tableClipPath = ''; }
26137
26138
26139 if ($table['borders_separate']) { $indent = $table['margin']['L'] + $table['border_details']['L']['w'] + $table['padding']['L'] + $table['border_spacing_H']/2; }
26140 else { $indent = $table['margin']['L'] + $table['max_cell_border_width']['L']/2; }
26141 $x0 += $indent;
26142
26143 $returny = 0;
26144 $lastCol = 0;
26145 $tableheader = array();
26146 $tablefooter = array();
26147 $tableheaderrowheight = 0;
26148 $tablefooterrowheight = 0;
26149 $footery = 0;
26150
26151 // mPD 3.0 Set the Page & Column where table starts
26152 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
26153 $tablestartpage = 'EVEN';
26154 }
26155 else if (($this->mirrorMargins) && (($this->page)%2==1)) { // ODD
26156 $tablestartpage = 'ODD';
26157 }
26158 else { $tablestartpage = ''; }
26159 if ($this->ColActive) { $tablestartcolumn = $this->CurrCol; }
26160 else { $tablestartcolumn = ''; }
26161
26162 if ($this->cacheTables) { $fh = fopen($table['cache'], "r+b"); }
26163 else { $fh = null; }
26164
26165 $y = $h = 0;
26166 for( $i = 0; $i < $numrows ; $i++ ) { //Rows
26167 if ($this->progressBar) { $this->UpdateProgressBar(7,intval(30 + ($i*40/$numrows)),' '); } // *PROGRESS-BAR*
26168 if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i] && $level==1) {
26169 $tablefooterrowheight += $table['hr'][$i];
26170 $tablefooter[$i][0]['trbackground-images'] = $table['trbackground-images'][$i];
26171 $tablefooter[$i][0]['trgradients'] = $table['trgradients'][$i];
26172 $tablefooter[$i][0]['trbgcolor'] = $table['bgcolor'][$i];
26173 for( $j = $startcol ; $j < $numcols ; $j++ ) { //Columns
26174 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
26175 if ($this->cacheTables) {
26176 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
26177 }
26178 else
26179 $cell = &$cells[$i][$j];
26180 if ($split) {
26181 if ($table['colPg'][$j] != $splitpg) { continue; }
26182 list($x,$w) = $this->_splitTableGetWidth($table, $i, $j, $fh);
26183 $js = $j - $startcol;
26184 }
26185 else {
26186 list($x,$w) = $this->_tableGetWidth($table, $i, $j, $fh);
26187 $js = $j;
26188 }
26189
26190 list($y,$h) = $this->_tableGetHeight($table, $i, $j, $fh);
26191 $x += $x0;
26192 $y += $y0;
26193 //Get info of tfoot ==>> table footer
26194 $tablefooter[$i][$js]['x'] = $x;
26195 $tablefooter[$i][$js]['y'] = $y;
26196 $tablefooter[$i][$js]['h'] = $h;
26197 $tablefooter[$i][$js]['w'] = $w;
26198 if (isset($cell['textbuffer'])) { $tablefooter[$i][$js]['textbuffer'] = $cell['textbuffer']; }
26199 else { $tablefooter[$i][$js]['textbuffer'] = ''; }
26200 $tablefooter[$i][$js]['a'] = $cell['a'];
26201 $tablefooter[$i][$js]['R'] = $cell['R'];
26202 $tablefooter[$i][$js]['va'] = $cell['va'];
26203 $tablefooter[$i][$js]['mih'] = $cell['mih'];
26204 $tablefooter[$i][$js]['gradient'] = $cell['gradient']; // *BACKGROUNDS*
26205 $tablefooter[$i][$js]['background-image'] = $cell['background-image']; // *BACKGROUNDS*
26206 //CELL FILL BGCOLOR
26207 if (!$this->simpleTables){
26208 if ($this->packTableData) {
26209 $c = $this->_unpackCellBorder($cell['borderbin']);
26210 $tablefooter[$i][$js]['border'] = $c['border'];
26211 $tablefooter[$i][$js]['border_details'] = $c['border_details'];
26212 }
26213 else {
26214 $tablefooter[$i][$js]['border'] = $cell['border'];
26215 $tablefooter[$i][$js]['border_details'] = $cell['border_details'];
26216 }
26217 }
26218 else if ($this->simpleTables){
26219 $tablefooter[$i][$js]['border'] = $table['simple']['border'];
26220 $tablefooter[$i][$js]['border_details'] = $table['simple']['border_details'];
26221 }
26222 $tablefooter[$i][$js]['bgcolor'] = $cell['bgcolor'];
26223 $tablefooter[$i][$js]['padding'] = $cell['padding'];
26224 $tablefooter[$i][$js]['rowspan'] = $cell['rowspan'];
26225 $tablefooter[$i][$js]['colspan'] = $cell['colspan'];
26226 }
26227 }
26228 }
26229 }
26230
26231 if ($level==1) { $this->_out('___TABLE___BACKGROUNDS'.$this->uniqstr); }
26232 $tableheaderadj = 0;
26233 $tablefooteradj = 0;
26234
26235 $tablestartpageno = $this->page;
26236
26237 //Draw Table Contents and Borders
26238 for( $i = 0; $i < $numrows ; $i++ ) { //Rows
26239 if ($split && $startrow > 0) {
26240 $thnr = (isset($table['is_thead']) ? count($table['is_thead']) : 0);
26241 if ($i >= $thnr && $i < $startrow) { continue; }
26242 if ($i == $startrow){ $returny = $rety - $tableheaderrowheight; }
26243 }
26244
26245 // Get Maximum row/cell height in row - including rowspan>1 + 1 overlapping
26246 $maxrowheight = $this->_tableGetMaxRowHeight($table, $i, $fh);
26247
26248 $skippage = false;
26249 $newpagestarted = false;
26250 for( $j = $startcol ; $j < $numcols ; $j++ ) { //Columns
26251 if ($split) {
26252 if ($table['colPg'][$j] > $splitpg) { break; }
26253 $lastCol = $j;
26254 }
26255 if (isset($cells[$i][$j]) && $cells[$i][$j]) {
26256 if ($this->cacheTables) {
26257 $cell = $this->_uncacheCell($table['cells'][$i][$j], '', $fh);
26258 }
26259 else
26260 $cell = &$cells[$i][$j];
26261 if ($split) {
26262 $lastCol = $j + (isset($cell['colspan']) ? ($cell['colspan']-1) : 0) ;
26263 list($x,$w) = $this->_splitTableGetWidth($table, $i, $j, $fh);
26264 }
26265 else { list($x,$w) = $this->_tableGetWidth($table, $i, $j, $fh); }
26266
26267 list($y,$h) = $this->_tableGetHeight($table, $i, $j, $fh);
26268 $x += $x0;
26269 $y += $y0;
26270 $y -= $returny;
26271
26272 if ($table['borders_separate']) {
26273 if (!empty($tablefooter) || $i == ($numrows-1) || (isset($cell['rowspan']) && ($i+$cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i+1) == $numrows) ) {
26274 $extra = $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
26275 //$extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
26276 }
26277 else {
26278 $extra = $table['border_spacing_V']/2;
26279 }
26280 }
26281 else { $extra = $table['max_cell_border_width']['B']/2; }
26282
26283 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 ) {
26284
26285 if (!$skippage) {
26286 $finalSpread = true;
26287 $firstSpread = true;
26288 if ($split) {
26289 for($t=$startcol; $t<$numcols; $t++) {
26290 // Are there more columns to print on a next page?
26291 if ($table['colPg'][$t] > $splitpg) {
26292 $finalSpread = false;
26293 break;
26294 }
26295 }
26296 if ($startcol>0) { $firstSpread = false; }
26297 }
26298
26299 if (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && $i > 0 ) {
26300 $this->y = $y;
26301 $ya = $this->y;
26302 $this->TableHeaderFooter($tablefooter,$tablestartpage,$tablestartcolumn,'F',$level, $firstSpread, $finalSpread);
26303 if ($this->table_rotate) {
26304 $this->tbrot_h += $this->y - $ya ;
26305 }
26306 $tablefooteradj = $this->y - $ya ;
26307 }
26308 $y -= $y0;
26309 $returny += $y;
26310
26311 $oldcolumn = $this->CurrCol;
26312 if ($this->AcceptPageBreak()) {
26313 $newpagestarted = true;
26314 $this->y = $y + $y0;
26315
26316 // Move down to account for border-spacing or
26317 // extra half border width in case page breaks in middle
26318 if($i>0 && !$this->table_rotate && $level==1 && !$this->ColActive) {
26319 if ($table['borders_separate']) {
26320 $adv = $table['border_spacing_V']/2;
26321 // If table footer
26322 if (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && $i > 0 ) {
26323 $adv += ($table['padding']['B'] + $table['border_details']['B']['w']);
26324 }
26325 }
26326 else {
26327 $maxbwtop = 0;
26328 $maxbwbottom = 0;
26329 if (!$this->simpleTables){
26330 if (!empty($tablefooter)) { $maxbwbottom = $table['max_cell_border_width']['B']; }
26331 else {
26332 $brow = $i-1;
26333 for( $ctj = 0 ; $ctj < $numcols ; $ctj++ ) {
26334 if (isset($cells[$brow][$ctj]) && $cells[$brow][$ctj]) {
26335 if ($this->cacheTables) {
26336 $cadj = $this->_uncacheCell($table['cells'][$brow][$ctj], '', $fh);
26337 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cadj['borderbin']);
26338 }
26339 else if ($this->packTableData) {
26340 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$brow][$ctj]['borderbin']);
26341 }
26342 else {
26343 $bb = $cells[$brow][$ctj]['border_details']['B']['w'];
26344 }
26345 $maxbwbottom = max($maxbwbottom , $bb);
26346 }
26347 }
26348 }
26349 if (!empty($tableheader)) { $maxbwtop = $table['max_cell_border_width']['T']; }
26350 else {
26351 $trow = $i-1;
26352 for( $ctj = 0 ; $ctj < $numcols ; $ctj++ ) {
26353 if (isset($cells[$trow][$ctj]) && $cells[$trow][$ctj]) {
26354 if ($this->cacheTables) {
26355 $cadj = $this->_uncacheCell($table['cells'][$trow][$ctj], '', $fh);
26356 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cadj['borderbin']);
26357 }
26358 else if ($this->packTableData) {
26359 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$trow][$ctj]['borderbin']);
26360 }
26361 else {
26362 $bt = $cells[$trow][$ctj]['border_details']['T']['w'];
26363 }
26364 $maxbwtop = max($maxbwtop , $bt);
26365 }
26366 }
26367 }
26368 }
26369 else if ($this->simpleTables){
26370 $maxbwtop = $table['simple']['border_details']['T']['w'];
26371 $maxbwbottom = $table['simple']['border_details']['B']['w'];
26372 }
26373 $adv = $maxbwbottom /2;
26374 }
26375 $this->y += $adv;
26376 }
26377
26378 // Rotated table split over pages - needs this->y for borders/backgrounds
26379 if($i>0 && $this->table_rotate && $level==1) {
26380 // $this->y = $y0 + $this->tbrot_w;
26381 }
26382
26383 if ($this->tableClipPath ) { $this->_out("Q"); }
26384
26385 $bx = $x0;
26386 $by = $y0;
26387
26388 if ($table['borders_separate']) {
26389 $bx -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H']/2);
26390 if ($tablestartpageno != $this->page) { // IF already broken across a previous pagebreak
26391 $by += $table['max_cell_border_width']['T']/2;
26392 if (empty($tableheader)) { $by -= ($table['border_spacing_V']/2); }
26393 }
26394 else {
26395 $by -= ($table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2);
26396 }
26397 }
26398
26399 else if ($tablestartpageno != $this->page && !empty($tableheader)) { $by += $maxbwtop /2; }
26400
26401 $by -= $tableheaderadj;
26402 $bh = $this->y - $by + $tablefooteradj;
26403 if (!$table['borders_separate']) { $bh -= $adv ; }
26404 if ($split) {
26405 $bw = 0;
26406 for($t=$startcol; $t<$numcols; $t++) {
26407 if ($table['colPg'][$t] == $splitpg) { $bw += $table['wc'][$t]; }
26408 if ($table['colPg'][$t] > $splitpg) { break; }
26409 }
26410 if ($table['borders_separate']) {
26411 if ($firstSpread) {
26412 $bw += $table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H'];
26413 }
26414 else {
26415 $bx += ($table['padding']['L'] + $table['border_details']['L']['w']);
26416 $bw += $table['border_spacing_H'];
26417 }
26418 if ($finalSpread) {
26419 $bw += $table['padding']['R'] + $table['border_details']['R']['w']/2 + $table['border_spacing_H'];
26420 }
26421 }
26422 }
26423 else {
26424 $bw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
26425 }
26426
26427 // mPDF 5.4.16
26428 if ($this->splitTableBorderWidth && ($this->keepColumns || !$this->ColActive) && empty($tablefooter) && $i > 0 && $table['border_details']['B']['w']) {
26429 $prevDrawColor = $this->DrawColor;
26430 $lw = $this->LineWidth;
26431 $this->SetLineWidth($this->splitTableBorderWidth);
26432 $this->SetDColor($table['border_details']['B']['c']);
26433 $this->SetLineJoin(0);
26434 $this->SetLineCap(0);
26435 $blx = $bx;
26436 $blw = $bw;
26437 if (!$table['borders_separate']) {
26438 $blx -= ($table['max_cell_border_width']['L']/2);
26439 $blw += ($table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2);
26440 }
26441 $this->Line($blx,$this->y+($this->splitTableBorderWidth/2),$blx+$blw,$this->y+($this->splitTableBorderWidth/2));
26442 $this->DrawColor = $prevDrawColor;
26443 $this->_out($this->DrawColor);
26444 $this->SetLineWidth($lw);
26445 $this->SetLineJoin(2);
26446 $this->SetLineCap(2);
26447 }
26448
26449 if (!$this->ColActive && ($i > 0 || $j > 0)) {
26450 if (isset($table['bgcolor'][-1])) {
26451 $color = $this->ConvertColor($table['bgcolor'][-1]);
26452 if ($color) {
26453 if (!$table['borders_separate']) { $bh -= $table['max_cell_border_width']['B']/2; }
26454 $this->tableBackgrounds[$level*9][] = array('gradient'=>false, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'col'=>$color);
26455 }
26456 }
26457
26458 /*-- BACKGROUNDS --*/
26459 if (isset($table['gradient'])) {
26460 $g = $this->grad->parseBackgroundGradient($table['gradient']);
26461 if ($g) {
26462 $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'=>'');
26463 }
26464 }
26465
26466 if (isset($table['background-image'])) {
26467 if ($table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['background-image']['gradient'] )) {
26468 $g = $this->grad->parseMozGradient( $table['background-image']['gradient'] );
26469 if ($g) {
26470 $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'=>'');
26471 }
26472 }
26473 else {
26474 $image_id = $table['background-image']['image_id'];
26475 $orig_w = $table['background-image']['orig_w'];
26476 $orig_h = $table['background-image']['orig_h'];
26477 $x_pos = $table['background-image']['x_pos'];
26478 $y_pos = $table['background-image']['y_pos'];
26479 $x_repeat = $table['background-image']['x_repeat'];
26480 $y_repeat = $table['background-image']['y_repeat'];
26481 $resize = $table['background-image']['resize'];
26482 $opacity = $table['background-image']['opacity'];
26483 $itype = $table['background-image']['itype'];
26484 $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);
26485 }
26486 }
26487 /*-- END BACKGROUNDS --*/
26488 }
26489
26490 // $this->AcceptPageBreak() has moved tablebuffer to $this->pages content
26491 if ($this->tableBackgrounds) {
26492 $s = $this->PrintTableBackgrounds();
26493 if ($this->bufferoutput) {
26494 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->headerbuffer);
26495 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', " ", $this->headerbuffer );
26496 }
26497 else {
26498 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
26499 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', " ", $this->pages[$this->page]);
26500 }
26501 $this->tableBackgrounds = array();
26502 }
26503
26504 if ($split) {
26505 if ($i == 0 && $j == 0) { $y0 = -1; }
26506 else if ($finalSpread) {
26507 $splitpg = 0;
26508 $startcol = 0;
26509 $startrow = $i;
26510 }
26511 else {
26512 $splitpg++;
26513 $startcol = $t;
26514 $returny -= $y;
26515 }
26516 return array(false, $startrow, $startcol, $splitpg, $returny, $y0);
26517 }
26518
26519 $this->AddPage($this->CurOrientation);
26520
26521 $this->_out('___TABLE___BACKGROUNDS'.$this->uniqstr);
26522
26523
26524 if ($this->tableClipPath ) { $this->_out($this->tableClipPath); }
26525
26526 // Added to correct for OddEven Margins
26527 $x= $x + $this->MarginCorrection;
26528 $x0= $x0 + $this->MarginCorrection;
26529
26530 // mPDF 5.4.16
26531 if ($this->splitTableBorderWidth && ($this->keepColumns || !$this->ColActive) && empty($tableheader) && $i > 0 && $table['border_details']['T']['w'] ) {
26532 $prevDrawColor = $this->DrawColor;
26533 $lw = $this->LineWidth;
26534 $this->SetLineWidth($this->splitTableBorderWidth);
26535 $this->SetDColor($table['border_details']['T']['c']);
26536 $this->SetLineJoin(0);
26537 $this->SetLineCap(0);
26538 $blx += $this->MarginCorrection;
26539 $this->Line($blx,$this->y-($this->splitTableBorderWidth/2),$blx+$blw,$this->y-($this->splitTableBorderWidth/2));
26540 $this->DrawColor = $prevDrawColor;
26541 $this->_out($this->DrawColor);
26542 $this->SetLineWidth($lw);
26543 $this->SetLineJoin(2);
26544 $this->SetLineCap(2);
26545 }
26546
26547 // Move down to account for half of top border-spacing or
26548 // extra half border width in case page was broken in middle
26549 if($i>0 && !$this->table_rotate && $level==1 && $table['headernrows']==0) {
26550 if ($table['borders_separate']) { $adv = $table['border_spacing_V']/2; }
26551 else {
26552 $maxbwtop = 0;
26553 for( $ctj = 0 ; $ctj < $numcols ; $ctj++ ) {
26554 if (isset($cells[$i][$ctj]) && $cells[$i][$ctj]) {
26555 if (!$this->simpleTables){
26556 if ($this->cacheTables) {
26557 $celltj = $this->_uncacheCell($table['cells'][$i][$ctj], '', $fh);
26558 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($celltj['borderbin']);
26559 }
26560 else if ($this->packTableData) {
26561 list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cells[$i][$ctj]['borderbin']);
26562 }
26563 else {
26564 $bt = $cells[$i][$ctj]['border_details']['T']['w'];
26565 }
26566 $maxbwtop = max($maxbwtop, $bt);
26567 }
26568 else if ($this->simpleTables){
26569 $maxbwtop = max($maxbwtop, $table['simple']['border_details']['T']['w']);
26570 }
26571 }
26572 }
26573 $adv = $maxbwtop /2;
26574 }
26575 $this->y += $adv;
26576 }
26577
26578
26579 if ($this->table_rotate) {
26580 $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'];
26581 if ($table['borders_separate']) { $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2; }
26582 else { $this->tbrot_h = $table['margin']['T'] + $table['max_cell_border_width']['T'] ; }
26583 $this->tbrot_y0 = $this->y;
26584 $pagetrigger = $y0 - $tableheaderadj + ($this->blk[$this->blklvl]['inner_width']);
26585 }
26586 else {
26587 $pagetrigger = $this->PageBreakTrigger;
26588 }
26589
26590 if ($this->kwt_saved && $level==1) {
26591 $this->kwt_moved = true;
26592 }
26593
26594
26595 // Disable Table header repeat if Keep Block together
26596 if (!$this->keep_block_together && !empty($tableheader)) {
26597 $ya = $this->y;
26598 $this->TableHeaderFooter($tableheader,$tablestartpage,$tablestartcolumn,'H',$level);
26599 if ($this->table_rotate) {
26600 $this->tbrot_h = $this->y - $ya ;
26601 }
26602 $tableheaderadj = $this->y - $ya ;
26603 }
26604
26605 else if ($i==0 && !$this->keep_block_together && !$this->table_rotate && $level==1 && !$this->ColActive) {
26606 // Advance down page
26607 if ($table['borders_separate']) { $adv = $table['border_spacing_V']/2 + $table['border_details']['T']['w'] + $table['padding']['T']; }
26608 else { $adv = $table['max_cell_border_width']['T'] /2 ; }
26609 if ($adv) {
26610 if ($this->table_rotate) {
26611 $this->y += ($adv);
26612 }
26613 else {
26614 $this->DivLn($adv,$this->blklvl,true);
26615 }
26616 }
26617 }
26618
26619 $outerfilled = 0;
26620 $y = $y0 = $this->y;
26621 }
26622
26623 /*-- COLUMNS --*/
26624 // COLS
26625 // COLUMN CHANGE
26626 if ($this->CurrCol != $oldcolumn) {
26627 // Added to correct for Columns
26628 $x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
26629 $x0 += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
26630 if ($this->CurrCol == 0) { // just added a page - possibly with tableheader
26631 $y0 = $this->y; // this->y0 is global used by Columns - $y0 is internal to tablewrite
26632 }
26633 else {
26634 $y0 = $this->y0; // this->y0 is global used by Columns - $y0 is internal to tablewrite
26635 }
26636 $y = $y0;
26637 $outerfilled = 0;
26638 if ($this->CurrCol != 0 && ($this->keepColumns && $this->ColActive) && !empty($tableheader) && $i > 0 ) {
26639 $this->x = $x;
26640 $this->y = $y;
26641 $this->TableHeaderFooter($tableheader,$tablestartpage,$tablestartcolumn,'H',$level);
26642 $y0 = $y=$this->y;
26643 }
26644 }
26645 /*-- END COLUMNS --*/
26646 }
26647 $skippage = true;
26648 }
26649
26650 $this->x = $x;
26651 $this->y = $y;
26652
26653 if ($this->kwt_saved && $level==1) {
26654 $this->printkwtbuffer();
26655 $x0 = $x = $this->x;
26656 $y0 = $y = $this->y;
26657 $this->kwt_moved = false;
26658 $this->kwt_saved = false;
26659 }
26660
26661
26662 // Set the Page & Column where table actually starts
26663 if ($i==0 && $j==0 && $level==1) {
26664 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
26665 $tablestartpage = 'EVEN';
26666 }
26667 else if (($this->mirrorMargins) && (($this->page)%2==1)) { // ODD
26668 $tablestartpage = 'ODD';
26669 }
26670 else { $tablestartpage = ''; }
26671 $tablestartpageno = $this->page;
26672 if ($this->ColActive) { $tablestartcolumn = $this->CurrCol; } // *COLUMNS*
26673 }
26674
26675
26676 //ALIGN
26677 $align = $cell['a'];
26678
26679
26680 /*-- COLUMNS --*/
26681 // If outside columns, this is done in PaintDivBB
26682 if ($this->ColActive) {
26683 //OUTER FILL BGCOLOR of DIVS
26684 if ($this->blklvl > 0 && ($j==0) && !$this->table_rotate && $level==1) {
26685 $firstblockfill = $this->GetFirstBlockFill();
26686 if ($firstblockfill && $this->blklvl >= $firstblockfill) {
26687 $divh = $maxrowheight;
26688 // Last row
26689 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
26690 if ($table['borders_separate']) {
26691 $adv = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2;
26692 }
26693 else {
26694 $adv = $table['margin']['B'] + $table['max_cell_border_width']['B']/2;
26695 }
26696 $divh += $adv; //last row: fill bottom half of bottom border (y advanced at end)
26697 }
26698
26699 if (($this->y + $divh) > $outerfilled ) { // if not already painted by previous rowspan
26700 $bak_x = $this->x;
26701 $bak_y = $this->y;
26702 if ($outerfilled > $this->y) {
26703 $divh = ($this->y + $divh) - $outerfilled;
26704 $this->y = $outerfilled;
26705 }
26706
26707 $this->DivLn($divh,-3,false);
26708 $outerfilled = $this->y + $divh;
26709 // Reset current block fill
26710 $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
26711 if ($bcor ) $this->SetFColor($bcor);
26712 $this->x = $bak_x;
26713 $this->y = $bak_y;
26714 }
26715 }
26716 }
26717 }
26718
26719
26720 //TABLE BACKGROUND FILL BGCOLOR - for cellSpacing
26721 if ($this->ColActive) {
26722 if ($table['borders_separate']) {
26723 $fill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
26724 if ($fill) {
26725 $color = $this->ConvertColor($fill);
26726 if ($color) {
26727 $xadj = ($table['border_spacing_H']/2);
26728 $yadj = ($table['border_spacing_V']/2);
26729 $wadj = $table['border_spacing_H'];
26730 $hadj = $table['border_spacing_V'];
26731 if ($i == 0) { // Top
26732 $yadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
26733 $hadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
26734 }
26735 if ($j == 0) { // Left
26736 $xadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
26737 $wadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
26738 }
26739 if ($i == ($numrows-1) || (isset($cell['rowspan']) && ($i+$cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i+1) == $numrows)) { // Bottom
26740 $hadj += $table['padding']['B'] + $table['border_details']['B']['w'] ;
26741 }
26742 if ($j == ($numcols-1) || (isset($cell['colspan']) && ($j+$cell['colspan']) == $numcols) || (!isset($cell['colspan']) && ($j+1) == $numcols)) { // Right
26743 $wadj += $table['padding']['R'] + $table['border_details']['R']['w'] ;
26744 }
26745 $this->SetFColor($color);
26746 $this->Rect($x - $xadj, $y - $yadj, $w + $wadj, $h + $hadj, 'F');
26747 }
26748 }
26749 }
26750 }
26751 /*-- END COLUMNS --*/
26752
26753 if ($table['empty_cells']!='hide' || !empty($cell['textbuffer']) || (isset($cell['nestedcontent']) && $cell['nestedcontent']) || !$table['borders_separate'] ) { $paintcell = true; }
26754 else { $paintcell = false; }
26755
26756 //Set Borders
26757 $bord = 0;
26758 $bord_det = array();
26759
26760 if (!$this->simpleTables){
26761 if ($this->packTableData) {
26762 if ($cell['borderbin']) {
26763 $c = $this->_unpackCellBorder($cell['borderbin']);
26764 $bord = $c['border'];
26765 $bord_det = $c['border_details'];
26766 }
26767 }
26768 else if ($cell['border']) {
26769 $bord = $cell['border'];
26770 $bord_det = $cell['border_details'];
26771 }
26772 }
26773 else if ($this->simpleTables){
26774 if ($table['simple']['border']) {
26775 $bord = $table['simple']['border'];
26776 $bord_det = $table['simple']['border_details'];
26777 }
26778 }
26779
26780 //TABLE ROW OR CELL FILL BGCOLOR
26781 $fill = 0;
26782 if (isset($cell['bgcolor']) && $cell['bgcolor'] && $cell['bgcolor']!='transparent') {
26783 $fill = $cell['bgcolor'];
26784 $leveladj = 6;
26785 }
26786 else if (isset($table['bgcolor'][$i]) && $table['bgcolor'][$i] && $table['bgcolor'][$i]!='transparent') { // Row color
26787 $fill = $table['bgcolor'][$i];
26788 $leveladj = 3;
26789 }
26790 if ($fill && $paintcell) {
26791 $color = $this->ConvertColor($fill);
26792 if ($color) {
26793 if ($table['borders_separate']) {
26794 if ($this->ColActive) {
26795 $this->SetFColor($color);
26796 $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');
26797 }
26798 else {
26799 $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);
26800 }
26801 }
26802 else {
26803 if ($this->ColActive) {
26804 $this->SetFColor($color);
26805 $this->Rect($x, $y, $w, $h, 'F');
26806 }
26807 else {
26808 $this->tableBackgrounds[$level*9+$leveladj][] = array('gradient'=>false, 'x'=>$x, 'y'=>$y, 'w'=>$w, 'h'=>$h, 'col'=>$color);
26809 }
26810 }
26811 }
26812 }
26813
26814 /*-- BACKGROUNDS --*/
26815 if (isset($cell['gradient']) && $cell['gradient'] && $paintcell){
26816 $g = $this->grad->parseBackgroundGradient($cell['gradient']);
26817 if ($g) {
26818 if ($table['borders_separate']) {
26819 $px = $x+ ($table['border_spacing_H']/2);
26820 $py = $y+ ($table['border_spacing_V']/2);
26821 $pw = $w- $table['border_spacing_H'];
26822 $ph = $h- $table['border_spacing_V'];
26823 }
26824 else {
26825 $px = $x;
26826 $py = $y;
26827 $pw = $w;
26828 $ph = $h;
26829 }
26830 if ($this->ColActive) {
26831 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
26832 }
26833 else {
26834 $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'=>'');
26835 }
26836 }
26837 }
26838
26839 if (isset($cell['background-image']) && $paintcell) {
26840 if ($cell['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $cell['background-image']['gradient'] )) {
26841 $g = $this->grad->parseMozGradient( $cell['background-image']['gradient'] );
26842 if ($g) {
26843 if ($table['borders_separate']) {
26844 $px = $x+ ($table['border_spacing_H']/2);
26845 $py = $y+ ($table['border_spacing_V']/2);
26846 $pw = $w- $table['border_spacing_H'];
26847 $ph = $h- $table['border_spacing_V'];
26848 }
26849 else {
26850 $px = $x;
26851 $py = $y;
26852 $pw = $w;
26853 $ph = $h;
26854 }
26855 if ($this->ColActive) {
26856 $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
26857 }
26858 else {
26859 $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'=>'');
26860 }
26861 }
26862 }
26863 else if ($cell['background-image']['image_id']) { // Background pattern
26864 $n = count($this->patterns)+1;
26865 if ($table['borders_separate']) {
26866 $px = $x+ ($table['border_spacing_H']/2);
26867 $py = $y+ ($table['border_spacing_V']/2);
26868 $pw = $w- $table['border_spacing_H'];
26869 $ph = $h- $table['border_spacing_V'];
26870 }
26871 else {
26872 $px = $x;
26873 $py = $y;
26874 $pw = $w;
26875 $ph = $h;
26876 }
26877 if ($this->ColActive) {
26878 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']);
26879 $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);
26880 if ($cell['background-image']['opacity']>0 && $cell['background-image']['opacity']<1) { $opac = $this->SetAlpha($cell['background-image']['opacity'],'Normal',true); }
26881 else { $opac = ''; }
26882 $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));
26883 }
26884 else {
26885 $image_id = $cell['background-image']['image_id'];
26886 $orig_w = $cell['background-image']['orig_w'];
26887 $orig_h = $cell['background-image']['orig_h'];
26888 $x_pos = $cell['background-image']['x_pos'];
26889 $y_pos = $cell['background-image']['y_pos'];
26890 $x_repeat = $cell['background-image']['x_repeat'];
26891 $y_repeat = $cell['background-image']['y_repeat'];
26892 $resize = $cell['background-image']['resize'];
26893 $opacity = $cell['background-image']['opacity'];
26894 $itype = $cell['background-image']['itype'];
26895 $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);
26896 }
26897 }
26898 }
26899 /*-- END BACKGROUNDS --*/
26900
26901 if (isset($cell['colspan']) && $cell['colspan']>1) { $ccolsp = $cell['colspan']; }
26902 else { $ccolsp = 1; }
26903 if (isset($cell['rowspan']) && $cell['rowspan']>1) { $crowsp = $cell['rowspan']; }
26904 else { $crowsp = 1; }
26905
26906
26907 // but still need to do this for repeated headers...
26908 if (!$table['borders_separate'] && $this->tabletheadjustfinished && !$this->simpleTables){
26909 if (isset($table['topntail']) && $table['topntail']) {
26910 $bord_det['T'] = $this->border_details($table['topntail']);
26911 $bord_det['T']['w'] /= $this->shrin_k;
26912 $this->setBorder($bord, _BORDER_TOP);
26913 }
26914 if (isset($table['thead-underline']) && $table['thead-underline']) {
26915 $bord_det['T'] = $this->border_details($table['thead-underline']);
26916 $bord_det['T']['w'] /= $this->shrin_k;
26917 $this->setBorder($bord, _BORDER_TOP);
26918 }
26919 }
26920
26921
26922 //Get info of first row ==>> table header
26923 //Use > 1 row if THEAD
26924 if (isset($table['is_thead'][$i]) && $table['is_thead'][$i] && $level==1) {
26925 if ($j==0) $tableheaderrowheight += $table['hr'][$i];
26926 $tableheader[$i][0]['trbackground-images'] = (isset($table['trbackground-images'][$i]) ? $table['trbackground-images'][$i] : null);
26927 $tableheader[$i][0]['trgradients'] = (isset($table['trgradients'][$i]) ? $table['trgradients'][$i] : null);
26928 $tableheader[$i][0]['trbgcolor'] = (isset($table['bgcolor'][$i]) ? $table['bgcolor'][$i] : null);
26929 $tableheader[$i][$j]['x'] = $x;
26930 $tableheader[$i][$j]['y'] = $y;
26931 $tableheader[$i][$j]['h'] = $h;
26932 $tableheader[$i][$j]['w'] = $w;
26933 if (isset($cell['textbuffer'])) { $tableheader[$i][$j]['textbuffer'] = $cell['textbuffer']; }
26934 else { $tableheader[$i][$j]['textbuffer'] = ''; }
26935 $tableheader[$i][$j]['a'] = $cell['a'];
26936 $tableheader[$i][$j]['R'] = $cell['R'];
26937
26938 $tableheader[$i][$j]['va'] = $cell['va'];
26939 $tableheader[$i][$j]['mih'] = $cell['mih'];
26940 $tableheader[$i][$j]['gradient'] = (isset($cell['gradient']) ? $cell['gradient'] : null); // *BACKGROUNDS*
26941 $tableheader[$i][$j]['background-image'] = (isset($cell['background-image']) ? $cell['background-image'] : null); // *BACKGROUNDS*
26942 $tableheader[$i][$j]['rowspan'] = (isset($cell['rowspan']) ? $cell['rowspan'] : null);
26943 $tableheader[$i][$j]['colspan'] = (isset($cell['colspan']) ? $cell['colspan'] : null);
26944 $tableheader[$i][$j]['bgcolor'] = $cell['bgcolor'];
26945
26946 if (!$this->simpleTables){
26947 $tableheader[$i][$j]['border'] = $bord;
26948 $tableheader[$i][$j]['border_details'] = $bord_det;
26949 }
26950 else if ($this->simpleTables){
26951 $tableheader[$i][$j]['border'] = $table['simple']['border'];
26952 $tableheader[$i][$j]['border_details'] = $table['simple']['border_details'];
26953 }
26954 $tableheader[$i][$j]['padding'] = $cell['padding'];
26955 }
26956
26957 // CELL BORDER
26958 if ($bord || $bord_det) {
26959 if ($table['borders_separate'] && $paintcell) {
26960 $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']);
26961 }
26962 else if (!$table['borders_separate']) {
26963 $this->_tableRect($x, $y, $w, $h, $bord, $bord_det, true, $table['borders_separate']); // true causes buffer
26964 }
26965
26966 }
26967
26968 //VERTICAL ALIGN
26969 if ($cell['R'] && INTVAL($cell['R']) > 0 && INTVAL($cell['R']) < 90 && isset($cell['va']) && $cell['va']!='B') { $cell['va']='B';}
26970 if (!isset($cell['va']) || $cell['va']=='M') $this->y += ($h-$cell['mih'])/2;
26971 elseif (isset($cell['va']) && $cell['va']=='B') $this->y += $h-$cell['mih'];
26972
26973 // NESTED CONTENT
26974
26975 // TEXT (and nested tables)
26976 $this->divalign=$align;
26977
26978 $this->divwidth=$w;
26979 if (!empty($cell['textbuffer'])) {
26980 if ($level==1) {
26981 if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i]) {
26982 if (preg_match('/{colsum([0-9]*)[_]*}/', $cell['textbuffer'][0][0], $m)) {
26983 $rep = sprintf("%01.".intval($m[1])."f", $this->colsums[$j]);
26984 $cell['textbuffer'][0][0] = preg_replace('/{colsum[0-9_]*}/', $rep ,$cell['textbuffer'][0][0]);
26985 }
26986 }
26987 else if (!isset($table['is_thead'][$i])) { $this->colsums[$j] += floatval(preg_replace('/^[^0-9\.\,]*/','',$cell['textbuffer'][0][0])); } // mPDF 5.6.66
26988 }
26989 $opy = $this->y;
26990 // mPDF ITERATION
26991 if ($this->iterationCounter) {
26992 foreach($cell['textbuffer'] AS $k=>$t) {
26993 if (preg_match('/{iteration ([a-zA-Z0-9_]+)}/',$t[0], $m)) {
26994 $vname = '__'.$m[1].'_';
26995 if (!isset($this->$vname)) { $this->$vname = 1; }
26996 else { $this->$vname++; }
26997 $cell['textbuffer'][$k][0] = preg_replace('/{iteration '.$m[1].'}/', $this->$vname, $cell['textbuffer'][$k][0]);
26998 }
26999 }
27000 }
27001
27002
27003 if ($cell['R']) {
27004 $cellPtSize = $cell['textbuffer'][0][11] / $this->shrin_k;
27005 if (!$cellPtSize) { $cellPtSize = $this->default_font_size; }
27006 $cellFontHeight = ($cellPtSize/_MPDFK);
27007 $opx = $this->x;
27008 $angle = INTVAL($cell['R']);
27009 // Only allow 45 to 89 degrees (when bottom-aligned) or exactly 90 or -90
27010 if ($angle > 90) { $angle = 90; }
27011 else if ($angle > 0 && $angle <45) { $angle = 45; }
27012 else if ($angle < 0) { $angle = -90; }
27013 $offset = ((sin(deg2rad($angle))) * 0.37 * $cellFontHeight);
27014 if (isset($cell['a']) && $cell['a']=='R') {
27015 $this->x += ($w) + ($offset) - ($cellFontHeight/3) - ($cell['padding']['R'] + ($table['border_spacing_H']/2));
27016 }
27017 else if (!isset($cell['a']) || $cell['a']=='C') {
27018 $this->x += ($w/2) + ($offset);
27019 }
27020 else {
27021 $this->x += ($offset) + ($cellFontHeight/3)+($cell['padding']['L'] +($table['border_spacing_H']/2));
27022 }
27023 $str = '';
27024 foreach($cell['textbuffer'] AS $t) { $str .= $t[0].' '; }
27025 $str = trim($str);
27026 if (!isset($cell['va']) || $cell['va']=='M') {
27027 $this->y -= ($h-$cell['mih'])/2; //Undo what was added earlier VERTICAL ALIGN
27028 if ($angle > 0) { $this->y += (($h-$cell['mih'])/2) + $cell['padding']['T'] + ($cell['mih']-($cell['padding']['T'] + $cell['padding']['B'])); }
27029 else if ($angle < 0) { $this->y += (($h-$cell['mih'])/2)+ ($cell['padding']['T'] + ($table['border_spacing_V']/2)); }
27030 }
27031 elseif (isset($cell['va']) && $cell['va']=='B') {
27032 $this->y -= $h-$cell['mih']; //Undo what was added earlier VERTICAL ALIGN
27033 if ($angle > 0) { $this->y += $h-($cell['padding']['B'] + ($table['border_spacing_V']/2)); }
27034 else if ($angle < 0) { $this->y += $h-$cell['mih'] + ($cell['padding']['T'] + ($table['border_spacing_V']/2)); }
27035 }
27036 elseif (isset($cell['va']) && $cell['va']=='T') {
27037 if ($angle > 0) { $this->y += $cell['mih']-($cell['padding']['B'] + ($table['border_spacing_V']/2)); }
27038 else if ($angle < 0) { $this->y += ($cell['padding']['T'] + ($table['border_spacing_V']/2)); }
27039 }
27040 $this->Rotate($angle,$this->x,$this->y);
27041 $s_fs = $this->FontSizePt;
27042 $s_f = $this->FontFamily;
27043 $s_st = $this->FontStyle;
27044 if (!empty($cell['textbuffer'][0][3])) { //Font Color
27045 $cor = $cell['textbuffer'][0][3];
27046 $this->SetTColor($cor);
27047 }
27048 $s_str = $this->strike;
27049 $this->strike = $cell['textbuffer'][0][8]; //Strikethrough
27050 $this->SetFont($cell['textbuffer'][0][4],$cell['textbuffer'][0][2],$cellPtSize,true,true);
27051 $this->Text($this->x,$this->y,$str);
27052 $this->Rotate(0);
27053 $this->SetFont($s_f,$s_st,$s_fs,true,true);
27054 $this->SetTColor(0);
27055 $this->strike = $s_str;
27056 $this->x = $opx;
27057 }
27058 else {
27059
27060 if (!$this->simpleTables){
27061 if ($bord_det) {
27062 $btlw = $bord_det['L']['w'];
27063 $btrw = $bord_det['R']['w'];
27064 $bttw = $bord_det['T']['w'];
27065 }
27066 else {
27067 $btlw = 0;
27068 $btrw = 0;
27069 $bttw = 0;
27070 }
27071 if ($table['borders_separate']) {
27072 $xadj = $btlw + $cell['padding']['L'] +($table['border_spacing_H']/2);
27073 $wadj = $btlw + $btrw + $cell['padding']['L'] +$cell['padding']['R'] + $table['border_spacing_H'];
27074 $yadj = $bttw + $cell['padding']['T'] + ($table['border_spacing_H']/2);
27075 }
27076 else {
27077 $xadj = $btlw/2 + $cell['padding']['L'];
27078 $wadj = ($btlw + $btrw)/2 + $cell['padding']['L'] + $cell['padding']['R'];
27079 $yadj = $bttw/2 + $cell['padding']['T'];
27080 }
27081 }
27082 else if ($this->simpleTables){
27083 if ($table['borders_separate']) { // NB twice border width
27084 $xadj = $table['simple']['border_details']['L']['w'] + $cell['padding']['L'] +($table['border_spacing_H']/2);
27085 $wadj = $table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'] + $cell['padding']['L'] +$cell['padding']['R'] + $table['border_spacing_H'];
27086 $yadj = $table['simple']['border_details']['T']['w'] + $cell['padding']['T'] + ($table['border_spacing_H']/2);
27087 }
27088 else {
27089 $xadj = $table['simple']['border_details']['L']['w']/2 + $cell['padding']['L'];
27090 $wadj = ($table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'])/2 + $cell['padding']['L'] + $cell['padding']['R'];
27091 $yadj = $table['simple']['border_details']['T']['w']/2 + $cell['padding']['T'];
27092 }
27093 }
27094 // mPDF 5.6.13
27095 $this->decimal_offset = 0;
27096 if(substr($cell['a'],0,1) == 'D') {
27097 if ($cell['colspan'] > 1) { $this->divalign = $c['a'] = substr($cell['a'],2,1); }
27098 else {
27099 $smax = $table['decimal_align'][$j]['maxs0'];
27100 $d_content = $table['decimal_align'][$j]['maxs0'] + $table['decimal_align'][$j]['maxs1'];
27101 $this->decimal_offset = $smax;
27102 $extra = ($w - $d_content - $wadj);
27103 if ($extra > 0) {
27104 if(substr($cell['a'],2,1) == 'R') { $this->decimal_offset += $extra; }
27105 else if(substr($cell['a'],2,1) == 'C') { $this->decimal_offset += ($extra)/2; }
27106 }
27107 }
27108 }
27109 $this->divwidth=$w-$wadj;
27110 if ($this->divwidth == 0) { $this->divwidth = 0.0001; }
27111 $this->x += $xadj;
27112 $this->y += $yadj;
27113 $this->printbuffer($cell['textbuffer'],'',true);
27114 }
27115 $this->y = $opy;
27116 }
27117
27118 /*-- BACKGROUNDS --*/
27119 if (!$this->ColActive) {
27120 if (isset($table['trgradients'][$i]) && ($j==0 || $table['borders_separate'])) {
27121 $g = $this->grad->parseBackgroundGradient($table['trgradients'][$i]);
27122 if ($g) {
27123 $gx = $x0;
27124 $gy = $y;
27125 $gh = $h;
27126 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
27127 if ($table['borders_separate']) {
27128 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
27129 $s = '';
27130 $clx = $x+ ($table['border_spacing_H']/2);
27131 $cly = $y+ ($table['border_spacing_V']/2);
27132 $clw = $w- $table['border_spacing_H'];
27133 $clh = $h- $table['border_spacing_V'];
27134 // Set clipping path
27135 $s = ' q 0 w '; // Line width=0
27136 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
27137 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
27138 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
27139 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
27140 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
27141 $s .= ' W n '; // Ends path no-op & Sets the clipping path
27142 $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);
27143 }
27144 else {
27145 $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'=>'');
27146 }
27147 }
27148 }
27149 if (isset($table['trbackground-images'][$i]) && ($j==0 || $table['borders_separate'])) {
27150 if ($table['trbackground-images'][$i]['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['trbackground-images'][$i]['gradient'] )) {
27151 $g = $this->grad->parseMozGradient( $table['trbackground-images'][$i]['gradient'] );
27152 if ($g) {
27153 $gx = $x0;
27154 $gy = $y;
27155 $gh = $h;
27156 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
27157 if ($table['borders_separate']) {
27158 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
27159 $s = '';
27160 $clx = $x+ ($table['border_spacing_H']/2);
27161 $cly = $y+ ($table['border_spacing_V']/2);
27162 $clw = $w- $table['border_spacing_H'];
27163 $clh = $h- $table['border_spacing_V'];
27164 // Set clipping path
27165 $s = ' q 0 w '; // Line width=0
27166 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
27167 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
27168 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
27169 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
27170 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
27171 $s .= ' W n '; // Ends path no-op & Sets the clipping path
27172 $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);
27173 }
27174 else {
27175 $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'=>'');
27176 }
27177 }
27178 }
27179 else {
27180 $image_id = $table['trbackground-images'][$i]['image_id'];
27181 $orig_w = $table['trbackground-images'][$i]['orig_w'];
27182 $orig_h = $table['trbackground-images'][$i]['orig_h'];
27183 $x_pos = $table['trbackground-images'][$i]['x_pos'];
27184 $y_pos = $table['trbackground-images'][$i]['y_pos'];
27185 $x_repeat = $table['trbackground-images'][$i]['x_repeat'];
27186 $y_repeat = $table['trbackground-images'][$i]['y_repeat'];
27187 $resize = $table['trbackground-images'][$i]['resize'];
27188 $opacity = $table['trbackground-images'][$i]['opacity'];
27189 $itype = $table['trbackground-images'][$i]['itype'];
27190 $clippath = '';
27191 $gx = $x0;
27192 $gy = $y;
27193 $gh = $h;
27194 $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
27195 if ($table['borders_separate']) {
27196 $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
27197 $s = '';
27198 $clx = $x + ($table['border_spacing_H']/2);
27199 $cly = $y + ($table['border_spacing_V']/2);
27200 $clw = $w - $table['border_spacing_H'];
27201 $clh = $h - $table['border_spacing_V'];
27202 // Set clipping path
27203 $s = ' q 0 w '; // Line width=0
27204 $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL
27205 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
27206 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
27207 $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
27208 $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
27209 $s .= ' W n '; // Ends path no-op & Sets the clipping path
27210 $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);
27211 }
27212 else {
27213 $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);
27214 }
27215 }
27216 }
27217 }
27218
27219 /*-- END BACKGROUNDS --*/
27220
27221 // TABLE BORDER - if separate
27222 if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) {
27223 $halfspaceL = $table['padding']['L'] + ($table['border_spacing_H']/2);
27224 $halfspaceR = $table['padding']['R'] + ($table['border_spacing_H']/2);
27225 $halfspaceT = $table['padding']['T'] + ($table['border_spacing_V']/2);
27226 $halfspaceB = $table['padding']['B'] + ($table['border_spacing_V']/2);
27227 $tbx = $x;
27228 $tby = $y;
27229 $tbw = $w;
27230 $tbh = $h;
27231 $tab_bord = 0;
27232
27233 $corner = '';
27234 if ($i == 0) { // Top
27235 $tby -= $halfspaceT + ($table['border_details']['T']['w']/2);
27236 $tbh += $halfspaceT + ($table['border_details']['T']['w']/2);
27237 $this->setBorder($tab_bord , _BORDER_TOP);
27238 $corner .= 'T';
27239 }
27240 if ($i == ($numrows-1) || (isset($cell['rowspan']) && ($i+$cell['rowspan']) == $numrows)) { // Bottom
27241 $tbh += $halfspaceB + ($table['border_details']['B']['w']/2);
27242 $this->setBorder($tab_bord , _BORDER_BOTTOM);
27243 $corner .= 'B';
27244 }
27245 if ($j == 0) { // Left
27246 $tbx -= $halfspaceL + ($table['border_details']['L']['w']/2);
27247 $tbw += $halfspaceL + ($table['border_details']['L']['w']/2);
27248 $this->setBorder($tab_bord , _BORDER_LEFT);
27249 $corner .= 'L';
27250 }
27251 if ($j == ($numcols-1) || (isset($cell['colspan']) && ($j+$cell['colspan']) == $numcols)) { // Right
27252 $tbw += $halfspaceR + ($table['border_details']['R']['w']/2);
27253 $this->setBorder($tab_bord , _BORDER_RIGHT);
27254 $corner .= 'R';
27255 }
27256 $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'] );
27257 }
27258
27259 unset($cell );
27260 //Reset values
27261 $this->Reset();
27262
27263 }//end of (if isset(cells)...)
27264 }// end of columns
27265
27266 $newpagestarted = false;
27267 $this->tabletheadjustfinished = false;
27268
27269 if ($this->ColActive && $i < $numrows-1 && $level==1) { $this->breakpoints[$this->CurrCol][] = $y + $h; } // *COLUMNS*
27270
27271 /*-- COLUMNS --*/
27272 if ($this->ColActive) {
27273 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); }
27274 }
27275 /*-- END COLUMNS --*/
27276
27277 if ($i == $numrows-1) { $this->y = $y + $h; } //last row jump (update this->y position)
27278 if ($this->table_rotate && $level==1) {
27279 $this->tbrot_h += $h;
27280 }
27281
27282
27283
27284 }// end of rows
27285
27286 if ($this->progressBar) { $this->UpdateProgressBar(7,70,' '); } // *PROGRESS-BAR*
27287
27288 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); }
27289
27290
27291 if ($this->tableClipPath ) { $this->_out("Q"); }
27292 $this->tableClipPath = '';
27293
27294 // Advance down page by half width of bottom border
27295 if ($table['borders_separate']) { $this->y += $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2; }
27296 else { $this->y += $table['max_cell_border_width']['B']/2; }
27297
27298 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; }
27299 else if ($level==1) { $this->tbrot_h += $table['margin']['B'] + $table['max_cell_border_width']['B']/2; }
27300
27301 $bx = $x0;
27302 $by = $y0;
27303 if ($table['borders_separate']) {
27304 $bx -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H']/2);
27305 if ($tablestartpageno != $this->page) { // IF broken across page
27306 $by += $table['max_cell_border_width']['T']/2;
27307 if (empty($tableheader)) { $by -= ($table['border_spacing_V']/2); }
27308 }
27309 else if ($split && $startrow > 0 && empty($tableheader)) {
27310 $by -= ($table['border_spacing_V']/2);
27311 }
27312 else {
27313 $by -= ($table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V']/2);
27314 }
27315 }
27316 else if ($tablestartpageno != $this->page && !empty($tableheader)) { $by += $maxbwtop /2; }
27317 $by -= $tableheaderadj;
27318 $bh = $this->y - $by;
27319 if (!$table['borders_separate']) { $bh -= $table['max_cell_border_width']['B']/2; }
27320
27321 if ($split) {
27322 $bw = 0;
27323 $finalSpread = true;
27324 for($t=$startcol; $t<$numcols; $t++) {
27325 if ($table['colPg'][$t] == $splitpg) { $bw += $table['wc'][$t]; }
27326 if ($table['colPg'][$t] > $splitpg) { $finalSpread = false; break; }
27327 }
27328 if ($startcol==0) { $firstSpread = true; }
27329 else { $firstSpread = false; }
27330 if ($table['borders_separate']) {
27331 $bw += $table['border_spacing_H'];
27332 if ($firstSpread) {
27333 $bw += $table['padding']['L'] + $table['border_details']['L']['w'];
27334 }
27335 else {
27336 $bx += ($table['padding']['L'] + $table['border_details']['L']['w']);
27337 }
27338 if ($finalSpread) {
27339 $bw += $table['padding']['R'] + $table['border_details']['R']['w'];
27340 }
27341 }
27342 }
27343 else {
27344 $bw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
27345 }
27346
27347 if (!$this->ColActive) {
27348 if (isset($table['bgcolor'][-1])) {
27349 $color = $this->ConvertColor($table['bgcolor'][-1]);
27350 if ($color) {
27351 $this->tableBackgrounds[$level*9][] = array('gradient'=>false, 'x'=>$bx, 'y'=>$by, 'w'=>$bw, 'h'=>$bh, 'col'=>$color);
27352 }
27353 }
27354
27355 /*-- BACKGROUNDS --*/
27356 if (isset($table['gradient'])) {
27357 $g = $this->grad->parseBackgroundGradient($table['gradient']);
27358 if ($g) {
27359 $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'=>'');
27360 }
27361 }
27362
27363 if (isset($table['background-image'])) {
27364 if ($table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['background-image']['gradient'] )) {
27365 $g = $this->grad->parseMozGradient( $table['background-image']['gradient'] );
27366 if ($g) {
27367 $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'=>'');
27368 }
27369 }
27370 else {
27371 $image_id = $table['background-image']['image_id'];
27372 $orig_w = $table['background-image']['orig_w'];
27373 $orig_h = $table['background-image']['orig_h'];
27374 $x_pos = $table['background-image']['x_pos'];
27375 $y_pos = $table['background-image']['y_pos'];
27376 $x_repeat = $table['background-image']['x_repeat'];
27377 $y_repeat = $table['background-image']['y_repeat'];
27378 $resize = $table['background-image']['resize'];
27379 $opacity = $table['background-image']['opacity'];
27380 $itype = $table['background-image']['itype'];
27381 $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);
27382 }
27383 }
27384 /*-- END BACKGROUNDS --*/
27385 }
27386
27387 if ($this->tableBackgrounds && $level == 1) {
27388 $s = $this->PrintTableBackgrounds();
27389 if ($this->table_rotate && !$this->processingHeader && !$this->processingFooter) {
27390 $this->tablebuffer = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->tablebuffer);
27391 if ($level == 1) { $this->tablebuffer = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', " ", $this->tablebuffer); }
27392 }
27393 else if ($this->bufferoutput) {
27394 $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->headerbuffer);
27395 if ($level == 1) { $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', " ", $this->headerbuffer ); }
27396 }
27397 else {
27398 $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
27399 if ($level == 1) { $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS'.$this->uniqstr.')/', " ", $this->pages[$this->page]); }
27400 }
27401 $this->tableBackgrounds = array();
27402 }
27403
27404
27405 // TABLE BOTTOM MARGIN
27406 if ($table['margin']['B']) {
27407 if (!$this->table_rotate && $level==1) {
27408 $this->DivLn($table['margin']['B'],$this->blklvl,true); // collapsible
27409 }
27410 else {
27411 $this->y += ($table['margin']['B']);
27412 }
27413 }
27414
27415 if ($this->ColActive && $level==1) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
27416
27417 if ($this->cacheTables) { fclose($fh); }
27418
27419 if ($split) {
27420 // Are there more columns to print on a next page?
27421 if ($lastCol < $numcols-1) {
27422 $splitpg++;
27423 $startcol = $lastCol + 1;
27424 return array(false, $startrow, $startcol, $splitpg, $returny, $y0);
27425 }
27426 else {
27427 if ($this->cacheTables) {
27428 unlink($table['cache']);
27429 @unlink($table['cache'].'.bak');
27430 }
27431 return array(true,0,0,0);
27432 }
27433 }
27434 if ($this->cacheTables) {
27435 unlink($table['cache']);
27436 @unlink($table['cache'].'.bak');
27437 }
27438
27439 }//END OF FUNCTION _tableWrite()
27440
27441
27442 /////////////////////////END OF TABLE CODE//////////////////////////////////
27443 /*-- END TABLES --*/
27444
27445 function _putextgstates() {
27446 for ($i = 1; $i <= count($this->extgstates); $i++) {
27447 $this->_newobj();
27448 $this->extgstates[$i]['n'] = $this->n;
27449 $this->_out('<</Type /ExtGState');
27450 foreach ($this->extgstates[$i]['parms'] as $k=>$v)
27451 $this->_out('/'.$k.' '.$v);
27452 $this->_out('>>');
27453 $this->_out('endobj');
27454 }
27455 }
27456
27457 function _putocg() {
27458 if ($this->hasOC) { // mPDF 5.6.01
27459 $this->_newobj();
27460 $this->n_ocg_print=$this->n;
27461 $this->_out('<</Type /OCG /Name '.$this->_textstring('Print only'));
27462 $this->_out('/Usage <</Print <</PrintState /ON>> /View <</ViewState /OFF>>>>>>');
27463 $this->_out('endobj');
27464 $this->_newobj();
27465 $this->n_ocg_view=$this->n;
27466 $this->_out('<</Type /OCG /Name '.$this->_textstring('Screen only'));
27467 $this->_out('/Usage <</Print <</PrintState /OFF>> /View <</ViewState /ON>>>>>>');
27468 $this->_out('endobj');
27469 $this->_newobj();
27470 $this->n_ocg_hidden=$this->n;
27471 $this->_out('<</Type /OCG /Name '.$this->_textstring('Hidden'));
27472 $this->_out('/Usage <</Print <</PrintState /OFF>> /View <</ViewState /OFF>>>>>>');
27473 $this->_out('endobj');
27474 }
27475 // mPDF 5.6.01 Add Layers
27476 if (count($this->layers)) {
27477 ksort($this->layers);
27478 foreach($this->layers as $id=>$layer) {
27479 $this->_newobj();
27480 $this->layers[$id]['n'] = $this->n;
27481 // mPDF 5.6.28
27482 if (isset($this->layerDetails[$id]['name']) && $this->layerDetails[$id]['name']) {
27483 $name = $this->layerDetails[$id]['name'];
27484 }
27485 else { $name = $layer['name']; }
27486 $this->_out('<</Type /OCG /Name '.$this->_UTF16BEtextstring($name).'>>');
27487 $this->_out('endobj');
27488 }
27489 }
27490 }
27491
27492
27493 /*-- IMPORTS --*/
27494
27495 // from mPDFI
27496 function _putimportedobjects() {
27497 if (is_array($this->parsers) && count($this->parsers) > 0) {
27498 foreach($this->parsers AS $filename => $p) {
27499 $this->current_parser =& $this->parsers[$filename];
27500 if (is_array($this->_obj_stack[$filename])) {
27501 while($n = key($this->_obj_stack[$filename])) {
27502 $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c,$this->_obj_stack[$filename][$n][1]);
27503 $this->_newobj($this->_obj_stack[$filename][$n][0]);
27504 if ($nObj[0] == PDF_TYPE_STREAM) {
27505 $this->pdf_write_value($nObj);
27506 }
27507 else {
27508 $this->pdf_write_value($nObj[1]);
27509 }
27510 $this->_out('endobj');
27511 $this->_obj_stack[$filename][$n] = null; // free memory
27512 unset($this->_obj_stack[$filename][$n]);
27513 reset($this->_obj_stack[$filename]);
27514 }
27515 }
27516 }
27517 }
27518 }
27519
27520
27521 function _putformxobjects() {
27522 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
27523 reset($this->tpls);
27524 foreach($this->tpls AS $tplidx => $tpl) {
27525 $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
27526 $this->_newobj();
27527 $this->tpls[$tplidx]['n'] = $this->n;
27528 $this->_out('<<'.$filter.'/Type /XObject');
27529 $this->_out('/Subtype /Form');
27530 $this->_out('/FormType 1');
27531 // Left/Bottom/Right/Top
27532 $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]',
27533 $tpl['box']['x']*_MPDFK,
27534 $tpl['box']['y']*_MPDFK,
27535 ($tpl['box']['x'] + $tpl['box']['w'])*_MPDFK,
27536 ($tpl['box']['y'] + $tpl['box']['h'])*_MPDFK )
27537 );
27538
27539
27540 if (isset($tpl['box']))
27541 $this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]',-$tpl['box']['x']*_MPDFK, -$tpl['box']['y']*_MPDFK));
27542 $this->_out('/Resources ');
27543
27544 if (isset($tpl['resources'])) {
27545 $this->current_parser =& $tpl['parser'];
27546 $this->pdf_write_value($tpl['resources']);
27547 } else {
27548 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27549 if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) {
27550 $this->_out('/Font <<');
27551 foreach($this->_res['tpl'][$tplidx]['fonts'] as $font)
27552 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27553 $this->_out('>>');
27554 }
27555 if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) ||
27556 isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls']))
27557 {
27558 $this->_out('/XObject <<');
27559 if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) {
27560 foreach($this->_res['tpl'][$tplidx]['images'] as $image)
27561 $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
27562 }
27563 if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) {
27564 foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $itpl)
27565 $this->_out($this->tplprefix.$i.' '.$itpl['n'].' 0 R');
27566 }
27567 $this->_out('>>');
27568 }
27569 $this->_out('>>');
27570 }
27571
27572 $this->_out('/Length '.strlen($p).' >>');
27573 $this->_putstream($p);
27574 $this->_out('endobj');
27575 }
27576 }
27577
27578 /*-- END IMPORTS --*/
27579
27580
27581 function _putpatterns() {
27582 for ($i = 1; $i <= count($this->patterns); $i++) {
27583 $x = $this->patterns[$i]['x'];
27584 $y = $this->patterns[$i]['y'];
27585 $w = $this->patterns[$i]['w'];
27586 $h = $this->patterns[$i]['h'];
27587 $pgh = $this->patterns[$i]['pgh'];
27588 $orig_w = $this->patterns[$i]['orig_w'];
27589 $orig_h = $this->patterns[$i]['orig_h'];
27590 $image_id = $this->patterns[$i]['image_id'];
27591 $itype = $this->patterns[$i]['itype'];
27592 $bpa = $this->patterns[$i]['bpa']; // mPDF 5.6.10 background positioning area
27593
27594 if ($this->patterns[$i]['x_repeat']) { $x_repeat = true; }
27595 else { $x_repeat = false; }
27596 if ($this->patterns[$i]['y_repeat']) { $y_repeat = true; }
27597 else { $y_repeat = false; }
27598 $x_pos = $this->patterns[$i]['x_pos'];
27599 if (stristr($x_pos ,'%') ) {
27600 $x_pos += 0;
27601 $x_pos /= 100;
27602 if (isset($bpa['w']) && $bpa['w']) $x_pos = ($bpa['w'] * $x_pos) - ($orig_w/_MPDFK * $x_pos); // mPDF 5.6.10
27603 else $x_pos = ($w * $x_pos) - ($orig_w/_MPDFK * $x_pos);
27604 }
27605 $y_pos = $this->patterns[$i]['y_pos'];
27606 if (stristr($y_pos ,'%') ) {
27607 $y_pos += 0;
27608 $y_pos /= 100;
27609 if (isset($bpa['h']) && $bpa['h']) $y_pos = ($bpa['h'] * $y_pos) - ($orig_h/_MPDFK * $y_pos); // mPDF 5.6.10
27610 else $y_pos = ($h * $y_pos) - ($orig_h/_MPDFK * $y_pos);
27611 }
27612 if (isset($bpa['x']) && $bpa['x']) $adj_x = ($x_pos + $bpa['x']) *_MPDFK; // mPDF 5.6.10
27613 else $adj_x = ($x_pos + $x) *_MPDFK;
27614 if (isset($bpa['y']) && $bpa['y']) $adj_y = (($pgh - $y_pos - $bpa['y'])*_MPDFK) - $orig_h ; // mPDF 5.6.10
27615 else $adj_y = (($pgh - $y_pos - $y)*_MPDFK) - $orig_h ;
27616 $img_obj = false;
27617 if ($itype == 'svg' || $itype == 'wmf') {
27618 foreach($this->formobjects AS $fo) {
27619 if ($fo['i'] == $image_id) {
27620 $img_obj = $fo['n'];
27621 $fo_w = $fo['w'];
27622 $fo_h = -$fo['h'];
27623 $wmf_x = $fo['x'];
27624 $wmf_y = $fo['y'];
27625 break;
27626 }
27627 }
27628 }
27629 else {
27630 foreach($this->images AS $img) {
27631 if ($img['i'] == $image_id) { $img_obj = $img['n']; break; }
27632 }
27633 }
27634 if (!$img_obj ) { echo "Problem: Image object not found for background pattern ".$img['i']; exit; }
27635
27636 $this->_newobj();
27637 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27638 if ($itype == 'svg' || $itype == 'wmf') {
27639 $this->_out('/XObject <</FO'.$image_id.' '.$img_obj.' 0 R >>');
27640 // ******* ADD ANY ExtGStates, Shading AND Fonts needed for the FormObject
27641 // Set in classes/svg array['fo'] = true
27642 // Required that _putshaders comes before _putpatterns in _putresources
27643 // This adds any resources associated with any FormObject to every Formobject - overkill but works!
27644 if (count($this->extgstates)) {
27645 $this->_out('/ExtGState <<');
27646 foreach($this->extgstates as $k=>$extgstate)
27647 if (isset($extgstate['fo']) && $extgstate['fo']) {
27648 if (isset($extgstate['trans'])) $this->_out('/'.$extgstate['trans'].' '.$extgstate['n'].' 0 R');
27649 else $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
27650 }
27651 $this->_out('>>');
27652 }
27653 /*-- BACKGROUNDS --*/
27654 if (isset($this->gradients) AND (count($this->gradients) > 0)) {
27655 $this->_out('/Shading <<');
27656 foreach ($this->gradients as $id => $grad) {
27657 if (isset($grad['fo']) && $grad['fo']) {
27658 $this->_out('/Sh'.$id.' '.$grad['id'].' 0 R');
27659 }
27660 }
27661 $this->_out('>>');
27662 }
27663 /*-- END BACKGROUNDS --*/
27664 $this->_out('/Font <<');
27665 foreach($this->fonts as $font) {
27666 if (!$font['used'] && $font['type']=='TTF') { continue; }
27667 if (isset($font['fo']) && $font['fo']) {
27668 if ($font['type']=='TTF' && ($font['sip'] || $font['smp'])) {
27669 foreach($font['n'] AS $k => $fid) {
27670 $this->_out('/F'.$font['subsetfontids'][$k].' '.$font['n'][$k].' 0 R');
27671 }
27672 }
27673 else {
27674 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27675 }
27676 }
27677 }
27678 $this->_out('>>');
27679 }
27680 else {
27681 $this->_out('/XObject <</I'.$image_id.' '.$img_obj.' 0 R >>');
27682 }
27683 $this->_out('>>');
27684 $this->_out('endobj');
27685
27686 $this->_newobj();
27687 $this->patterns[$i]['n'] = $this->n;
27688 $this->_out('<< /Type /Pattern /PatternType 1 /PaintType 1 /TilingType 2');
27689 $this->_out('/Resources '. ($this->n-1) .' 0 R');
27690
27691 $this->_out(sprintf('/BBox [0 0 %.3F %.3F]',$orig_w,$orig_h));
27692 if ($x_repeat) { $this->_out(sprintf('/XStep %.3F',$orig_w)); }
27693 else { $this->_out(sprintf('/XStep %d',99999)); }
27694 if ($y_repeat) { $this->_out(sprintf('/YStep %.3F',$orig_h)); }
27695 else { $this->_out(sprintf('/YStep %d',99999)); }
27696
27697 if ($itype == 'svg' || $itype == 'wmf') {
27698 $this->_out(sprintf('/Matrix [1 0 0 -1 %.3F %.3F]', $adj_x, ($adj_y+$orig_h)));
27699 $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);
27700 }
27701 else {
27702 $this->_out(sprintf('/Matrix [1 0 0 1 %.3F %.3F]',$adj_x,$adj_y));
27703 $s = sprintf("q %.3F 0 0 %.3F 0 0 cm /I%d Do Q",$orig_w,$orig_h,$image_id);
27704 }
27705
27706 if ($this->compress) {
27707 $this->_out('/Filter /FlateDecode');
27708 $s = gzcompress($s);
27709 }
27710 $this->_out('/Length '.strlen($s).'>>');
27711 $this->_putstream($s);
27712 $this->_out('endobj');
27713 }
27714 }
27715
27716 /*-- BACKGROUNDS --*/
27717 function _putshaders() {
27718 $maxid = count($this->gradients); //index for transparency gradients
27719 foreach ($this->gradients as $id => $grad) {
27720 if (($grad['type'] == 2 || $grad['type'] == 3) && empty($grad['is_mask'])) {
27721 $this->_newobj();
27722 $this->_out('<<');
27723 $this->_out('/FunctionType 3');
27724 $this->_out('/Domain [0 1]');
27725 $fn = array();
27726 $bd = array();
27727 $en = array();
27728 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27729 $fn[] = ($this->n+1+$i).' 0 R';
27730 $en[] = '0 1';
27731 if ($i>0) { $bd[] = sprintf('%.3F', $grad['stops'][$i]['offset']); }
27732 }
27733 $this->_out('/Functions ['.implode(' ',$fn).']');
27734 $this->_out('/Bounds ['.implode(' ',$bd).']');
27735 $this->_out('/Encode ['.implode(' ',$en).']');
27736 $this->_out('>>');
27737 $this->_out('endobj');
27738 $f1 = $this->n;
27739 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27740 $this->_newobj();
27741 $this->_out('<<');
27742 $this->_out('/FunctionType 2');
27743 $this->_out('/Domain [0 1]');
27744 $this->_out('/C0 ['.$grad['stops'][$i]['col'].']');
27745 $this->_out('/C1 ['.$grad['stops'][$i+1]['col'].']');
27746 $this->_out('/N 1');
27747 $this->_out('>>');
27748 $this->_out('endobj');
27749 }
27750 }
27751 if ($grad['type'] == 2 || $grad['type'] == 3) {
27752 if (isset($grad['trans']) && $grad['trans']) {
27753 $this->_newobj();
27754 $this->_out('<<');
27755 $this->_out('/FunctionType 3');
27756 $this->_out('/Domain [0 1]');
27757 $fn = array();
27758 $bd = array();
27759 $en = array();
27760 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27761 $fn[] = ($this->n+1+$i).' 0 R';
27762 $en[] = '0 1';
27763 if ($i>0) { $bd[] = sprintf('%.3F', $grad['stops'][$i]['offset']); }
27764 }
27765 $this->_out('/Functions ['.implode(' ',$fn).']');
27766 $this->_out('/Bounds ['.implode(' ',$bd).']');
27767 $this->_out('/Encode ['.implode(' ',$en).']');
27768 $this->_out('>>');
27769 $this->_out('endobj');
27770 $f2 = $this->n;
27771 for($i=0; $i<(count($grad['stops'])-1); $i++) {
27772 $this->_newobj();
27773 $this->_out('<<');
27774 $this->_out('/FunctionType 2');
27775 $this->_out('/Domain [0 1]');
27776 $this->_out(sprintf('/C0 [%.3F]', $grad['stops'][$i]['opacity']));
27777 $this->_out(sprintf('/C1 [%.3F]', $grad['stops'][$i+1]['opacity']));
27778 $this->_out('/N 1');
27779 $this->_out('>>');
27780 $this->_out('endobj');
27781 }
27782 }
27783 }
27784
27785 if (empty($grad['is_mask'])) {
27786 $this->_newobj();
27787 $this->_out('<<');
27788 $this->_out('/ShadingType '.$grad['type']);
27789 if (isset($grad['colorspace'])) {
27790 $this->_out('/ColorSpace /Device'.$grad['colorspace']); // Can use CMYK if all C0 and C1 above have 4 values
27791 } else {
27792 $this->_out('/ColorSpace /DeviceRGB');
27793 }
27794 if ($grad['type'] == 2) {
27795 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]));
27796 $this->_out('/Function '.$f1.' 0 R');
27797 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27798 $this->_out('>>');
27799 }
27800 else if ($grad['type'] == 3) {
27801 //x0, y0, r0, x1, y1, r1
27802 //at this this time radius of inner circle is 0
27803 $ir = 0;
27804 if (isset($grad['coords'][5]) && $grad['coords'][5]) { $ir = $grad['coords'][5]; }
27805 $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]));
27806 $this->_out('/Function '.$f1.' 0 R');
27807 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27808 $this->_out('>>');
27809 }
27810 else if ($grad['type']==6) {
27811 $this->_out('/BitsPerCoordinate 16');
27812 $this->_out('/BitsPerComponent 8');
27813 if ($grad['colorspace'] == 'CMYK') { $this->_out('/Decode[0 1 0 1 0 1 0 1 0 1 0 1]'); }
27814 else if ($grad['colorspace'] == 'Gray') { $this->_out('/Decode[0 1 0 1 0 1]'); }
27815 else { $this->_out('/Decode[0 1 0 1 0 1 0 1 0 1]'); }
27816 $this->_out('/BitsPerFlag 8');
27817 $this->_out('/Length '.strlen($grad['stream']));
27818 $this->_out('>>');
27819 $this->_putstream($grad['stream']);
27820 }
27821 $this->_out('endobj');
27822 }
27823
27824 $this->gradients[$id]['id'] = $this->n;
27825
27826 // set pattern object
27827 $this->_newobj();
27828 $out = '<< /Type /Pattern /PatternType 2';
27829 $out .= ' /Shading '.$this->gradients[$id]['id'].' 0 R';
27830 $out .= ' >>';
27831 $out .= "\n".'endobj';
27832 $this->_out($out);
27833
27834
27835 $this->gradients[$id]['pattern'] = $this->n;
27836
27837 if (isset($grad['trans']) && $grad['trans']) {
27838 // luminosity pattern
27839 $transid = $id + $maxid;
27840 $this->_newobj();
27841 $this->_out('<<');
27842 $this->_out('/ShadingType '.$grad['type']);
27843 $this->_out('/ColorSpace /DeviceGray');
27844 if ($grad['type'] == 2) {
27845 $this->_out(sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]));
27846 $this->_out('/Function '.$f2.' 0 R');
27847 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27848 $this->_out('>>');
27849 }
27850 else if ($grad['type'] == 3) {
27851 //x0, y0, r0, x1, y1, r1
27852 //at this this time radius of inner circle is 0
27853 $ir = 0;
27854 if (isset($grad['coords'][5]) && $grad['coords'][5]) { $ir = $grad['coords'][5]; }
27855 $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]));
27856 $this->_out('/Function '.$f2.' 0 R');
27857 $this->_out('/Extend ['.$grad['extend'][0].' '.$grad['extend'][1].'] ');
27858 $this->_out('>>');
27859 }
27860 else if ($grad['type']==6) {
27861 $this->_out('/BitsPerCoordinate 16');
27862 $this->_out('/BitsPerComponent 8');
27863 $this->_out('/Decode[0 1 0 1 0 1]');
27864 $this->_out('/BitsPerFlag 8');
27865 $this->_out('/Length '.strlen($grad['stream_trans']));
27866 $this->_out('>>');
27867 $this->_putstream($grad['stream_trans']);
27868 }
27869 $this->_out('endobj');
27870
27871 $this->gradients[$transid]['id'] = $this->n;
27872 $this->_newobj();
27873 $this->_out('<< /Type /Pattern /PatternType 2');
27874 $this->_out('/Shading '.$this->gradients[$transid]['id'].' 0 R');
27875 $this->_out('>>');
27876 $this->_out('endobj');
27877 $this->gradients[$transid]['pattern'] = $this->n;
27878 $this->_newobj();
27879 // Need to extend size of viewing box in case of transformations
27880 $str = 'q /a0 gs /Pattern cs /p'.$transid.' scn -'.($this->wPt/2).' -'.($this->hPt/2).' '.(2*$this->wPt).' '.(2*$this->hPt).' re f Q';
27881 $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
27882 $p=($this->compress) ? gzcompress($str) : $str;
27883 $this->_out('<< /Type /XObject /Subtype /Form /FormType 1 '.$filter);
27884 $this->_out('/Length '.strlen($p));
27885 $this->_out('/BBox [-'.($this->wPt/2).' -'.($this->hPt/2).' '.(2*$this->wPt).' '.(2*$this->hPt).']');
27886 $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceGray >>');
27887 $this->_out('/Resources <<');
27888 $this->_out('/ExtGState << /a0 << /ca 1 /CA 1 >> >>');
27889 $this->_out('/Pattern << /p'.$transid.' '.$this->gradients[$transid]['pattern'].' 0 R >>');
27890 $this->_out('>>');
27891 $this->_out('>>');
27892 $this->_putstream($p);
27893 $this->_out('endobj');
27894 $this->_newobj();
27895 $this->_out('<< /Type /Mask /S /Luminosity /G '.($this->n - 1).' 0 R >>'."\n".'endobj');
27896 $this->_newobj();
27897 $this->_out('<< /Type /ExtGState /SMask '.($this->n - 1).' 0 R /AIS false >>'."\n".'endobj');
27898 if ($grad['fo']) { $this->extgstates[] = array('n' => $this->n, 'trans' => 'TGS'.$id, 'fo'=>true); }
27899 else { $this->extgstates[] = array('n' => $this->n, 'trans' => 'TGS'.$id); }
27900 }
27901 }
27902 }
27903 /*-- END BACKGROUNDS --*/
27904
27905 function _putspotcolors() {
27906 foreach($this->spotColors as $name=>$color) {
27907 $this->_newobj();
27908 $this->_out('[/Separation /'.str_replace(' ','#20',$name));
27909 $this->_out('/DeviceCMYK <<');
27910 $this->_out('/Range [0 1 0 1 0 1 0 1] /C0 [0 0 0 0] ');
27911 $this->_out(sprintf('/C1 [%.3F %.3F %.3F %.3F] ',$color['c']/100,$color['m']/100,$color['y']/100,$color['k']/100));
27912 $this->_out('/FunctionType 2 /Domain [0 1] /N 1>>]');
27913 $this->_out('endobj');
27914 $this->spotColors[$name]['n']=$this->n;
27915 }
27916 }
27917
27918
27919 function _putresources() {
27920 if ($this->hasOC || count($this->layers)) // mPDF 5.6.01
27921 $this->_putocg();
27922 $this->_putextgstates();
27923 $this->_putspotcolors();
27924 if ($this->progressBar) { $this->UpdateProgressBar(2,'40','Compiling Fonts'); } // *PROGRESS-BAR*
27925 $this->_putfonts();
27926 if ($this->progressBar) { $this->UpdateProgressBar(2,'50','Compiling Images'); } // *PROGRESS-BAR*
27927 $this->_putimages();
27928 $this->_putformobjects(); // *IMAGES-CORE*
27929
27930 /*-- IMPORTS --*/
27931 if ($this->enableImports) {
27932 $this->_putformxobjects();
27933 $this->_putimportedobjects();
27934 }
27935 /*-- END IMPORTS --*/
27936
27937 /*-- BACKGROUNDS --*/
27938 $this->_putshaders();
27939 $this->_putpatterns();
27940 /*-- END BACKGROUNDS --*/
27941
27942
27943 //Resource dictionary
27944 $this->offsets[2]=strlen($this->buffer);
27945 $this->_out('2 0 obj');
27946 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
27947
27948 $this->_out('/Font <<');
27949 foreach($this->fonts as $font) {
27950 if (!$font['used'] && $font['type']=='TTF') { continue; }
27951 if ($font['type']=='TTF' && ($font['sip'] || $font['smp'])) {
27952 foreach($font['n'] AS $k => $fid) {
27953 $this->_out('/F'.$font['subsetfontids'][$k].' '.$font['n'][$k].' 0 R');
27954 }
27955 }
27956 else {
27957 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
27958 }
27959 }
27960 $this->_out('>>');
27961
27962 if (count($this->spotColors)) {
27963 $this->_out('/ColorSpace <<');
27964 foreach($this->spotColors as $color)
27965 $this->_out('/CS'.$color['i'].' '.$color['n'].' 0 R');
27966 $this->_out('>>');
27967 }
27968
27969 if (count($this->extgstates)) {
27970 $this->_out('/ExtGState <<');
27971 foreach($this->extgstates as $k=>$extgstate)
27972 if (isset($extgstate['trans'])) $this->_out('/'.$extgstate['trans'].' '.$extgstate['n'].' 0 R');
27973 else $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
27974 $this->_out('>>');
27975 }
27976
27977 /*-- BACKGROUNDS --*/
27978 if ((isset($this->gradients) AND (count($this->gradients) > 0)) || ($this->enableImports && count($this->tpls))) { // mPDF 5.7.3
27979 $this->_out('/Shading <<');
27980 foreach ($this->gradients as $id => $grad) {
27981 $this->_out('/Sh'.$id.' '.$grad['id'].' 0 R');
27982 }
27983 // mPDF 5.7.3
27984 // If a shading dictionary is in an object (tpl) imported from another PDF, it needs to be included
27985 // in the document resources, as well as the object resources
27986 // Otherwise get an error in some PDF viewers
27987 if ($this->enableImports && count($this->tpls)) {
27988 foreach($this->tpls as $tplidx => $tpl) {
27989 if (isset($tpl['resources'])) {
27990 $this->current_parser =& $tpl['parser'];
27991 reset ($tpl['resources'][1]);
27992 while (list($k, $v) = each($tpl['resources'][1])) {
27993 if ($k == '/Shading') {
27994 while (list($k2, $v2) = each($v[1])) {
27995 $this->_out($k2 . " ",false);
27996 $this->pdf_write_value($v2);
27997 }
27998 }
27999 }
28000
28001
28002 }
28003 }
28004 }
28005
28006 $this->_out('>>');
28007 /*
28008 // ??? Not needed !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
28009 $this->_out('/Pattern <<');
28010 foreach ($this->gradients as $id => $grad) {
28011 $this->_out('/P'.$id.' '.$grad['pattern'].' 0 R');
28012 }
28013 $this->_out('>>');
28014 */
28015 }
28016 /*-- END BACKGROUNDS --*/
28017
28018 if(count($this->images) || count($this->formobjects) || ($this->enableImports && count($this->tpls))) {
28019 $this->_out('/XObject <<');
28020 foreach($this->images as $image)
28021 $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
28022 foreach($this->formobjects as $formobject)
28023 $this->_out('/FO'.$formobject['i'].' '.$formobject['n'].' 0 R');
28024 /*-- IMPORTS --*/
28025 if ($this->enableImports && count($this->tpls)) {
28026 foreach($this->tpls as $tplidx => $tpl) {
28027 $this->_out($this->tplprefix.$tplidx.' '.$tpl['n'].' 0 R');
28028 }
28029 }
28030 /*-- END IMPORTS --*/
28031 $this->_out('>>');
28032 }
28033
28034 /*-- BACKGROUNDS --*/
28035
28036 if (count($this->patterns)) {
28037 $this->_out('/Pattern <<');
28038 foreach($this->patterns as $k=>$patterns)
28039 $this->_out('/P'.$k.' '.$patterns['n'].' 0 R');
28040 $this->_out('>>');
28041 }
28042 /*-- END BACKGROUNDS --*/
28043
28044 // mPDF 5.6.01
28045 if ($this->hasOC || count($this->layers)) {
28046 $this->_out('/Properties <<');
28047 if ($this->hasOC) {
28048 $this->_out('/OC1 '.$this->n_ocg_print.' 0 R /OC2 '.$this->n_ocg_view.' 0 R /OC3 '.$this->n_ocg_hidden.' 0 R ');
28049 }
28050 if (count($this->layers)) {
28051 foreach($this->layers as $id=>$layer)
28052 $this->_out('/ZI'.$id.' '.$layer['n'].' 0 R');
28053 }
28054 $this->_out('>>');
28055 }
28056
28057 $this->_out('>>');
28058 $this->_out('endobj'); // end resource dictionary
28059
28060 $this->_putbookmarks(); // *BOOKMARKS*
28061
28062 if (isset($this->js) && $this->js) {
28063 $this->_putjavascript();
28064 }
28065
28066 /*-- ENCRYPTION --*/
28067 if ($this->encrypted) {
28068 $this->_newobj();
28069 $this->enc_obj_id = $this->n;
28070 $this->_out('<<');
28071 $this->_putencryption();
28072 $this->_out('>>');
28073 $this->_out('endobj');
28074 }
28075 /*-- END ENCRYPTION --*/
28076 }
28077
28078
28079 function _putjavascript() {
28080 $this->_newobj();
28081 $this->n_js = $this->n;
28082 $this->_out('<<');
28083 $this->_out('/Names [(EmbeddedJS) '.(1 + $this->n).' 0 R ]');
28084 $this->_out('>>');
28085 $this->_out('endobj');
28086
28087 $this->_newobj();
28088 $this->_out('<<');
28089 $this->_out('/S /JavaScript');
28090 $this->_out('/JS '.$this->_textstring($this->js));
28091 $this->_out('>>');
28092 $this->_out('endobj');
28093 }
28094
28095
28096
28097
28098 /*-- ENCRYPTION --*/
28099 function _putencryption() {
28100 $this->_out('/Filter /Standard');
28101 if ($this->useRC128encryption) {
28102 $this->_out('/V 2');
28103 $this->_out('/R 3');
28104 $this->_out('/Length 128');
28105 }
28106 else {
28107 $this->_out('/V 1');
28108 $this->_out('/R 2');
28109 }
28110 $this->_out('/O ('.$this->_escape($this->Ovalue).')');
28111 $this->_out('/U ('.$this->_escape($this->Uvalue).')');
28112 $this->_out('/P '.$this->Pvalue);
28113 }
28114 /*-- END ENCRYPTION --*/
28115
28116 function _puttrailer() {
28117 $this->_out('/Size '.($this->n+1));
28118 $this->_out('/Root '.$this->n.' 0 R');
28119 $this->_out('/Info '.$this->InfoRoot.' 0 R');
28120 /*-- ENCRYPTION --*/
28121 if ($this->encrypted) {
28122 $this->_out('/Encrypt '.$this->enc_obj_id.' 0 R');
28123 $this->_out('/ID [<'.$this->uniqid.'> <'.$this->uniqid.'>]');
28124 }
28125 else {
28126 /*-- END ENCRYPTION --*/
28127 $uniqid = md5(time() . $this->buffer);
28128 $this->_out('/ID [<'.$uniqid.'> <'.$uniqid.'>]');
28129 /*-- ENCRYPTION --*/
28130 }
28131 /*-- END ENCRYPTION --*/
28132 }
28133
28134 /*-- ENCRYPTION --*/
28135 function SetProtection($permissions=array(),$user_pass='',$owner_pass=null, $length=40) {
28136 $this->encrypted=false;
28137 if (is_string($permissions) && strlen($permissions)>0) { $permissions = array($permissions); }
28138 else if (!is_array($permissions)) { return 0; }
28139 $this->last_rc4_key='';
28140 $this->padding="\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08".
28141 "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
28142
28143 $options = array(
28144 'print' => 4, // bit 3
28145 'modify' => 8, // bit 4
28146 'copy' => 16, // bit 5
28147 'annot-forms' => 32, // bit 6
28148 'fill-forms' => 256, // bit 9
28149 'extract' => 512, // bit 10
28150 'assemble' => 1024,// bit 11
28151 'print-highres' => 2048 // bit 12
28152 );
28153 // bit 31 = 1073741824
28154 // bit 32 = 2147483648
28155 // bits 13-31 = 2147479552
28156 // bits 13-32 = 4294963200 + 192 = 4294963392
28157 $protection = 4294963392; // bits 7,8,13-32
28158 foreach ($permissions as $permission) {
28159 if (!isset($options[$permission]))
28160 $this->Error('Incorrect permission: '.$permission);
28161 if ($options[$permission] > 32) { $this->useRC128encryption = true; }
28162 if (isset($options[$permission])) $protection += $options[$permission];
28163 }
28164 if ($length==128) { $this->useRC128encryption = true; }
28165 if ($owner_pass === null)
28166 $owner_pass = uniqid(rand());
28167 $this->encrypted = true;
28168 $this->_generateencryptionkey($user_pass, $owner_pass, $protection);
28169 }
28170
28171
28172 // Compute key depending on object number where the encrypted data is stored
28173 function _objectkey($n) {
28174 if ($this->useRC128encryption)
28175 $len = 16;
28176 else
28177 $len = 10;
28178 return substr($this->_md5_16($this->encryption_key.pack('VXxx',$n)),0,$len);
28179 }
28180
28181 // RC4 is the standard encryption algorithm used in PDF format
28182 function _RC4($key, $text) {
28183 if ($this->last_rc4_key != $key) {
28184 $k = str_repeat($key, 256/strlen($key)+1);
28185 $rc4 = range(0,255);
28186 $j = 0;
28187 for ($i=0; $i<256; $i++){
28188 $t = $rc4[$i];
28189 $j = ($j + $t + ord($k[$i])) % 256;
28190 $rc4[$i] = $rc4[$j];
28191 $rc4[$j] = $t;
28192 }
28193 $this->last_rc4_key = $key;
28194 $this->last_rc4_key_c = $rc4;
28195 } else {
28196 $rc4 = $this->last_rc4_key_c;
28197 }
28198
28199 $len = strlen($text);
28200 $a = 0;
28201 $b = 0;
28202 $out = '';
28203 for ($i=0; $i<$len; $i++){
28204 $a = ($a+1)%256;
28205 $t= $rc4[$a];
28206 $b = ($b+$t)%256;
28207 $rc4[$a] = $rc4[$b];
28208 $rc4[$b] = $t;
28209 $k = $rc4[($rc4[$a]+$rc4[$b])%256];
28210 $out.= chr(ord($text[$i]) ^ $k);
28211 }
28212 return $out;
28213 }
28214
28215 // Get MD5 as binary string
28216 function _md5_16($string) {
28217 return pack('H*',md5($string));
28218 }
28219
28220 // Compute O value
28221 function _Ovalue($user_pass, $owner_pass) {
28222 $tmp = $this->_md5_16($owner_pass);
28223 if ($this->useRC128encryption) {
28224 for ($i = 0; $i < 50; ++$i) {
28225 $tmp = $this->_md5_16($tmp);
28226 }
28227 }
28228 if ($this->useRC128encryption)
28229 $keybytelen = (128 / 8);
28230 else
28231 $keybytelen = (40 / 8);
28232 $owner_RC4_key = substr($tmp,0,$keybytelen);
28233 $enc = $this->_RC4($owner_RC4_key, $user_pass);
28234 if ($this->useRC128encryption) {
28235 $len = strlen($owner_RC4_key);
28236 for ($i = 1; $i <= 19; ++$i) {
28237 $key = '';
28238 for ($j = 0; $j < $len; ++$j) {
28239 $key .= chr(ord($owner_RC4_key{$j}) ^ $i);
28240 }
28241 $enc = $this->_RC4($key, $enc);
28242 }
28243 }
28244 return $enc;
28245 }
28246
28247 // Compute U value
28248 function _Uvalue() {
28249 if ($this->useRC128encryption) {
28250 $tmp = $this->_md5_16($this->padding.$this->_hexToString($this->uniqid));
28251 $enc = $this->_RC4($this->encryption_key, $tmp);
28252 $len = strlen($tmp);
28253 for ($i=1; $i<=19; ++$i) {
28254 $key = '';
28255 for ($j=0; $j<$len; ++$j) {
28256 $key .= chr(ord($this->encryption_key{$j}) ^ $i);
28257 }
28258 $enc = $this->_RC4($key, $enc);
28259 }
28260 $enc .= str_repeat("\x00", 16);
28261 return substr($enc, 0, 32);
28262 }
28263 else {
28264 return $this->_RC4($this->encryption_key, $this->padding);
28265 }
28266 }
28267
28268 // Compute encryption key
28269 function _generateencryptionkey($user_pass, $owner_pass, $protection) {
28270 // Pad passwords
28271 $user_pass = substr($user_pass.$this->padding,0,32);
28272 $owner_pass = substr($owner_pass.$this->padding,0,32);
28273 $chars = 'ABCDEF1234567890';
28274 $id = '';
28275 for ($i=0; $i<32; $i++) { $id .= $chars{rand(0, 15)}; }
28276 $this->uniqid = md5($id);
28277 // Compute O value
28278 $this->Ovalue = $this->_Ovalue($user_pass,$owner_pass);
28279 // Compute encyption key
28280 if ($this->useRC128encryption)
28281 $keybytelen = (128/8);
28282 else
28283 $keybytelen = (40/8);
28284 $prot = sprintf('%032b', $protection);
28285 $perms = chr(bindec(substr($prot,24,8)));
28286 $perms .= chr(bindec(substr($prot,16,8)));
28287 $perms .= chr(bindec(substr($prot,8,8)));
28288 $perms .= chr(bindec(substr($prot,0,8)));
28289 $tmp = $this->_md5_16($user_pass.$this->Ovalue.$perms.$this->_hexToString($this->uniqid));
28290 if ($this->useRC128encryption) {
28291 for ($i=0; $i<50; ++$i) {
28292 $tmp = $this->_md5_16(substr($tmp, 0, $keybytelen));
28293 }
28294 }
28295 $this->encryption_key = substr($tmp,0,$keybytelen);
28296 // Compute U value
28297 $this->Uvalue = $this->_Uvalue();
28298 // Compute P value
28299 $this->Pvalue = $protection;
28300 }
28301
28302
28303 function _hexToString($hs) {
28304 $s = '';
28305 $len = strlen($hs);
28306 if (($len % 2) != 0) {
28307 $hs .= '0';
28308 ++$len;
28309 }
28310 for ($i = 0; $i < $len; $i += 2) {
28311 $s .= chr(hexdec($hs{$i}.$hs{($i + 1)}));
28312 }
28313 return $s;
28314 }
28315
28316 /*-- END ENCRYPTION --*/
28317
28318 //=========================================
28319 /*-- BOOKMARKS --*/
28320 // FROM class PDF_Bookmark
28321
28322 function Bookmark($txt,$level=0,$y=0) {
28323 $txt = $this->purify_utf8_text($txt);
28324 if ($this->text_input_as_HTML) {
28325 $txt = $this->all_entities_to_utf8($txt);
28326 }
28327 if($y==-1) {
28328 if (!$this->ColActive){ $y=$this->y; }
28329 else { $y = $this->y0; } // If columns are on - mark top of columns
28330 }
28331 // else y is used as set, or =0 i.e. top of page
28332 // DIRECTIONALITY RTL
28333 $bmo = array('t'=>$txt,'l'=>$level,'y'=>$y,'p'=>$this->page);
28334 if ($this->keep_block_together) {
28335 $this->ktBMoutlines[]= $bmo;
28336 }
28337 /*-- TABLES --*/
28338 else if ($this->table_rotate) {
28339 $this->tbrot_BMoutlines[]= $bmo;
28340 }
28341 else if ($this->kwt) {
28342 $this->kwt_BMoutlines[]= $bmo;
28343 }
28344 /*-- END TABLES --*/
28345 else if ($this->ColActive) { // *COLUMNS*
28346 $this->col_BMoutlines[]= $bmo; // *COLUMNS*
28347 } // *COLUMNS*
28348 else {
28349 $this->BMoutlines[]= $bmo;
28350 }
28351 }
28352
28353
28354 function _putbookmarks()
28355 {
28356 $nb=count($this->BMoutlines);
28357 if($nb==0)
28358 return;
28359
28360 // mPDF 5.6.36
28361 $bmo = $this->BMoutlines;
28362 $this->BMoutlines = array();
28363 $lastlevel = -1;
28364 for($i=0;$i<count($bmo);$i++) {
28365 if ($bmo[$i]['l']>0) {
28366 while($bmo[$i]['l']-$lastlevel > 1) { // If jump down more than one level, insert a new entry
28367 $new = $bmo[$i];
28368 $new['t']="[".$new['t']."]"; // Put [] around text/title to highlight
28369 $new['l']=$lastlevel+1;
28370 $lastlevel++;
28371 $this->BMoutlines[] = $new;
28372 }
28373 }
28374 $this->BMoutlines[] = $bmo[$i];
28375 $lastlevel = $bmo[$i]['l'];
28376 }
28377 $nb=count($this->BMoutlines);
28378
28379 $lru=array();
28380 $level=0;
28381 foreach($this->BMoutlines as $i=>$o) {
28382 if($o['l']>0) {
28383 $parent=$lru[$o['l']-1];
28384 //Set parent and last pointers
28385 $this->BMoutlines[$i]['parent']=$parent;
28386 $this->BMoutlines[$parent]['last']=$i;
28387 if($o['l']>$level) {
28388 //Level increasing: set first pointer
28389 $this->BMoutlines[$parent]['first']=$i;
28390 }
28391 }
28392 else {
28393 $this->BMoutlines[$i]['parent']=$nb;
28394 }
28395 if($o['l']<=$level and $i>0) {
28396 //Set prev and next pointers
28397 $prev=$lru[$o['l']];
28398 $this->BMoutlines[$prev]['next']=$i;
28399 $this->BMoutlines[$i]['prev']=$prev;
28400 }
28401 $lru[$o['l']]=$i;
28402 $level=$o['l'];
28403 }
28404
28405
28406 //Outline items
28407 $n=$this->n+1;
28408 foreach($this->BMoutlines as $i=>$o) {
28409 $this->_newobj();
28410 $this->_out('<</Title '.$this->_UTF16BEtextstring($o['t']));
28411 $this->_out('/Parent '.($n+$o['parent']).' 0 R');
28412 if(isset($o['prev']))
28413 $this->_out('/Prev '.($n+$o['prev']).' 0 R');
28414 if(isset($o['next']))
28415 $this->_out('/Next '.($n+$o['next']).' 0 R');
28416 if(isset($o['first']))
28417 $this->_out('/First '.($n+$o['first']).' 0 R');
28418 if(isset($o['last']))
28419 $this->_out('/Last '.($n+$o['last']).' 0 R');
28420
28421
28422 if (isset($this->pageDim[$o['p']]['h'])) { $h=$this->pageDim[$o['p']]['h']; }
28423 else { $h = 0; }
28424
28425 $this->_out(sprintf('/Dest [%d 0 R /XYZ 0 %.3F null]',1+2*($o['p']),($h-$o['y'])*_MPDFK));
28426 if (isset($this->bookmarkStyles) && isset($this->bookmarkStyles[$o['l']])) {
28427 // font style
28428 $bms = $this->bookmarkStyles[$o['l']]['style'];
28429 $style = 0;
28430 if (strpos($bms,'B') !== false) { $style += 2; }
28431 if (strpos($bms,'I') !== false) { $style += 1; }
28432 $this->_out(sprintf('/F %d', $style));
28433 // Colour
28434 $col = $this->bookmarkStyles[$o['l']]['color'];
28435 if (isset($col) && is_array($col) && count($col)==3) {
28436 $this->_out(sprintf('/C [%.3F %.3F %.3F]', ($col[0]/255), ($col[1]/255), ($col[2]/255)));
28437 }
28438 }
28439
28440 $this->_out('/Count 0>>');
28441 $this->_out('endobj');
28442 }
28443 //Outline root
28444 $this->_newobj();
28445 $this->OutlineRoot=$this->n;
28446 $this->_out('<</Type /BMoutlines /First '.$n.' 0 R');
28447 $this->_out('/Last '.($n+$lru[0]).' 0 R>>');
28448 $this->_out('endobj');
28449 }
28450 /*-- END BOOKMARKS --*/
28451
28452
28453
28454 //======================================================
28455
28456
28457 // DEPRACATED but included for backwards compatability
28458 function startPageNums() {
28459 }
28460
28461 //======================================================
28462 /*-- TOC --*/
28463 // ToC TABLE OF CONTENTS
28464
28465 // Initiate, and Mark a place for the Table of Contents to be inserted
28466 function TOC($tocfont='', $tocfontsize=0, $tocindent=0, $resetpagenum='', $pagenumstyle='', $suppress='', $toc_orientation='', $TOCusePaging=true, $TOCuseLinking=false, $toc_id=0, $tocoutdent='') { // mPDF 5.6.19
28467 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28468 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28469 $this->tocontents->TOC($tocfont, $tocfontsize, $tocindent, $resetpagenum, $pagenumstyle, $suppress, $toc_orientation, $TOCusePaging, $TOCuseLinking, $toc_id, $tocoutdent); // mPDF 5.6.19
28470 }
28471
28472
28473 function TOCpagebreakByArray($a) {
28474 if (!is_array($a)) { $a = array(); }
28475 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28476 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28477 $tocoutdent = (isset($a['tocoutdent']) ? $a['tocoutdent'] : (isset($a['outdent']) ? $a['outdent'] : ''));
28478 $TOCusePaging = (isset($a['TOCusePaging']) ? $a['TOCusePaging'] : (isset($a['paging']) ? $a['paging'] : true));
28479 $TOCuseLinking = (isset($a['TOCuseLinking']) ? $a['TOCuseLinking'] : (isset($a['links']) ? $a['links'] : ''));
28480 $toc_orientation = (isset($a['toc_orientation']) ? $a['toc_orientation'] : (isset($a['toc-orientation']) ? $a['toc-orientation'] : ''));
28481 $toc_mgl = (isset($a['toc_mgl']) ? $a['toc_mgl'] : (isset($a['toc-margin-left']) ? $a['toc-margin-left'] : ''));
28482 $toc_mgr = (isset($a['toc_mgr']) ? $a['toc_mgr'] : (isset($a['toc-margin-right']) ? $a['toc-margin-right'] : ''));
28483 $toc_mgt = (isset($a['toc_mgt']) ? $a['toc_mgt'] : (isset($a['toc-margin-top']) ? $a['toc-margin-top'] : ''));
28484 $toc_mgb = (isset($a['toc_mgb']) ? $a['toc_mgb'] : (isset($a['toc-margin-bottom']) ? $a['toc-margin-bottom'] : ''));
28485 $toc_mgh = (isset($a['toc_mgh']) ? $a['toc_mgh'] : (isset($a['toc-margin-header']) ? $a['toc-margin-header'] : ''));
28486 $toc_mgf = (isset($a['toc_mgf']) ? $a['toc_mgf'] : (isset($a['toc-margin-footer']) ? $a['toc-margin-footer'] : ''));
28487 $toc_ohname = (isset($a['toc_ohname']) ? $a['toc_ohname'] : (isset($a['toc-odd-header-name']) ? $a['toc-odd-header-name'] : ''));
28488 $toc_ehname = (isset($a['toc_ehname']) ? $a['toc_ehname'] : (isset($a['toc-even-header-name']) ? $a['toc-even-header-name'] : ''));
28489 $toc_ofname = (isset($a['toc_ofname']) ? $a['toc_ofname'] : (isset($a['toc-odd-footer-name']) ? $a['toc-odd-footer-name'] : ''));
28490 $toc_efname = (isset($a['toc_efname']) ? $a['toc_efname'] : (isset($a['toc-even-footer-name']) ? $a['toc-even-footer-name'] : ''));
28491 $toc_ohvalue = (isset($a['toc_ohvalue']) ? $a['toc_ohvalue'] : (isset($a['toc-odd-header-value']) ? $a['toc-odd-header-value'] : 0));
28492 $toc_ehvalue = (isset($a['toc_ehvalue']) ? $a['toc_ehvalue'] : (isset($a['toc-even-header-value']) ? $a['toc-even-header-value'] : 0));
28493 $toc_ofvalue = (isset($a['toc_ofvalue']) ? $a['toc_ofvalue'] : (isset($a['toc-odd-footer-value']) ? $a['toc-odd-footer-value'] : 0));
28494 $toc_efvalue = (isset($a['toc_efvalue']) ? $a['toc_efvalue'] : (isset($a['toc-even-footer-value']) ? $a['toc-even-footer-value'] : 0));
28495 $toc_preHTML = (isset($a['toc_preHTML']) ? $a['toc_preHTML'] : (isset($a['toc-preHTML']) ? $a['toc-preHTML'] : ''));
28496 $toc_postHTML = (isset($a['toc_postHTML']) ? $a['toc_postHTML'] : (isset($a['toc-postHTML']) ? $a['toc-postHTML'] : ''));
28497 $toc_bookmarkText = (isset($a['toc_bookmarkText']) ? $a['toc_bookmarkText'] : (isset($a['toc-bookmarkText']) ? $a['toc-bookmarkText'] : ''));
28498 $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : '');
28499 $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : '');
28500 $suppress = (isset($a['suppress']) ? $a['suppress'] : '');
28501 $orientation = (isset($a['orientation']) ? $a['orientation'] : '');
28502 $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
28503 $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
28504 $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
28505 $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
28506 $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
28507 $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
28508 $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
28509 $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
28510 $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
28511 $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
28512 $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
28513 $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
28514 $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
28515 $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
28516 $toc_id = (isset($a['toc_id']) ? $a['toc_id'] : (isset($a['name']) ? $a['name'] : 0));
28517 $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : ''));
28518 $toc_pagesel = (isset($a['toc_pagesel']) ? $a['toc_pagesel'] : (isset($a['toc-pageselector']) ? $a['toc-pageselector'] : ''));
28519 $sheetsize = (isset($a['sheetsize']) ? $a['sheetsize'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
28520 $toc_sheetsize = (isset($a['toc_sheetsize']) ? $a['toc_sheetsize'] : (isset($a['toc-sheet-size']) ? $a['toc-sheet-size'] : ''));
28521
28522 $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
28523
28524 }
28525
28526 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) {
28527 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28528 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28529 //Start a new page
28530 if($this->state==0) $this->AddPage();
28531 if ($this->y == $this->tMargin && (!$this->mirrorMargins ||($this->mirrorMargins && $this->page % 2==1))) {
28532 // Don't add a page
28533 if ($this->page==1 && count($this->PageNumSubstitutions)==0) {
28534 if (!$suppress) { $suppress = 'off'; }
28535 if (!$resetpagenum) { $resetpagenum= 1; }
28536 //$this->PageNumSubstitutions[] = array('from'=>1, 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=> $suppress);
28537 }
28538 $this->PageNumSubstitutions[] = array('from'=>$this->page, 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=> $suppress);
28539 }
28540 else {
28541 $this->AddPage($orientation,'NEXT-ODD', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$sheetsize);
28542 }
28543
28544 $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
28545 }
28546
28547 function TOC_Entry($txt, $level=0, $toc_id=0) {
28548 // mPDF 5.7.2
28549 if ($this->ColActive) { $ily = $this->y0; } else { $ily = $this->y; } // use top of columns
28550
28551 if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
28552 if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
28553 $linkn = $this->AddLink();
28554 $uid = '__mpdfinternallink_' . $linkn ;
28555 if ($this->keep_block_together) { $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page, "kt"=>true ); }
28556 else if ($this->table_rotate) { $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page, "tbrot"=>true ); }
28557 else if ($this->kwt) { $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page, "kwt"=>true ); }
28558 else if ($this->ColActive) { $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page, "col"=>$this->CurrCol ); }
28559 else $this->internallink[$uid] = array("Y"=>$ily,"PAGE"=>$this->page );
28560 $this->internallink['#'.$uid] = $linkn;
28561 $this->SetLink($linkn,$ily,$this->page);
28562
28563 /*-- RTL --*/
28564 if ($this->biDirectional) {
28565 $txt = preg_replace_callback("/([".$this->pregRTLchars."]+)/u", array($this, 'arabJoinPregCallback'), $txt ); // mPDF 5.7+
28566 }
28567 /*-- END RTL --*/
28568 if (strtoupper($toc_id)=='ALL') { $toc_id = '_mpdf_all'; }
28569 else if (!$toc_id) { $toc_id = 0; }
28570 else { $toc_id = strtolower($toc_id); }
28571 $btoc = array('t'=>$txt,'l'=>$level,'p'=>$this->page, 'link'=>$linkn, 'toc_id'=>$toc_id);
28572 if ($this->keep_block_together) {
28573 $this->_kttoc[]= $btoc;
28574 }
28575 /*-- TABLES --*/
28576 else if ($this->table_rotate) {
28577 $this->tbrot_toc[]= $btoc;
28578 }
28579 else if ($this->kwt) {
28580 $this->kwt_toc[]= $btoc;
28581 }
28582 /*-- END TABLES --*/
28583 else if ($this->ColActive) { // *COLUMNS*
28584 $this->col_toc[]= $btoc; // *COLUMNS*
28585 } // *COLUMNS*
28586 else {
28587 $this->tocontents->_toc[]= $btoc;
28588 }
28589 }
28590
28591 /*-- END TOC --*/
28592
28593 //======================================================
28594 function MovePages($target_page, $start_page, $end_page=-1) {
28595 // move a page/pages EARLIER in the document
28596 if ($end_page<1) { $end_page = $start_page; }
28597 $n_toc = $end_page - $start_page + 1;
28598
28599 // Set/Update PageNumSubstitutions changes before moving anything
28600 if (count($this->PageNumSubstitutions)) {
28601 $tp_present = false;
28602 $sp_present = false;
28603 $ep_present = false;
28604 foreach($this->PageNumSubstitutions AS $k=>$v) {
28605 if ($this->PageNumSubstitutions[$k]['from']==$target_page) {
28606 $tp_present = true;
28607 if ($this->PageNumSubstitutions[$k]['suppress']!='on' && $this->PageNumSubstitutions[$k]['suppress']!=1) {
28608 $this->PageNumSubstitutions[$k]['suppress']='off';
28609 }
28610 }
28611 if ($this->PageNumSubstitutions[$k]['from']==$start_page) {
28612 $sp_present = true;
28613 if ($this->PageNumSubstitutions[$k]['suppress']!='on' && $this->PageNumSubstitutions[$k]['suppress']!=1) {
28614 $this->PageNumSubstitutions[$k]['suppress']='off';
28615 }
28616 }
28617 if ($this->PageNumSubstitutions[$k]['from']==($end_page+1)) {
28618 $ep_present = true;
28619 if ($this->PageNumSubstitutions[$k]['suppress']!='on' && $this->PageNumSubstitutions[$k]['suppress']!=1) {
28620 $this->PageNumSubstitutions[$k]['suppress']='off';
28621 }
28622 }
28623 }
28624
28625 if (!$tp_present) {
28626 list($tp_type, $tp_suppress, $tp_reset) = $this->docPageSettings($target_page);
28627 }
28628 if (!$sp_present) {
28629 list($sp_type, $sp_suppress, $sp_reset) = $this->docPageSettings($start_page);
28630 }
28631 if (!$ep_present) {
28632 list($ep_type, $ep_suppress, $ep_reset) = $this->docPageSettings($start_page-1);
28633 }
28634
28635 }
28636
28637 $last = array();
28638 //store pages
28639 for($i = $start_page;$i <= $end_page ;$i++)
28640 $last[]=$this->pages[$i];
28641 //move pages
28642 for($i=$start_page - 1;$i>=($target_page);$i--) {
28643 $this->pages[$i+$n_toc]=$this->pages[$i];
28644 }
28645 //Put toc pages at insert point
28646 for($i = 0;$i < $n_toc;$i++) {
28647 $this->pages[$target_page + $i]=$last[$i];
28648 }
28649
28650 /*-- BOOKMARKS --*/
28651 // Update Bookmarks
28652 foreach($this->BMoutlines as $i=>$o) {
28653 if($o['p']>=$target_page) {
28654 $this->BMoutlines[$i]['p'] += $n_toc;
28655 }
28656 }
28657 /*-- END BOOKMARKS --*/
28658
28659 // Update Page Links
28660 if (count($this->PageLinks)) {
28661 $newarr = array();
28662 foreach($this->PageLinks as $i=>$o) {
28663 foreach($this->PageLinks[$i] as $key => $pl) {
28664 if (strpos($pl[4],'@')===0) {
28665 $p=substr($pl[4],1);
28666 if($p>=$start_page && $p<=$end_page) {
28667 $this->PageLinks[$i][$key][4] = '@'.($p + ($target_page - $start_page));
28668 }
28669 else if($p>=$target_page && $p<$start_page) {
28670 $this->PageLinks[$i][$key][4] = '@'.($p+$n_toc);
28671 }
28672 }
28673 }
28674 if($i>=$start_page && $i<=$end_page) {
28675 $newarr[($i + ($target_page - $start_page))] = $this->PageLinks[$i];
28676 }
28677 else if($i>=$target_page && $i<$start_page) {
28678 $newarr[($i + $n_toc)] = $this->PageLinks[$i];
28679 }
28680 else {
28681 $newarr[$i] = $this->PageLinks[$i];
28682 }
28683 }
28684 $this->PageLinks = $newarr;
28685 }
28686
28687 // OrientationChanges
28688 if (count($this->OrientationChanges)) {
28689 $newarr = array();
28690 foreach($this->OrientationChanges AS $p=>$v) {
28691 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->OrientationChanges[$p]; }
28692 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->OrientationChanges[$p]; }
28693 else { $newarr[$p] = $this->OrientationChanges[$p]; }
28694 }
28695 ksort($newarr);
28696 $this->OrientationChanges = $newarr;
28697 }
28698
28699 // Page Dimensions
28700 if (count($this->pageDim)) {
28701 $newarr = array();
28702 foreach($this->pageDim AS $p=>$v) {
28703 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->pageDim[$p]; }
28704 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->pageDim[$p]; }
28705 else { $newarr[$p] = $this->pageDim[$p]; }
28706 }
28707 ksort($newarr);
28708 $this->pageDim = $newarr;
28709 }
28710
28711 // HTML Headers & Footers
28712 if (count($this->saveHTMLHeader)) {
28713 $newarr = array();
28714 foreach($this->saveHTMLHeader AS $p=>$v) {
28715 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->saveHTMLHeader[$p]; }
28716 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->saveHTMLHeader[$p]; }
28717 else { $newarr[$p] = $this->saveHTMLHeader[$p]; }
28718 }
28719 ksort($newarr);
28720 $this->saveHTMLHeader = $newarr;
28721 }
28722 if (count($this->saveHTMLFooter)) {
28723 $newarr = array();
28724 foreach($this->saveHTMLFooter AS $p=>$v) {
28725 if($p>=$start_page && $p<=$end_page) { $newarr[($p + ($target_page - $start_page))] = $this->saveHTMLFooter[$p]; }
28726 else if($p>=$target_page && $p<$start_page) { $newarr[$p+$n_toc] = $this->saveHTMLFooter[$p]; }
28727 else { $newarr[$p] = $this->saveHTMLFooter[$p]; }
28728 }
28729 ksort($newarr);
28730 $this->saveHTMLFooter = $newarr;
28731 }
28732
28733 // Update Internal Links
28734 if (count($this->internallink)) {
28735 foreach($this->internallink as $key=>$o) {
28736 if($o['PAGE']>=$start_page && $o['PAGE']<=$end_page) {
28737 $this->internallink[$key]['PAGE'] += ($target_page - $start_page);
28738 }
28739 else if($o['PAGE']>=$target_page && $o['PAGE']<$start_page) {
28740 $this->internallink[$key]['PAGE'] += $n_toc;
28741 }
28742 }
28743 }
28744
28745 // Update Links
28746 if (count($this->links)) {
28747 foreach($this->links as $key=>$o) {
28748 if($o[0]>=$start_page && $o[0]<=$end_page) {
28749 $this->links[$key][0] += ($target_page - $start_page);
28750 }
28751 if($o[0]>=$target_page && $o[0]<$start_page) {
28752 $this->links[$key][0] += $n_toc;
28753 }
28754 }
28755 }
28756
28757 // Update Form fields
28758 if (count($this->form->forms)) {
28759 foreach($this->form->forms as $key=>$f) {
28760 if($f['page']>=$start_page && $f['page']<=$end_page) {
28761 $this->form->forms[$key]['page'] += ($target_page - $start_page);
28762 }
28763 if($f['page']>=$target_page && $f['page']<$start_page) {
28764 $this->form->forms[$key]['page'] += $n_toc;
28765 }
28766 }
28767 }
28768
28769 /*-- ANNOTATIONS --*/
28770 // Update Annotations
28771 if (count($this->PageAnnots)) {
28772 $newarr = array();
28773 foreach($this->PageAnnots as $p=>$anno) {
28774 if($p>=$start_page && $p<=$end_page) {
28775 $np = $p + ($target_page - $start_page);
28776 foreach($anno as $o) {
28777 $newarr[$np][] = $o;
28778 }
28779 }
28780 else if($p>=$target_page && $p<$start_page) {
28781 $np = $p + $n_toc;
28782 foreach($anno as $o) {
28783 $newarr[$np][] = $o;
28784 }
28785 }
28786 else {
28787 $newarr[$p] = $this->PageAnnots[$p];
28788 }
28789 }
28790 $this->PageAnnots = $newarr;
28791 unset($newarr);
28792 }
28793 /*-- END ANNOTATIONS --*/
28794
28795 // Update PageNumSubstitutions
28796 if (count($this->PageNumSubstitutions)) {
28797 $newarr = array();
28798 foreach($this->PageNumSubstitutions AS $k=>$v) {
28799 if($this->PageNumSubstitutions[$k]['from']>=$start_page && $this->PageNumSubstitutions[$k]['from']<=$end_page) {
28800 $this->PageNumSubstitutions[$k]['from'] += ($target_page - $start_page);
28801 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
28802 }
28803 else if($this->PageNumSubstitutions[$k]['from']>=$target_page && $this->PageNumSubstitutions[$k]['from']<$start_page) {
28804 $this->PageNumSubstitutions[$k]['from'] += $n_toc;
28805 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
28806 }
28807 else {
28808 $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k];
28809 }
28810 }
28811
28812 if (!$sp_present) {
28813 $newarr[$target_page] = array('from'=>$target_page, 'suppress'=>$sp_suppress, 'reset'=>$sp_reset, 'type'=>$sp_type);
28814 }
28815 if (!$tp_present) {
28816 $newarr[($target_page + $n_toc)] = array('from'=>($target_page+$n_toc), 'suppress'=>$tp_suppress, 'reset'=>$tp_reset, 'type'=>$tp_type);
28817 }
28818 if (!$ep_present && $end_page>count($this->pages)) {
28819 $newarr[($end_page+1)] = array('from'=>($end_page+1), 'suppress'=>$ep_suppress, 'reset'=>$ep_reset, 'type'=>$ep_type);
28820 }
28821 ksort($newarr);
28822 $this->PageNumSubstitutions = array();
28823 foreach($newarr as $v) {
28824 $this->PageNumSubstitutions[] = $v;
28825 }
28826 }
28827 }
28828
28829 //======================================================
28830 function DeletePages($start_page, $end_page=-1) {
28831 // move a page/pages EARLIER in the document
28832 if ($end_page<1) { $end_page = $start_page; }
28833 $n_tod = $end_page - $start_page + 1;
28834 $last_page = count($this->pages);
28835 $n_atend = $last_page - $end_page + 1;
28836
28837 //move pages
28838 for($i=0;$i<$n_atend;$i++) {
28839 $this->pages[$start_page+$i]=$this->pages[$end_page+1+$i];
28840 }
28841 //delete pages
28842 for($i = 0;$i < $n_tod ;$i++)
28843 unset($this->pages[$last_page-$i]);
28844
28845
28846 /*-- BOOKMARKS --*/
28847 // Update Bookmarks
28848 foreach($this->BMoutlines as $i=>$o) {
28849 if($o['p']>=$end_page) { $this->BMoutlines[$i]['p'] -= $n_tod; }
28850 else if($p<$start_page) { unset($this->BMoutlines[$i]); }
28851 }
28852 /*-- END BOOKMARKS --*/
28853
28854 // Update Page Links
28855 if (count($this->PageLinks)) {
28856 $newarr = array();
28857 foreach($this->PageLinks as $i=>$o) {
28858 foreach($this->PageLinks[$i] as $key => $pl) {
28859 if (strpos($pl[4],'@')===0) {
28860 $p=substr($pl[4],1);
28861 if($p>$end_page) { $this->PageLinks[$i][$key][4] = '@'.($p - $n_tod); }
28862 else if($p<$start_page) { unset($this->PageLinks[$i][$key]); }
28863 }
28864 }
28865 if($i>$end_page) { $newarr[($i - $n_tod)] = $this->PageLinks[$i]; }
28866 else if($p<$start_page) { $newarr[$i] = $this->PageLinks[$i]; }
28867 }
28868 $this->PageLinks = $newarr;
28869 }
28870
28871 // OrientationChanges
28872 if (count($this->OrientationChanges)) {
28873 $newarr = array();
28874 foreach($this->OrientationChanges AS $p=>$v) {
28875 if($p>$end_page) { $newarr[($p - $t_tod)] = $this->OrientationChanges[$p]; }
28876 else if($p<$start_page) { $newarr[$p] = $this->OrientationChanges[$p]; }
28877 }
28878 ksort($newarr);
28879 $this->OrientationChanges = $newarr;
28880 }
28881
28882 // Page Dimensions
28883 if (count($this->pageDim)) {
28884 $newarr = array();
28885 foreach($this->pageDim AS $p=>$v) {
28886 if($p>$end_page) { $newarr[($p - $n_tod)] = $this->pageDim[$p]; }
28887 else if($p<$start_page) { $newarr[$p] = $this->pageDim[$p]; }
28888 }
28889 ksort($newarr);
28890 $this->pageDim = $newarr;
28891 }
28892
28893 // HTML Headers & Footers
28894 if (count($this->saveHTMLHeader)) {
28895 foreach($this->saveHTMLHeader AS $p=>$v) {
28896 if($p>$end_page) { $newarr[($p - $n_tod)] = $this->saveHTMLHeader[$p]; } // mPDF 5.7.3
28897 else if($p<$start_page) { $newarr[$p] = $this->saveHTMLHeader[$p]; }
28898 }
28899 ksort($newarr);
28900 $this->saveHTMLHeader = $newarr;
28901 }
28902 if (count($this->saveHTMLFooter)) {
28903 $newarr = array();
28904 foreach($this->saveHTMLFooter AS $p=>$v) {
28905 if($p>$end_page) { $newarr[($p - $n_tod)] = $this->saveHTMLFooter[$p]; }
28906 else if($p<$start_page) { $newarr[$p] = $this->saveHTMLFooter[$p]; }
28907 }
28908 ksort($newarr);
28909 $this->saveHTMLFooter = $newarr;
28910 }
28911
28912 // Update Internal Links
28913 foreach($this->internallink as $key=>$o) {
28914 if($o['PAGE']>$end_page) { $this->internallink[$key]['PAGE'] -= $n_tod; }
28915 else if($o['PAGE']<$start_page) { unset($this->internallink[$key]); }
28916 }
28917
28918 // Update Links
28919 foreach($this->links as $key=>$o) {
28920 if($o[0]>$end_page) { $this->links[$key][0] -= $n_tod; }
28921 else if($o[0]<$start_page) { unset($this->links[$key]); }
28922 }
28923
28924 // Update Form fields
28925 foreach($this->form->forms as $key=>$f) {
28926 if($f['page']>$end_page) { $this->form->forms[$key]['page'] -= $n_tod; }
28927 else if($f['page']<$start_page) { unset($this->form->forms[$key]); }
28928 }
28929
28930 /*-- ANNOTATIONS --*/
28931 // Update Annotations
28932 if (count($this->PageAnnots)) {
28933 $newarr = array();
28934 foreach($this->PageAnnots as $p=>$anno) {
28935 if($p>$end_page) { foreach($anno as $o) { $newarr[($p - $n_tod)][] = $o; } }
28936 else if($p<$start_page) { $newarr[$p] = $this->PageAnnots[$p]; }
28937 }
28938 ksort($newarr);
28939 $this->PageAnnots = $newarr;
28940 }
28941 /*-- END ANNOTATIONS --*/
28942
28943 // Update PageNumSubstitutions
28944 foreach($this->PageNumSubstitutions AS $k=>$v) {
28945 if($this->PageNumSubstitutions[$k]['from']>$end_page) { $this->PageNumSubstitutions[$k]['from'] -= $n_tod; }
28946 else if($this->PageNumSubstitutions[$k]['from']<$start_page) { unset($this->PageNumSubstitutions[$k]); }
28947 }
28948
28949 unset($newarr);
28950 $this->page = count($this->pages);
28951 }
28952
28953
28954 //======================================================
28955 /*-- INDEX --*/
28956 // FROM class PDF_Ref == INDEX
28957
28958 function Reference($txt) {
28959 $this->IndexEntry($txt);
28960 }
28961
28962
28963 function IndexEntry($txt, $xref='') {
28964 if ($xref) {
28965 $this->IndexEntrySee($txt,$xref);
28966 return;
28967 }
28968 $txt = strip_tags($txt);
28969 $txt = $this->purify_utf8_text($txt);
28970 if ($this->text_input_as_HTML) {
28971 $txt = $this->all_entities_to_utf8($txt);
28972 }
28973 if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
28974
28975 $Present=0;
28976 $size=sizeof($this->Reference);
28977
28978 if ($this->directionality == 'rtl') { // *RTL*
28979 $txt = str_replace(':',' - ',$txt); // *RTL*
28980 } // *RTL*
28981 else { // *RTL*
28982 $txt = str_replace(':',', ',$txt);
28983 } // *RTL*
28984
28985
28986 //Search the reference (AND Ref/PageNo) in the array
28987 for ($i=0;$i<$size;$i++){
28988 if ($this->keep_block_together) {
28989 if (isset($this->ktReference[$i]['t']) && $this->ktReference[$i]['t']==$txt){
28990 $Present=1;
28991 if ($this->page != $this->ktReference[$i]['op']) { // mPDF 5.7.2
28992 $this->ktReference[$i]['op'] = $this->page;
28993 }
28994 }
28995 }
28996 /*-- TABLES --*/
28997 else if ($this->table_rotate) {
28998 if (isset($this->tbrot_Reference[$i]['t']) && $this->tbrot_Reference[$i]['t']==$txt){
28999 $Present=1;
29000 if ($this->page != $this->tbrot_Reference[$i]['op']) { // mPDF 5.7.2
29001 $this->tbrot_Reference[$i]['op'] = $this->page;
29002 }
29003 }
29004 }
29005 else if ($this->kwt) {
29006 if (isset($this->kwt_Reference[$i]['t']) && $this->kwt_Reference[$i]['t']==$txt){
29007 $Present=1;
29008 if ($this->page != $this->kwt_Reference[$i]['op']) { // mPDF 5.7.2
29009 $this->kwt_Reference[$i]['op'] = $this->page;
29010 }
29011 }
29012 }
29013 /*-- END TABLES --*/
29014 /*-- COLUMNS --*/
29015 else if ($this->ColActive) {
29016 if (isset($this->col_Reference[$i]['t']) && $this->col_Reference[$i]['t']==$txt){
29017 $Present=1;
29018 if ($this->page != $this->col_Reference[$i]['op']) { // mPDF 5.7.2
29019 $this->col_Reference[$i]['op'] = $this->page;
29020 }
29021 }
29022 }
29023 /*-- END COLUMNS --*/
29024 else {
29025 if (isset($this->Reference[$i]['t']) && $this->Reference[$i]['t']==$txt){
29026 $Present=1;
29027 if (!in_array($this->page,$this->Reference[$i]['p'])) {
29028 $this->Reference[$i]['p'][] = $this->page;
29029 }
29030 }
29031 }
29032 }
29033 //If not found, add it
29034 if ($Present==0) {
29035 $opr = array('t'=>$txt, 'op'=>$this->page);
29036 if ($this->keep_block_together) {
29037 $this->ktReference[]= $opr;
29038 }
29039 /*-- TABLES --*/
29040 else if ($this->table_rotate) {
29041 $this->tbrot_Reference[]= $opr;
29042 }
29043 else if ($this->kwt) {
29044 $this->kwt_Reference[]= $opr;
29045 }
29046 /*-- END TABLES --*/
29047 /*-- COLUMNS --*/
29048 else if ($this->ColActive) {
29049 $this->col_Reference[]= $opr;
29050 }
29051 /*-- END COLUMNS --*/
29052 else {
29053 $this->Reference[]=array('t'=>$txt,'p'=>array($this->page));
29054 }
29055 }
29056 }
29057
29058 // Added function to add a reference "Elephants. See Chickens"
29059 function ReferenceSee($txta,$txtb) {
29060 $this->IndexEntrySee($txta,$txtb);
29061 }
29062
29063 function IndexEntrySee($txta,$txtb) {
29064 $txta = strip_tags($txta);
29065 $txtb = strip_tags($txtb);
29066 $txta = $this->purify_utf8_text($txta);
29067 $txtb = $this->purify_utf8_text($txtb);
29068 if ($this->text_input_as_HTML) {
29069 $txta = $this->all_entities_to_utf8($txta);
29070 $txtb = $this->all_entities_to_utf8($txtb);
29071 }
29072 if ($this->usingCoreFont) {
29073 $txta = mb_convert_encoding($txta,$this->mb_enc,'UTF-8');
29074 $txtb = mb_convert_encoding($txtb,$this->mb_enc,'UTF-8');
29075 }
29076 if ($this->directionality == 'rtl') { // *RTL*
29077 $txta = str_replace(':',' - ',$txta); // *RTL*
29078 $txtb = str_replace(':',' - ',$txtb); // *RTL*
29079 } // *RTL*
29080 else { // *RTL*
29081 $txta = str_replace(':',', ',$txta);
29082 $txtb = str_replace(':',', ',$txtb);
29083 } // *RTL*
29084 $this->Reference[]=array('t'=>$txta.' - see '.$txtb,'p'=>array());
29085 }
29086
29087 function CreateReference($NbCol=1, $reffontsize='', $linespacing='', $offset=3, $usedivletters=1, $divlettfontsize='', $gap=5, $reffont='',$divlettfont='', $useLinking=false) {
29088 $this->CreateIndex($NbCol, $reffontsize, $linespacing, $offset, $usedivletters, $divlettfontsize, $gap, $reffont, $divlettfont, $useLinking);
29089 }
29090
29091 function CreateIndex($NbCol=1, $reffontsize='', $linespacing='', $offset=3, $usedivletters=1, $divlettfontsize='', $gap=5, $reffont='',$divlettfont='', $useLinking=false) {
29092 if (!$reffontsize) { $reffontsize = $this->default_font_size; }
29093 if (!$divlettfontsize) { $divlettfontsize = ($this->default_font_size * 1.8); }
29094 if (!$reffont) { $reffont = $this->default_font; }
29095 if (!$divlettfont) { $divlettfont = $reffont; }
29096 if (!$linespacing) { $linespacing= $this->default_lineheight_correction; }
29097 if ($this->ColActive) { $this->SetColumns(0); } // *COLUMNS*
29098 $size=sizeof($this->Reference);
29099 if ($size == 0) { return false; }
29100
29101
29102 if ($NbCol<2) {
29103 $NbCol = 1;
29104 $colWidth = $this->pgwidth;
29105 }
29106 else {
29107 $this->SetColumns($NbCol,'',$gap);
29108 $colWidth = $this->ColWidth;
29109 }
29110 if ($this->directionality == 'rtl') { $align = 'R'; }
29111 else { $align = 'L'; }
29112 $lett = '';
29113 if (!function_exists('cmp')) {
29114 function cmp ($a, $b) {
29115 return strnatcmp(strtolower($a['t']), strtolower($b['t']));
29116 }
29117 }
29118 //Alphabetic sort of the references
29119 usort($this->Reference, 'cmp');
29120 $size=sizeof($this->Reference);
29121 $this->breakpoints[$this->CurrCol][] = $this->y; // *COLUMNS*
29122
29123 $divlettjuststarted = false;
29124
29125 $this->OpenTag('DIV',array('STYLE'=>'line-height: '.$linespacing.'; font-family: '.$reffont.'; font-size: '.$reffontsize.'pt; '));
29126
29127 $last_lett = '';
29128 for ($i=0;$i<$size;$i++){
29129 if ($this->Reference[$i]['t']) {
29130 if ($usedivletters) {
29131
29132 $lett = mb_strtoupper(mb_substr($this->Reference[$i]['t'],0,1,$this->mb_enc ),$this->mb_enc );
29133 if ($lett != $last_lett) {
29134
29135 $save_bp = $this->breakpoints[$this->CurrCol]; // *COLUMNS*
29136 $divlettjuststarted = true;
29137
29138 if ($i>0) {
29139 $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; '));
29140 }
29141 else {
29142 $this->OpenTag('DIV',array('STYLE'=>'line-height: '.$linespacing.'; font-family: '.$divlettfont.'; font-size: '.$divlettfontsize.'pt; font-weight: bold; page-break-after: avoid; '));
29143 }
29144 $this->_saveTextBuffer($lett);
29145 $this->CloseTag('DIV');
29146 }
29147 }
29148
29149 $this->OpenTag('DIV',array('STYLE'=>'text-indent: -'.$offset.'mm; line-height: '.$linespacing.'; font-family: '.$reffont.'; font-size: '.$reffontsize.'pt; '));
29150
29151 /*-- RTL --*/
29152 // Change Arabic + Persian. to Presentation Forms
29153 if ($this->biDirectional) {
29154 $this->Reference[$i]['t'] = preg_replace_callback("/([".$this->pregRTLchars."]+)/u", array($this, 'arabJoinPregCallback'), $this->Reference[$i]['t'] ); // mPDF 5.7+
29155 }
29156 /*-- END RTL --*/
29157
29158 // Font-specific ligature substitution for Indic fonts
29159 if (isset($this->CurrentFont['indic']) && $this->CurrentFont['indic']) $this->ConvertIndic($this->Reference[$i]['t']); // *INDIC*
29160
29161 $this->_saveTextBuffer($this->Reference[$i]['t']);
29162 $ppp = $this->Reference[$i]['p']; // = array of page numbers to point to
29163 if (count($ppp)) {
29164 sort($ppp);
29165 $newarr = array();
29166 $range_start = $ppp[0];
29167 $range_end = 0;
29168
29169 if (!$this->usingCoreFont) { $spacer = "\xc2\xa0 "; }
29170 else { $spacer = chr(160).' '; }
29171 $this->_saveTextBuffer($spacer);
29172 if ($this->directionality == 'rtl') { $sep = '.'; $joiner = '-'; }
29173 else { $sep = ', '; $joiner = '-'; }
29174 for ($zi=1;$zi<count($ppp);$zi++) {
29175 // RTL - Each number separately
29176 if ($this->directionality == 'rtl') {
29177 /*-- RTL --*/
29178 if ($zi<count($ppp)-1) {
29179 $txt = $sep . $this->docPageNum($ppp[$zi]);
29180 if ($useLinking) { $href = '@'.$ppp[$zi]; }
29181 else { $href = ''; }
29182 $this->_saveTextBuffer($txt, $href);
29183 }
29184 /*-- END RTL --*/
29185 }
29186
29187 else if ($ppp[$zi] == ($ppp[($zi-1)]+1)) {
29188 $range_end = $ppp[$zi];
29189 }
29190 else {
29191 if ($range_end) {
29192 if ($range_end == $range_start+1) {
29193 if ($useLinking) { $href = '@'.$range_start; }
29194 else { $href = ''; }
29195 $txt = $this->docPageNum($range_start) . $sep;
29196 $this->_saveTextBuffer($txt, $href);
29197 if ($useLinking) { $href = '@'.$ppp[$zi-1]; }
29198 else { $href = ''; }
29199 $txt = $this->docPageNum($ppp[$zi-1]) . $sep;
29200 $this->_saveTextBuffer($txt, $href);
29201 }
29202 else {
29203 if ($useLinking) { $href = '@'.$range_start; }
29204 else { $href = ''; }
29205 }
29206 }
29207 else {
29208 if ($useLinking) { $href = '@'.$ppp[$zi-1]; }
29209 else { $href = ''; }
29210 $txt = $this->docPageNum($ppp[$zi-1]) . $sep;
29211 $this->_saveTextBuffer($txt, $href);
29212 }
29213 $range_start = $ppp[$zi];
29214 $range_end = 0;
29215 }
29216 }
29217
29218 if ($range_end) {
29219 if ($range_end == $range_start+1) {
29220 if ($useLinking) { $href = '@'.$range_start; }
29221 else { $href = ''; }
29222 $txt = $this->docPageNum($range_start) . $sep;
29223 $this->_saveTextBuffer($txt, $href);
29224 if ($useLinking) { $href = '@'.$range_end; }
29225 else { $href = ''; }
29226 $txt = $this->docPageNum($range_end);
29227 $this->_saveTextBuffer($txt, $href);
29228 }
29229 else {
29230 if ($useLinking) { $href = '@'.$range_start; }
29231 else { $href = ''; }
29232 $txt = $this->docPageNum($range_start) . $joiner;
29233 $this->_saveTextBuffer($txt, $href);
29234 if ($useLinking) { $href = '@'.$range_end; }
29235 else { $href = ''; }
29236 $txt = $this->docPageNum($range_end);
29237 $this->_saveTextBuffer($txt, $href);
29238 }
29239 }
29240 else {
29241 if ($useLinking) { $href = '@'.$ppp[(count($ppp)-1)]; }
29242 else { $href = ''; }
29243 $txt = $this->docPageNum($ppp[(count($ppp)-1)]);
29244 $this->_saveTextBuffer($txt, $href);
29245 }
29246 }
29247 }
29248 $this->CloseTag('DIV');
29249
29250 if ($divlettjuststarted) { $this->breakpoints[$this->CurrCol] = $save_bp; } // *COLUMNS*
29251 $divlettjuststarted = false;
29252
29253 $this->breakpoints[$this->CurrCol][] = $this->y; // *COLUMNS*
29254 $last_lett = $lett;
29255 }
29256 $this->CloseTag('DIV');
29257 $this->breakpoints[$this->CurrCol][] = $this->y; // *COLUMNS*
29258 if ($this->ColActive) { $this->SetColumns(0); } // *COLUMNS*
29259 }
29260 /*-- END INDEX --*/
29261
29262
29263 function AcceptPageBreak() {
29264 if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); } // *TABLES*
29265 /*-- COLUMNS --*/
29266 if ($this->ColActive==1) {
29267 if($this->CurrCol<$this->NbCol-1) {
29268 //Go to the next column
29269 $this->CurrCol++;
29270 $this->SetCol($this->CurrCol);
29271 $this->y=$this->y0;
29272 $this->ChangeColumn=1; // Number (and direction) of columns changed +1, +2, -2 etc.
29273 // DIRECTIONALITY RTL
29274 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
29275
29276 //Stay on the page
29277 return false;
29278 }
29279 else {
29280 //Go back to the first column - NEW PAGE
29281 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
29282 $this->SetCol(0);
29283 $this->y0 = $this->tMargin;
29284 $this->ChangeColumn= -($this->NbCol-1);
29285 // DIRECTIONALITY RTL
29286 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
29287 //Page break
29288 return true;
29289 }
29290 }
29291 /*-- END COLUMNS --*/
29292 /*-- TABLES --*/
29293 else if ($this->table_rotate) {
29294 if ($this->tablebuffer) { $this->printtablebuffer(); }
29295 return true;
29296 }
29297 /*-- END TABLES --*/
29298 else { // *COLUMNS*
29299 $this->ChangeColumn=0;
29300 return $this->autoPageBreak;
29301 } // *COLUMNS*
29302 return $this->autoPageBreak;
29303 }
29304
29305
29306 //----------- COLUMNS ---------------------
29307 /*-- COLUMNS --*/
29308
29309 function SetColumns($NbCol,$vAlign='',$gap=5) {
29310 // NbCol = number of columns
29311 // CurrCol = Number of the current column starting at 0
29312 // Called externally to set columns on/off and number
29313 // Integer 2 upwards sets columns on to that number
29314 // Anything less than 2 turns columns off
29315 if ($NbCol<2) { // SET COLUMNS OFF
29316 if ($this->ColActive) {
29317 $this->ColActive=0;
29318 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
29319 $this->NbCol=1;
29320 $this->ResetMargins();
29321 $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
29322 $this->divwidth = 0;
29323 $this->Ln();
29324 }
29325 $this->ColActive=0;
29326 $this->columnbuffer = array();
29327 $this->ColDetails = array();
29328 $this->columnLinks = array();
29329 $this->columnAnnots = array();
29330 $this->columnForms = array();
29331 $this->col_Reference = array();
29332 $this->col_BMoutlines = array();
29333 $this->col_toc = array();
29334 $this->breakpoints = array();
29335 }
29336 else { // SET COLUMNS ON
29337 if ($this->ColActive) {
29338 $this->ColActive=0;
29339 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
29340 $this->ResetMargins();
29341 }
29342 if (isset($this->y) && $this->y>$this->tMargin) $this->Ln();
29343 $this->NbCol=$NbCol;
29344 $this->ColGap = $gap;
29345 $this->divwidth = 0;
29346 $this->ColActive=1;
29347 $this->ColumnAdjust = true; // enables column height adjustment for the page
29348 $this->columnbuffer = array();
29349 $this->ColDetails = array();
29350 $this->columnLinks = array();
29351 $this->columnAnnots = array();
29352 $this->columnForms = array();
29353 $this->col_Reference = array();
29354 $this->col_BMoutlines = array();
29355 $this->col_toc = array();
29356 $this->breakpoints = array();
29357 if ((strtoupper($vAlign) == 'J') || (strtoupper($vAlign) == 'JUSTIFY')) { $vAlign = 'J'; }
29358 else { $vAlign = ''; }
29359 $this->colvAlign = $vAlign;
29360 //Save the ordinate
29361 $absL = $this->DeflMargin-($gap/2);
29362 $absR = $this->DefrMargin-($gap/2);
29363 $PageWidth = $this->w-$absL-$absR; // virtual pagewidth for calculation only
29364 $ColWidth = (($PageWidth - ($gap * ($NbCol)))/$NbCol);
29365 $this->ColWidth = $ColWidth;
29366 /*-- RTL --*/
29367
29368 if ($this->directionality == 'rtl') {
29369 for ($i=0;$i<$this->NbCol;$i++) {
29370 $this->ColL[$i] = $absL + ($gap/2) + (($NbCol - ($i+1))*($PageWidth/$NbCol)) ;
29371 $this->ColR[$i] = $this->ColL[$i] + $ColWidth; // NB This is not R margin -> R pos
29372 }
29373 }
29374 else {
29375 /*-- END RTL --*/
29376 for ($i=0;$i<$this->NbCol;$i++) {
29377 $this->ColL[$i] = $absL + ($gap/2) + ($i* ($PageWidth/$NbCol) );
29378 $this->ColR[$i] = $this->ColL[$i] + $ColWidth; // NB This is not R margin -> R pos
29379 }
29380 } // *RTL*
29381 $this->pgwidth = $ColWidth;
29382 $this->SetCol(0);
29383 $this->y0=$this->y;
29384 }
29385 $this->x = $this->lMargin;
29386 }
29387
29388 function SetCol($CurrCol) {
29389 // Used internally to set column by number: 0 is 1st column
29390 //Set position on a column
29391 $this->CurrCol=$CurrCol;
29392 $x = $this->ColL[$CurrCol];
29393 $xR = $this->ColR[$CurrCol]; // NB This is not R margin -> R pos
29394 if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
29395 $x += $this->MarginCorrection ;
29396 $xR += $this->MarginCorrection ;
29397 }
29398 $this->SetMargins($x,($this->w - $xR),$this->tMargin);
29399 }
29400
29401 function AddColumn() {
29402 $this->NewColumn();
29403 $this->ColumnAdjust = false; // disables all column height adjustment for the page.
29404 }
29405 function NewColumn() {
29406 if ($this->ColActive==1) {
29407 if($this->CurrCol<$this->NbCol-1) {
29408 //Go to the next column
29409 $this->CurrCol++;
29410 $this->SetCol($this->CurrCol);
29411 $this->y = $this->y0;
29412 $this->ChangeColumn=1;
29413 // DIRECTIONALITY RTL
29414 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
29415 //Stay on the page
29416 }
29417 else {
29418 //Go back to the first column
29419 //Page break
29420 if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
29421 $this->AddPage($this->CurOrientation);
29422 $this->SetCol(0);
29423 $this->y0 = $this->tMargin;
29424 $this->ChangeColumn= -($this->NbCol-1);
29425 // DIRECTIONALITY RTL
29426 if ($this->directionality == 'rtl') { $this->ChangeColumn = -($this->ChangeColumn); } // *RTL*
29427 }
29428 $this->x = $this->lMargin;
29429 }
29430 else {
29431 $this->AddPage($this->CurOrientation);
29432 }
29433 }
29434
29435 function printcolumnbuffer() {
29436 // Columns ended (but page not ended) -> try to match all columns - unless disabled by using a custom column-break
29437 if (!$this->ColActive && $this->ColumnAdjust && !$this->keepColumns) { // mPDF 5.7.2
29438 // Calculate adjustment to add to each column to calculate rel_y value
29439 $this->ColDetails[0]['add_y'] = 0;
29440 $last_col = 0;
29441 // Recursively add previous column's height
29442 for($i=1;$i<$this->NbCol;$i++) {
29443 if (isset($this->ColDetails[$i]['bottom_margin']) && $this->ColDetails[$i]['bottom_margin']) { // If any entries in the column
29444 $this->ColDetails[$i]['add_y'] = ($this->ColDetails[$i-1]['bottom_margin'] - $this->y0) + $this->ColDetails[$i-1]['add_y'];
29445 $last_col = $i; // Last column actually printed
29446 }
29447 }
29448
29449 // Calculate value for each position sensitive entry as though for one column
29450 foreach($this->columnbuffer AS $key=>$s) {
29451 $t = $s['s'];
29452 if ($t == 'ACROFORM') {
29453 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29454 $this->columnbuffer[$key]['s'] = '';
29455 }
29456 else if (preg_match('/BT \d+\.\d\d+ (\d+\.\d\d+) Td/',$t)) {
29457 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29458 }
29459 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/',$t)) {
29460 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29461 }
29462 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) {
29463 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29464 }
29465 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) {
29466 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29467 }
29468 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)) {
29469 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29470 }
29471 else if (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) {
29472 $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0;
29473 }
29474 }
29475 foreach($this->internallink AS $key => $f) {
29476 if (is_array($f) && isset($f['col'])) {
29477 $this->internallink[$key]['rel_y'] = $f['Y'] + $this->ColDetails[$f['col']]['add_y'] - $this->y0;
29478 }
29479 }
29480
29481 $breaks = array();
29482 foreach($this->breakpoints AS $c => $bpa) {
29483 foreach($bpa AS $rely) {
29484 $breaks[] = $rely + $this->ColDetails[$c]['add_y'] - $this->y0;
29485 }
29486 }
29487
29488 if (isset($this->ColDetails[$last_col]['bottom_margin'])) { $lcbm = $this->ColDetails[$last_col]['bottom_margin']; }
29489 else { $lcbm = 0; }
29490 $sum_h = $this->ColDetails[$last_col]['add_y'] + $lcbm - $this->y0;
29491 //$sum_h = max($this->ColDetails[$last_col]['add_y'] + $this->ColDetails[$last_col]['bottom_margin'] - $this->y0, end($breaks));
29492 $target_h = ($sum_h / $this->NbCol);
29493
29494 $cbr = array();
29495 for($i=1;$i<$this->NbCol;$i++) {
29496 $th = ($sum_h * $i / $this->NbCol);
29497 foreach($breaks AS $bk=>$val) {
29498 if ($val > $th) {
29499 if (($val-$th) < ($th-$breaks[$bk-1])) { $cbr[$i-1] = $val; }
29500 else { $cbr[$i-1] = $breaks[$bk-1]; }
29501 break;
29502 }
29503 }
29504 }
29505 $cbr[($this->NbCol-1)] = $sum_h;
29506
29507 // Now update the columns - divide into columns of approximately equal value
29508 $last_new_col = 0;
29509 $yadj = 0; // mm
29510 $xadj = 0;
29511 $last_col_bottom = 0;
29512 $lowest_bottom_y = 0;
29513 $block_bottom = 0;
29514 $newcolumn = 0;
29515 foreach($this->columnbuffer AS $key=>$s) {
29516 if (isset($s['rel_y'])) { // only process position sensitive data
29517 if ($s['rel_y'] >= $cbr[$newcolumn]) {
29518 $newcolumn++;
29519 }
29520 else {
29521 $newcolumn = $last_new_col ;
29522 }
29523
29524
29525 $block_bottom = max($block_bottom,($s['rel_y']+$s['h']));
29526
29527 if ($this->directionality == 'rtl') { // *RTL*
29528 $xadj = -(($newcolumn - $s['col']) * ($this->ColWidth + $this->ColGap)); // *RTL*
29529 } // *RTL*
29530 else { // *RTL*
29531 $xadj = ($newcolumn - $s['col']) * ($this->ColWidth + $this->ColGap);
29532 } // *RTL*
29533
29534 if ($last_new_col != $newcolumn) { // Added new column
29535 $last_col_bottom = $this->columnbuffer[$key]['rel_y'];
29536 $block_bottom = 0;
29537 }
29538 $yadj = ($s['rel_y'] - $s['y']) - ($last_col_bottom)+$this->y0;
29539 // callback function
29540 $t = $s['s'];
29541
29542 // mPDF 5.7+
29543 $t = $this->columnAdjustPregReplace('Td', $xadj, $yadj, '/BT (\d+\.\d\d+) (\d+\.\d\d+) Td/', $t);
29544 $t = $this->columnAdjustPregReplace('re', $xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) ([\-]{0,1}\d+\.\d\d+) re/', $t);
29545 $t = $this->columnAdjustPregReplace('l', $xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) l/', $t);
29546 $t = $this->columnAdjustPregReplace('img', $xadj, $yadj, '/q (\d+\.\d\d+) 0 0 (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) cm \/(I|FO)/', $t);
29547 $t = $this->columnAdjustPregReplace('draw', $xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) m/', $t);
29548 $t = $this->columnAdjustPregReplace('bezier',$xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) c/', $t);
29549
29550 $this->columnbuffer[$key]['s'] = $t;
29551 $this->columnbuffer[$key]['newcol'] = $newcolumn;
29552 $this->columnbuffer[$key]['newy'] = $s['y'] + $yadj;
29553 $last_new_col = $newcolumn;
29554 $clb = $s['y'] + $yadj + $s['h'] ; // bottom_margin of current
29555 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; }
29556 if ($clb > $lowest_bottom_y) { $lowest_bottom_y = $clb; }
29557 // Adjust LINKS
29558 if (isset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29559 $ref = $this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29560 $this->PageLinks[$this->page][$ref][0] += ($xadj*_MPDFK);
29561 $this->PageLinks[$this->page][$ref][1] -= ($yadj*_MPDFK);
29562 unset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29563 }
29564 // Adjust FORM FIELDS
29565 if (isset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29566 $ref = $this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29567 $this->form->forms[$ref]['x'] += ($xadj);
29568 $this->form->forms[$ref]['y'] += ($yadj);
29569 unset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29570 }
29571 /*-- ANNOTATIONS --*/
29572 if (isset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29573 $ref = $this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29574 if ($this->PageAnnots[$this->page][$ref]['x'] < 0) {
29575 $this->PageAnnots[$this->page][$ref]['x'] -= ($xadj);
29576 }
29577 else {
29578 $this->PageAnnots[$this->page][$ref]['x'] += ($xadj);
29579 }
29580 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj); // unlike PageLinks, Page annots has y values from top in mm
29581 unset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29582 }
29583 /*-- END ANNOTATIONS --*/
29584 }
29585 }
29586
29587 /*-- BOOKMARKS --*/
29588 // Adjust Bookmarks
29589 foreach($this->col_BMoutlines AS $v) {
29590 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$this->y0,'p'=>$v['p']);
29591 }
29592 /*-- END BOOKMARKS --*/
29593
29594 /*-- INDEX --*/
29595 // Adjust Reference (index)
29596 foreach($this->col_Reference AS $v) {
29597 $Present=0;
29598 //Search the reference (AND Ref/PageNo) in the array
29599 for ($i=0;$i<count($this->Reference);$i++){
29600 if ($this->Reference[$i]['t']==$v['t']){
29601 $Present=1;
29602 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29603 $this->Reference[$i]['p'][] = $v['op'];
29604 }
29605 }
29606 }
29607 if ($Present==0) {
29608 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29609 }
29610 }
29611 /*-- END INDEX --*/
29612
29613 /*-- TOC --*/
29614
29615 // Adjust ToC
29616 foreach($this->col_toc AS $v) {
29617 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29618 $this->links[$v['link']][1] = $this->y0;
29619 }
29620 /*-- END TOC --*/
29621
29622 // Adjust column length to be equal
29623 if ($this->colvAlign == 'J') {
29624 foreach($this->columnbuffer AS $key=>$s) {
29625 if (isset($s['rel_y'])) { // only process position sensitive data
29626 // Set ratio to expand y values or heights
29627 if (isset($this->ColDetails[$s['newcol']]['max_bottom']) && $this->ColDetails[$s['newcol']]['max_bottom'] && $this->ColDetails[$s['newcol']]['max_bottom']!=$this->y0) {
29628 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['newcol']]['max_bottom'] - ($this->y0));
29629 }
29630 else { $ratio = 1; }
29631 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29632 $yadj = ($s['newy'] - $this->y0) * ($ratio - 1);
29633
29634 // Adjust LINKS
29635 if (isset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29636 $ref = $this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29637 $this->PageLinks[$this->page][$ref][1] -= ($yadj*_MPDFK); // y value
29638 $this->PageLinks[$this->page][$ref][3] *= $ratio; // height
29639 unset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29640 }
29641 // Adjust FORM FIELDS
29642 if (isset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29643 $ref = $this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29644 $this->form->forms[$ref]['x'] += ($xadj);
29645 $this->form->forms[$ref]['y'] += ($yadj);
29646 unset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29647 }
29648 /*-- ANNOTATIONS --*/
29649 if (isset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29650 $ref = $this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29651 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj);
29652 unset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29653 }
29654 /*-- END ANNOTATIONS --*/
29655 }
29656 }
29657 }
29658 foreach($this->internallink AS $key => $f) {
29659 if (is_array($f) && isset($f['col'])) {
29660 $last_col_bottom = 0;
29661 for ($nbc=0; $nbc<$this->NbCol; $nbc++) {
29662 if ($f['rel_y'] >= $cbr[$nbc]) { $last_col_bottom = $cbr[$nbc]; }
29663 }
29664 $yadj = ($f['rel_y'] - $f['Y']) - $last_col_bottom + $this->y0;
29665 $f['Y'] += $yadj;
29666 unset($f['col']);
29667 unset($f['rel_y']);
29668 $this->internallink[$key] = $f;
29669 }
29670 }
29671
29672 $last_col = -1;
29673 $trans_on = false;
29674 foreach($this->columnbuffer AS $key=>$s) {
29675 if (isset($s['rel_y'])) { // only process position sensitive data
29676 // Set ratio to expand y values or heights
29677 if (isset($this->ColDetails[$s['newcol']]['max_bottom']) && $this->ColDetails[$s['newcol']]['max_bottom'] && $this->ColDetails[$s['newcol']]['max_bottom']!=$this->y0) {
29678 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['newcol']]['max_bottom'] - ($this->y0));
29679 }
29680 else { $ratio = 1; }
29681 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29682 //Start Transformation
29683 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
29684 $this->pages[$this->page] .= $this->transformScale(100, $ratio*100, $x='', $this->y0, true)."\n";
29685 $trans_on = true;
29686 }
29687 }
29688 // Now output the adjusted values
29689 $this->pages[$this->page] .= $s['s']."\n";
29690 if (isset($s['rel_y']) && ($ratio > 1) && ($ratio <= $this->max_colH_correction)) { // only process position sensitive data
29691 //Stop Transformation
29692 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
29693 $trans_on = false;
29694 }
29695 }
29696 if ($trans_on) { $this->pages[$this->page] .= $this->StopTransform(true)."\n"; }
29697 }
29698 else { // if NOT $this->colvAlign == 'J'
29699 // Now output the adjusted values
29700 foreach($this->columnbuffer AS $s) {
29701 $this->pages[$this->page] .= $s['s']."\n";
29702 }
29703 }
29704 if ($lowest_bottom_y > 0) { $this->y = $lowest_bottom_y ; }
29705 }
29706
29707 // Columns not ended but new page -> align columns (can leave the columns alone - just tidy up the height)
29708 else if ($this->colvAlign == 'J' && $this->ColumnAdjust && !$this->keepColumns) {
29709 // calculate the lowest bottom margin
29710 $lowest_bottom_y = 0;
29711 foreach($this->columnbuffer AS $key=>$s) {
29712 // Only process output data
29713 $t = $s['s'];
29714 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)) ||
29715 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) ||
29716 (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/',$t)) ||
29717 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) ||
29718 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) ) {
29719
29720 $clb = $s['y'] + $s['h'];
29721 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; }
29722 if ($clb > $lowest_bottom_y) { $lowest_bottom_y = $clb; }
29723 $this->columnbuffer[$key]['rel_y'] = $s['y']; // Marks position sensitive data to process later
29724 if ($t == 'ACROFORM') { $this->columnbuffer[$key]['s'] = ''; }
29725 }
29726 }
29727 // Adjust column length equal
29728 foreach($this->columnbuffer AS $key=>$s) {
29729 // Set ratio to expand y values or heights
29730 if (isset($this->ColDetails[$s['col']]['max_bottom']) && $this->ColDetails[$s['col']]['max_bottom']) {
29731 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['col']]['max_bottom'] - ($this->y0));
29732 }
29733 else { $ratio = 1; }
29734 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29735 $yadj = ($s['y'] - $this->y0) * ($ratio - 1);
29736
29737 // Adjust LINKS
29738 if (isset($s['rel_y'])) { // only process position sensitive data
29739 // otherwise triggers for all entries in column buffer (.e.g. formatting) and makes below adjustments more than once
29740 if (isset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29741 $ref = $this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29742 $this->PageLinks[$this->page][$ref][1] -= ($yadj*_MPDFK); // y value
29743 $this->PageLinks[$this->page][$ref][3] *= $ratio; // height
29744 unset($this->columnLinks[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29745 }
29746 // Adjust FORM FIELDS
29747 if (isset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29748 $ref = $this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29749 $this->form->forms[$ref]['x'] += ($xadj);
29750 $this->form->forms[$ref]['y'] += ($yadj);
29751 unset($this->columnForms[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29752 }
29753 /*-- ANNOTATIONS --*/
29754 if (isset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])])) {
29755 $ref = $this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])];
29756 $this->PageAnnots[$this->page][$ref]['y'] += ($yadj);
29757 unset($this->columnAnnots[$s['col']][INTVAL($s['x'])][INTVAL($s['y'])]);
29758 }
29759 /*-- END ANNOTATIONS --*/
29760 }
29761 }
29762 }
29763
29764 /*-- BOOKMARKS --*/
29765
29766 // Adjust Bookmarks
29767 foreach($this->col_BMoutlines AS $v) {
29768 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$this->y0,'p'=>$v['p']);
29769 }
29770 /*-- END BOOKMARKS --*/
29771
29772 /*-- INDEX --*/
29773
29774 // Adjust Reference (index)
29775 foreach($this->col_Reference AS $v) {
29776 $Present=0;
29777 //Search the reference (AND Ref/PageNo) in the array
29778 for ($i=0;$i<count($this->Reference);$i++){
29779 if ($this->Reference[$i]['t']==$v['t']){
29780 $Present=1;
29781 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29782 $this->Reference[$i]['p'][] = $v['op'];
29783 }
29784 }
29785 }
29786 if ($Present==0) {
29787 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29788 }
29789 }
29790 /*-- END INDEX --*/
29791
29792 /*-- TOC --*/
29793
29794 // Adjust ToC
29795 foreach($this->col_toc AS $v) {
29796 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29797 $this->links[$v['link']][1] = $this->y0;
29798 }
29799 /*-- END TOC --*/
29800 $trans_on = false;
29801 foreach($this->columnbuffer AS $key=>$s) {
29802 if (isset($s['rel_y'])) { // only process position sensitive data
29803 // Set ratio to expand y values or heights
29804 if ($this->ColDetails[$s['col']]['max_bottom']) {
29805 $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['col']]['max_bottom'] - ($this->y0));
29806 }
29807 else { $ratio = 1; }
29808 if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29809 //Start Transformation
29810 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
29811 $this->pages[$this->page] .= $this->transformScale(100, $ratio*100, $x='', $this->y0, true)."\n";
29812 $trans_on = true;
29813 }
29814 }
29815 // Now output the adjusted values
29816 $this->pages[$this->page] .= $s['s']."\n";
29817 if (isset($s['rel_y']) && ($ratio > 1) && ($ratio <= $this->max_colH_correction)) {
29818 //Stop Transformation
29819 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
29820 $trans_on = false; // mPDF 5.1.001
29821 }
29822 }
29823 if ($trans_on) { $this->pages[$this->page] .= $this->StopTransform(true)."\n"; }
29824
29825 if ($lowest_bottom_y > 0) { $this->y = $lowest_bottom_y ; }
29826 }
29827
29828
29829 // Just reproduce the page as it was
29830 else {
29831 // If page has not ended but height adjustment was disabled by custom column-break - adjust y
29832 $lowest_bottom_y = 0;
29833 if (!$this->ColActive && (!$this->ColumnAdjust || $this->keepColumns)) {
29834 // calculate the lowest bottom margin
29835 foreach($this->columnbuffer AS $key=>$s) {
29836 // Only process output data
29837 $t = $s['s'];
29838 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)) ||
29839 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/',$t)) ||
29840 (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/',$t)) ||
29841 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/',$t)) ||
29842 (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/',$t)) ) {
29843
29844 $clb = $s['y'] + $s['h'];
29845 if ($clb > $this->ColDetails[$s['col']]['max_bottom']) { $this->ColDetails[$s['col']]['max_bottom'] = $clb; }
29846 if ($clb > $lowest_bottom_y) { $lowest_bottom_y = $clb; }
29847 }
29848 }
29849 }
29850 foreach($this->columnbuffer AS $key=>$s) {
29851 if ($s['s'] != 'ACROFORM')
29852 $this->pages[$this->page] .= $s['s']."\n";
29853 }
29854 if ($lowest_bottom_y > 0) { $this->y = $lowest_bottom_y ; }
29855 /*-- INDEX --*/
29856
29857 // Output Reference (index)
29858 foreach($this->col_Reference AS $v) {
29859 $Present=0;
29860 for ($i=0;$i<count($this->Reference);$i++){
29861 if ($this->Reference[$i]['t']==$v['t']){
29862 $Present=1;
29863 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29864 $this->Reference[$i]['p'][] = $v['op'];
29865 }
29866 }
29867 }
29868 if ($Present==0) {
29869 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29870 }
29871 }
29872 /*-- END INDEX --*/
29873 /*-- BOOKMARKS --*/
29874 // Output Bookmarks
29875 foreach($this->col_BMoutlines AS $v) {
29876 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29877 }
29878 /*-- END BOOKMARKS --*/
29879 /*-- TOC --*/
29880 // Output ToC
29881 foreach($this->col_toc AS $v) {
29882 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29883 }
29884 /*-- END TOC --*/
29885 }
29886 foreach($this->internallink AS $key => $f) {
29887 if (isset($this->internallink[$key]['col'])) unset($this->internallink[$key]['col']);
29888 if (isset($this->internallink[$key]['rel_y'])) unset($this->internallink[$key]['rel_y']);
29889 }
29890
29891 $this->columnbuffer = array();
29892 $this->ColDetails = array();
29893 $this->columnLinks = array();
29894 $this->columnAnnots = array();
29895 $this->columnForms = array();
29896
29897 $this->col_Reference = array();
29898 $this->col_BMoutlines = array();
29899 $this->col_toc = array();
29900 $this->breakpoints = array();
29901 }
29902
29903 // mPDF 5.7+
29904 function columnAdjustPregReplace($type, $xadj, $yadj, $pattern, $subject) {
29905 preg_match($pattern, $subject, $matches);
29906 if (!isset($matches[3])) { $matches[3] = 0; }
29907 if (!isset($matches[4])) { $matches[4] = 0; }
29908 if (!isset($matches[5])) { $matches[5] = 0; }
29909 if (!isset($matches[6])) { $matches[6] = 0; }
29910 return str_replace($matches[0], $this->columnAdjustAdd($type, _MPDFK, $xadj, $yadj, $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]), $subject);
29911 }
29912
29913 /*-- END COLUMNS --*/
29914
29915
29916 //==================================================================
29917 /*-- TABLES --*/
29918 function printcellbuffer() {
29919 if (count($this->cellBorderBuffer )) {
29920 sort($this->cellBorderBuffer);
29921 foreach($this->cellBorderBuffer AS $cbb) {
29922 $cba = unpack("A16dom/nbord/A1side/ns/dbw/a6ca/A10style/dx/dy/dw/dh/dmbl/dmbr/dmrt/dmrb/dmtl/dmtr/dmlt/dmlb/dcpd/dover/", $cbb);
29923 $side = $cba['side'];
29924 $details = array();
29925 $details[$side]['dom'] = (float) $cba['dom'];
29926 $details[$side]['s'] = $cba['s'];
29927 $details[$side]['w'] = $cba['bw'];
29928 $details[$side]['c'] = $cba['ca'];
29929 $details[$side]['style'] = trim($cba['style']);
29930 $details['mbw']['BL'] = $cba['mbl'];
29931 $details['mbw']['BR'] = $cba['mbr'];
29932 $details['mbw']['RT'] = $cba['mrt'];
29933 $details['mbw']['RB'] = $cba['mrb'];
29934 $details['mbw']['TL'] = $cba['mtl'];
29935 $details['mbw']['TR'] = $cba['mtr'];
29936 $details['mbw']['LT'] = $cba['mlt'];
29937 $details['mbw']['LB'] = $cba['mlb'];
29938 $details['cellposdom'] = $cba['cpd'];
29939 $details['p'] = $side;
29940 if ($cba['over']==1) { $details[$side]['overlay'] = true; }
29941 else { $details[$side]['overlay'] = false; }
29942 $this->_tableRect($cba['x'],$cba['y'],$cba['w'],$cba['h'],$cba['bord'],$details, false, false);
29943
29944 }
29945 $this->cellBorderBuffer = array();
29946 }
29947 }
29948 //==================================================================
29949 function printtablebuffer() {
29950
29951 if (!$this->table_rotate) {
29952 $this->pages[$this->page] .= $this->tablebuffer;
29953 foreach($this->tbrot_Links AS $p => $l) {
29954 foreach($l AS $v) {
29955 $this->PageLinks[$p][] = $v;
29956 }
29957 }
29958 $this->tbrot_Links = array();
29959 /*-- ANNOTATIONS --*/
29960 foreach($this->tbrot_Annots AS $p => $l) {
29961 foreach($l AS $v) {
29962 $this->PageAnnots[$p][] = $v;
29963 }
29964 }
29965 $this->tbrot_Annots = array();
29966 /*-- END ANNOTATIONS --*/
29967
29968 /*-- INDEX --*/
29969 // Output Reference (index)
29970 foreach($this->tbrot_Reference AS $v) {
29971 $Present=0;
29972 for ($i=0;$i<count($this->Reference);$i++){
29973 if ($this->Reference[$i]['t']==$v['t']){
29974 $Present=1;
29975 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
29976 $this->Reference[$i]['p'][] = $v['op'];
29977 }
29978 }
29979 }
29980 if ($Present==0) {
29981 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
29982 }
29983 }
29984 $this->tbrot_Reference = array();
29985 /*-- END INDEX --*/
29986
29987 /*-- BOOKMARKS --*/
29988 // Output Bookmarks
29989 foreach($this->tbrot_BMoutlines AS $v) {
29990 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
29991 }
29992 $this->tbrot_BMoutlines = array();
29993 /*-- END BOOKMARKS --*/
29994
29995 /*-- TOC --*/
29996 // Output ToC
29997 foreach($this->tbrot_toc AS $v) {
29998 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
29999 }
30000 $this->tbrot_toc = array();
30001 /*-- END TOC --*/
30002
30003 return;
30004 }
30005 // else if rotated
30006 $lm = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left'];
30007 $pw = $this->blk[$this->blklvl]['inner_width'];
30008 //Start Transformation
30009 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
30010
30011 if ($this->table_rotate > 1) { // clockwise
30012 if ($this->tbrot_align == 'L') {
30013 $xadj = $this->tbrot_h ; // align L (as is)
30014 }
30015 else if ($this->tbrot_align == 'R') {
30016 $xadj = $lm-$this->tbrot_x0+($pw) ; // align R
30017 }
30018 else {
30019 $xadj = $lm-$this->tbrot_x0+(($pw + $this->tbrot_h)/2) ; // align C
30020 }
30021 $yadj = 0;
30022 }
30023 else { // anti-clockwise
30024 if ($this->tbrot_align == 'L') {
30025 $xadj = 0 ; // align L (as is)
30026 }
30027 else if ($this->tbrot_align == 'R') {
30028 $xadj = $lm-$this->tbrot_x0+($pw - $this->tbrot_h) ; // align R
30029 }
30030 else {
30031 $xadj = $lm-$this->tbrot_x0+(($pw - $this->tbrot_h)/2) ; // align C
30032 }
30033 $yadj = $this->tbrot_w;
30034 }
30035
30036
30037 $this->pages[$this->page] .= $this->transformTranslate($xadj, $yadj , true)."\n";
30038 $this->pages[$this->page] .= $this->transformRotate($this->table_rotate, $this->tbrot_x0 , $this->tbrot_y0 , true)."\n";
30039
30040 // Now output the adjusted values
30041 $this->pages[$this->page] .= $this->tablebuffer;
30042
30043
30044 foreach($this->tbrot_Links AS $p => $l) {
30045 foreach($l AS $v) {
30046 $w = $v[2]/_MPDFK;
30047 $h = $v[3]/_MPDFK;
30048 $ax = ($v[0]/_MPDFK) - $this->tbrot_x0;
30049 $ay = (($this->hPt-$v[1])/_MPDFK) - $this->tbrot_y0;
30050 if ($this->table_rotate > 1) { // clockwise
30051 $bx = $this->tbrot_x0+$xadj-$ay-$h;
30052 $by = $this->tbrot_y0+$yadj+$ax;
30053 }
30054 else {
30055 $bx = $this->tbrot_x0+$xadj+$ay;
30056 $by = $this->tbrot_y0+$yadj-$ax-$w;
30057 }
30058 $v[0] = $bx*_MPDFK;
30059 $v[1] = ($this->h-$by)*_MPDFK;
30060 $v[2] = $h*_MPDFK; // swap width and height
30061 $v[3] = $w*_MPDFK;
30062 $this->PageLinks[$p][] = $v;
30063 }
30064 }
30065 $this->tbrot_Links = array();
30066 foreach($this->internallink AS $key => $f) {
30067 if (is_array($f) && isset($f['tbrot'])) {
30068 $f['Y'] = $this->tbrot_y0;
30069 $f['PAGE'] = $this->page;
30070 unset($f['tbrot']);
30071 $this->internallink[$key] = $f;
30072 }
30073 }
30074 /*-- ANNOTATIONS --*/
30075 foreach($this->tbrot_Annots AS $p => $l) {
30076 foreach($l AS $v) {
30077 $ax = abs($v['x']) - $this->tbrot_x0; // abs because -ve values are internally set and held for reference if annotMargin set
30078 $ay = $v['y'] - $this->tbrot_y0;
30079 if ($this->table_rotate > 1) { // clockwise
30080 $bx = $this->tbrot_x0+$xadj-$ay;
30081 $by = $this->tbrot_y0+$yadj+$ax;
30082 }
30083 else {
30084 $bx = $this->tbrot_x0+$xadj+$ay;
30085 $by = $this->tbrot_y0+$yadj-$ax;
30086 }
30087 if ($v['x'] < 0) {
30088 $v['x'] = -$bx;
30089 }
30090 else {
30091 $v['x'] = $bx;
30092 }
30093 $v['y'] = ($by);
30094 $this->PageAnnots[$p][] = $v;
30095 }
30096 }
30097 $this->tbrot_Annots = array();
30098 /*-- END ANNOTATIONS --*/
30099
30100
30101 /*-- BOOKMARKS --*/
30102
30103 // Adjust Bookmarks
30104 foreach($this->tbrot_BMoutlines AS $v) {
30105 $v['y'] = $this->tbrot_y0;
30106 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$this->page);
30107 }
30108 /*-- END BOOKMARKS --*/
30109
30110 /*-- INDEX --*/
30111
30112 // Adjust Reference (index)
30113 foreach($this->tbrot_Reference AS $v) {
30114 $Present=0;
30115 //Search the reference (AND Ref/PageNo) in the array
30116 for ($i=0;$i<count($this->Reference);$i++){
30117 if ($this->Reference[$i]['t']==$v['t']){
30118 $Present=1;
30119 if (!in_array($this->page,$this->Reference[$i]['p'])) {
30120 $this->Reference[$i]['p'][] = $this->page;
30121 }
30122 }
30123 }
30124 if ($Present==0) {
30125 $this->Reference[]=array('t'=>$v['t'],'p'=>array($this->page));
30126 }
30127 }
30128 /*-- END INDEX --*/
30129
30130 /*-- TOC --*/
30131
30132 // Adjust ToC - uses document page number
30133 foreach($this->tbrot_toc AS $v) {
30134 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$this->page,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
30135 $this->links[$v['link']][1] = $this->tbrot_y0;
30136 }
30137 /*-- END TOC --*/
30138
30139
30140
30141 $this->tbrot_Reference = array();
30142 $this->tbrot_BMoutlines = array();
30143 $this->tbrot_toc = array();
30144
30145 //Stop Transformation
30146 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
30147
30148
30149 $this->y = $this->tbrot_y0 + $this->tbrot_w;
30150 $this->x = $this->lMargin;
30151
30152 $this->tablebuffer = '';
30153 }
30154
30155 //==================================================================
30156 // Keep-with-table This buffers contents of h1-6 to keep on page with table
30157 function printkwtbuffer() {
30158 if (!$this->kwt_moved) {
30159 foreach($this->kwt_buffer AS $s) { $this->pages[$this->page] .= $s['s']."\n"; }
30160 foreach($this->kwt_Links AS $p => $l) {
30161 foreach($l AS $v) {
30162 $this->PageLinks[$p][] = $v;
30163 }
30164 }
30165 $this->kwt_Links = array();
30166 /*-- ANNOTATIONS --*/
30167 foreach($this->kwt_Annots AS $p => $l) {
30168 foreach($l AS $v) {
30169 $this->PageAnnots[$p][] = $v;
30170 }
30171 }
30172 $this->kwt_Annots = array();
30173 /*-- END ANNOTATIONS --*/
30174
30175 /*-- INDEX --*/
30176 // Output Reference (index)
30177 foreach($this->kwt_Reference AS $v) {
30178 $Present=0;
30179 for ($i=0;$i<count($this->Reference);$i++){
30180 if ($this->Reference[$i]['t']==$v['t']){
30181 $Present=1;
30182 if (!in_array($v['op'],$this->Reference[$i]['p'])) {
30183 $this->Reference[$i]['p'][] = $v['op'];
30184 }
30185 }
30186 }
30187 if ($Present==0) {
30188 $this->Reference[]=array('t'=>$v['t'],'p'=>array($v['op']));
30189 }
30190 }
30191 $this->kwt_Reference = array();
30192 /*-- END INDEX --*/
30193
30194 /*-- BOOKMARKS --*/
30195 // Output Bookmarks
30196 foreach($this->kwt_BMoutlines AS $v) {
30197 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
30198 }
30199 $this->kwt_BMoutlines = array();
30200 /*-- END BOOKMARKS --*/
30201
30202 /*-- TOC --*/
30203 // Output ToC
30204 foreach($this->kwt_toc AS $v) {
30205 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
30206 }
30207 $this->kwt_toc = array();
30208 /*-- END TOC --*/
30209
30210 return;
30211 }
30212
30213 //Start Transformation
30214 $this->pages[$this->page] .= $this->StartTransform(true)."\n";
30215 $xadj = $this->lMargin - $this->kwt_x0 ;
30216 //$yadj = $this->y - $this->kwt_y0 ;
30217 $yadj = $this->tMargin - $this->kwt_y0 ;
30218
30219 $this->pages[$this->page] .= $this->transformTranslate($xadj, $yadj , true)."\n";
30220
30221 // Now output the adjusted values
30222 foreach($this->kwt_buffer AS $s) { $this->pages[$this->page] .= $s['s']."\n"; }
30223
30224 // Adjust hyperLinks
30225 foreach($this->kwt_Links AS $p => $l) {
30226 foreach($l AS $v) {
30227 $bx = $this->kwt_x0+$xadj;
30228 $by = $this->kwt_y0+$yadj;
30229 $v[0] = $bx*_MPDFK;
30230 $v[1] = ($this->h-$by)*_MPDFK;
30231 $this->PageLinks[$p][] = $v;
30232 }
30233 }
30234 foreach($this->internallink AS $key => $f) {
30235 if (is_array($f) && isset($f['kwt'])) {
30236 $f['Y'] += $yadj;
30237 $f['PAGE'] = $this->page;
30238 unset($f['kwt']);
30239 $this->internallink[$key] = $f;
30240 }
30241 }
30242 /*-- ANNOTATIONS --*/
30243 foreach($this->kwt_Annots AS $p => $l) {
30244 foreach($l AS $v) {
30245 $bx = $this->kwt_x0+$xadj;
30246 $by = $this->kwt_y0+$yadj;
30247 if ($v['x'] < 0) {
30248 $v['x'] = -$bx;
30249 }
30250 else {
30251 $v['x'] = $bx;
30252 }
30253 $v['y'] = $by;
30254 $this->PageAnnots[$p][] = $v;
30255 }
30256 }
30257 /*-- END ANNOTATIONS --*/
30258
30259 /*-- BOOKMARKS --*/
30260
30261 // Adjust Bookmarks
30262 foreach($this->kwt_BMoutlines AS $v) {
30263 if ($v['y'] != 0) { $v['y'] += $yadj; }
30264 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$this->page);
30265 }
30266 /*-- END BOOKMARKS --*/
30267
30268 /*-- INDEX --*/
30269
30270 // Adjust Reference (index)
30271 foreach($this->kwt_Reference AS $v) {
30272 $Present=0;
30273 //Search the reference (AND Ref/PageNo) in the array
30274 for ($i=0;$i<count($this->Reference);$i++){
30275 if ($this->Reference[$i]['t']==$v['t']){
30276 $Present=1;
30277 if (!in_array($this->page,$this->Reference[$i]['p'])) {
30278 $this->Reference[$i]['p'][] = $this->page;
30279 }
30280 }
30281 }
30282 if ($Present==0) {
30283 $this->Reference[]=array('t'=>$v['t'],'p'=>array($this->page));
30284 }
30285 }
30286 /*-- END INDEX --*/
30287
30288 /*-- TOC --*/
30289
30290 // Adjust ToC
30291 foreach($this->kwt_toc AS $v) {
30292 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$this->page,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
30293 $this->links[$v['link']][0] = $this->page;
30294 $this->links[$v['link']][1] += $yadj;
30295 }
30296 /*-- END TOC --*/
30297
30298
30299 $this->kwt_Links = array();
30300 $this->kwt_Annots = array();
30301
30302 $this->kwt_Reference = array();
30303 $this->kwt_BMoutlines = array();
30304 $this->kwt_toc = array();
30305 //Stop Transformation
30306 $this->pages[$this->page] .= $this->StopTransform(true)."\n";
30307
30308 $this->kwt_buffer = array();
30309
30310 $this->y += $this->kwt_height;
30311 }
30312
30313 /*-- END TABLES --*/
30314
30315
30316 //==================================================================
30317
30318 function printfloatbuffer() {
30319 if (count($this->floatbuffer)) {
30320 $this->objectbuffer = $this->floatbuffer;
30321 $this->printobjectbuffer(false);
30322 $this->objectbuffer = array();
30323 $this->floatbuffer = array();
30324 $this->floatmargins = array();
30325 }
30326 }
30327 //==================================================================
30328
30329 function printdivbuffer() {
30330 $p1 = $this->blk[$this->blklvl]['startpage'];
30331 $p2 = $this->page;
30332 $bottom[$p1] = $this->ktBlock[$p1]['bottom_margin'];
30333 $bottom[$p2] = $this->y; // $this->ktBlock[$p2]['bottom_margin'];
30334 $top[$p1] = $this->kt_y00;
30335
30336 $top2 = $this->h;
30337 foreach($this->divbuffer AS $key=>$s) {
30338 if ($s['page'] == $p2) {
30339 $top2 = MIN($s['y'], $top2);
30340 }
30341 }
30342 $top[$p2] = $top2;
30343 $height[$p1] = ($bottom[$p1] - $top[$p1]);
30344 $height[$p2] = ($bottom[$p2] - $top[$p2]);
30345 $xadj[$p1] = $this->MarginCorrection;
30346 $yadj[$p1] = -($top[$p1] - $top[$p2]);
30347 $xadj[$p2] = 0;
30348 $yadj[$p2] = $height[$p1];
30349
30350 // Output without any transformation
30351 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) {
30352 foreach($this->divbuffer AS $s) { $this->pages[$s['page']] .= $s['s']."\n"; }
30353 foreach($this->ktLinks AS $p => $l) {
30354 foreach($l AS $v) {
30355 $this->PageLinks[$p][] = $v;
30356 }
30357 }
30358 foreach($this->ktForms AS $key => $f) {
30359 $this->form->forms[$f['n']] = $f;
30360 }
30361 /*-- ANNOTATIONS --*/
30362 foreach($this->ktAnnots AS $p => $l) {
30363 foreach($l AS $v) {
30364 $this->PageAnnots[$p][] = $v;
30365 }
30366 }
30367 /*-- END ANNOTATIONS --*/
30368 /*-- INDEX --*/
30369 // Adjust Reference (index)
30370 foreach($this->ktReference AS $v) {
30371 $Present=0;
30372 //Search the reference (AND Ref/PageNo) in the array
30373 for ($i=0;$i<count($this->Reference);$i++){
30374 if ($this->Reference[$i]['t']==$v['t']){
30375 $Present=1;
30376 if (!in_array($p2,$this->Reference[$i]['p'])) {
30377 $this->Reference[$i]['p'][] = $p2;
30378 }
30379 }
30380 }
30381 //If not found, add it
30382 if ($Present==0) {
30383 $this->Reference[]=array('t'=>$v['t'],'p'=>array($p2));
30384 }
30385 }
30386 /*-- END INDEX --*/
30387
30388 /*-- BOOKMARKS --*/
30389 // Adjust Bookmarks
30390 foreach($this->ktBMoutlines AS $v) {
30391 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$v['p']);
30392 }
30393 /*-- END BOOKMARKS --*/
30394
30395 /*-- TOC --*/
30396 // Adjust ToC
30397 foreach($this->_kttoc AS $v) {
30398 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$v['p'],'link'=>$v['link'],'toc_id'=>$v['toc_id']);
30399 }
30400 /*-- END TOC --*/
30401
30402 $this->divbuffer = array();
30403 $this->ktLinks = array();
30404 $this->ktAnnots = array();
30405 $this->ktForms = array();
30406 $this->ktBlock = array();
30407 $this->ktReference = array();
30408 $this->ktBMoutlines = array();
30409 $this->_kttoc = array();
30410 $this->keep_block_together = 0;
30411 return;
30412 }
30413 else {
30414 // Output with transformation
30415 // mPDF 5.6.17
30416 $np = '';
30417 $lastpage = -1;
30418 foreach($this->divbuffer AS $key=>$s) {
30419 // callback function
30420 $t = $s['s'];
30421 $p = $s['page'];
30422 if ($p != $lastpage) {
30423 $q = '';
30424 if ($lastpage != -1) { $q = ' Q'."\n"; }
30425 $t = $q . $this->StartTransform(true)."\n" . $this->transformTranslate($xadj[$p], $yadj[$p] , true)."\n" . $t;
30426 $lastpage = $p;
30427 }
30428 $np .= $t."\n";
30429 }
30430 if ($lastpage != -1) { $np .= ' Q'."\n"; }
30431
30432 $this->pages[$this->page] .= $np;
30433
30434 // Adjust hyperLinks
30435 foreach($this->ktLinks AS $p => $l) {
30436 foreach($l AS $v) {
30437 $v[0] += ($xadj[$p]*_MPDFK);
30438 $v[1] -= ($yadj[$p]*_MPDFK);
30439 $this->PageLinks[$p2][] = $v;
30440 }
30441 }
30442 foreach($this->ktForms AS $key => $f) {
30443 $p = $f['page'];
30444 $f['x'] += ($xadj[$p]);
30445 $f['y'] += ($yadj[$p]);
30446 $f['page'] = $p2;
30447 $this->form->forms[$f['n']] = $f;
30448 }
30449 foreach($this->internallink AS $key => $f) {
30450 if (is_array($f) && isset($f['kt'])) {
30451 $f['Y'] += ($yadj[$f['PAGE']]);
30452 $f['PAGE'] = $p2;
30453 unset($f['kt']);
30454 $this->internallink[$key] = $f;
30455 }
30456 }
30457 /*-- ANNOTATIONS --*/
30458 foreach($this->ktAnnots AS $p => $l) {
30459 foreach($l AS $v) {
30460 if ($v['x']>0) { $v['x'] += $xadj[$p]; }
30461 else if ($v['x']<0) { $v['x'] -= $xadj[$p]; }
30462 $v['y'] += $yadj[$p];
30463 $this->PageAnnots[$p2][] = $v;
30464 }
30465 }
30466 /*-- END ANNOTATIONS --*/
30467
30468 /*-- BOOKMARKS --*/
30469 // Adjust Bookmarks
30470 foreach($this->ktBMoutlines AS $v) {
30471 if ($v['y'] != 0) { $v['y'] += ($yadj[$v['p']]); }
30472 $this->BMoutlines[]=array('t'=>$v['t'],'l'=>$v['l'],'y'=>$v['y'],'p'=>$p2);
30473 }
30474 /*-- END BOOKMARKS --*/
30475
30476 /*-- INDEX --*/
30477 // Adjust Reference (index)
30478 foreach($this->ktReference AS $v) {
30479 $Present=0;
30480 //Search the reference (AND Ref/PageNo) in the array
30481 for ($i=0;$i<count($this->Reference);$i++){
30482 if ($this->Reference[$i]['t']==$v['t']){
30483 $Present=1;
30484 if (!in_array($p2,$this->Reference[$i]['p'])) {
30485 $this->Reference[$i]['p'][] = $p2;
30486 }
30487 }
30488 }
30489 //If not found, add it
30490 if ($Present==0) {
30491 $this->Reference[]=array('t'=>$v['t'],'p'=>array($p2));
30492 }
30493 }
30494 /*-- END INDEX --*/
30495
30496 /*-- TOC --*/
30497 // Adjust ToC
30498 foreach($this->_kttoc AS $v) {
30499 $this->tocontents->_toc[]=array('t'=>$v['t'],'l'=>$v['l'],'p'=>$p2,'link'=>$v['link'],'toc_id'=>$v['toc_id']);
30500 $this->links[$v['link']][0] = $p2;
30501 $this->links[$v['link']][1] += $yadj[$v['p']];
30502 }
30503 /*-- END TOC --*/
30504
30505 $this->y = $top[$p2] + $height[$p1] + $height[$p2];
30506 $this->x = $this->lMargin;
30507
30508 $this->divbuffer = array();
30509 $this->ktLinks = array();
30510 $this->ktAnnots = array();
30511 $this->ktForms = array();
30512 $this->ktBlock = array();
30513 $this->ktReference = array();
30514 $this->ktBMoutlines = array();
30515 $this->_kttoc = array();
30516 $this->keep_block_together = 0;
30517 }
30518 }
30519
30520
30521 //==================================================================
30522 // Added ELLIPSES and CIRCLES
30523 function Circle($x,$y,$r,$style='S') {
30524 $this->Ellipse($x,$y,$r,$r,$style);
30525 }
30526
30527 function Ellipse($x,$y,$rx,$ry,$style='S') {
30528 if($style=='F') { $op='f'; }
30529 elseif($style=='FD' or $style=='DF') { $op='B'; }
30530 else { $op='S'; }
30531 $lx=4/3*(M_SQRT2-1)*$rx;
30532 $ly=4/3*(M_SQRT2-1)*$ry;
30533 $h=$this->h;
30534 $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));
30535 $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));
30536 $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));
30537 $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));
30538 }
30539
30540 /*-- DIRECTW --*/
30541 // Added adaptation of shaded_box = AUTOSIZE-TEXT
30542 function AutosizeText($text,$w,$font,$style,$szfont=72) {
30543 $text = $this->purify_utf8_text($text);
30544 if ($this->text_input_as_HTML) {
30545 $text = $this->all_entities_to_utf8($text);
30546 }
30547 if ($this->usingCoreFont) { $text = mb_convert_encoding($text,$this->mb_enc,'UTF-8'); }
30548 $text = ' '.$text.' ';
30549 $width = $this->ConvertSize($w);
30550 $loop = 0;
30551 while ( $loop == 0 ) {
30552 $this->SetFont($font,$style,$szfont);
30553 $sz = $this->GetStringWidth( $text );
30554 if ( $sz > $w ) { $szfont --; }
30555 else { $loop ++; }
30556 }
30557 $this->SetFont($font,$style,$szfont);
30558 $this->Cell($w, 0, $text, 0, 0, "C");
30559 }
30560 /*-- END DIRECTW --*/
30561
30562
30563
30564
30565
30566 // ====================================================
30567 // ====================================================
30568 /*-- RTL --*/
30569 function reverse_letters($str) {
30570 $str = strtr($str, '{}[]()', '}{][)(');
30571 return $this->mb_strrev($str, $this->mb_enc);
30572 }
30573
30574 // mPDF 5.7+
30575 function reverse_letters_preg_callback($matches) {
30576 return $this->reverse_letters($matches[1]);
30577 }
30578
30579 function magic_reverse_dir(&$chunk, $join=true, $dir) {
30580 if ($this->usingCoreFont) { return 0; }
30581 if ($this->biDirectional) {
30582 // mPDF 5.4.05 Include PUA for non-indexed Arabic glyphs
30583 $pregRTLchars = $this->pregRTLchars;
30584 if ($this->CurrentFont['unAGlyphs']) { $pregRTLchars .= "\x{F500}-\x{F7FF}"; }
30585
30586 // Change Arabic + Persian. to Presentation Forms
30587 if ($join) {
30588 $chunk = preg_replace_callback("/([".$pregRTLchars."]+)/u", array($this, 'arabJoinPregCallback'), $chunk ); // mPDF 5.7+
30589 }
30590 $contains_rtl = false;
30591 $all_rtl = true;
30592 $initSpace = false;
30593 $endSpace = false;
30594 $nonDirchars = "\x{A0}\"\'\(\)\{\}\[\].,:\\/-="; // mPDF 5.6.32
30595 // mPDF 5.6.43
30596 $bdo=array();
30597 preg_match_all('/([\x{202A}\x{202B}])(.*?)([\x{202C}])/u',$chunk,$m);
30598 if (count($m[0])) {
30599 for($i=0;$i<count($m[0]);$i++) {
30600 if ($m[1][$i]=="\xe2\x80\xab") { // Right-to-Left Embedding [RLE] U+202B &#8235;
30601 $mark = code2utf(0xf800+$i);
30602 $bdo[$i] = $this->reverse_letters($m[2][$i]);
30603 }
30604 else if ($m[1][$i]=="\xe2\x80\xaa") { // Left-to-Right Embedding [LRE] U+202A &#8234;
30605 $mark = code2utf(0xf880+$i);
30606 $bdo[$i] = $m[2][$i];
30607 }
30608 $chunk = preg_replace('/'.preg_quote($m[0][$i],'/').'/u',$mark,$chunk);
30609 }
30610 $pregRTLchars .= "\x{F800}-\x{F87F}";
30611 }
30612 if (preg_match("/[".$pregRTLchars."]/u",$chunk)) { // Chunk contains RTL characters
30613 if (preg_match("/^[ ]/",$chunk)) { $initSpace = true; $chunk = preg_replace("/^[ ]/",'',$chunk); }
30614 if (preg_match("/[ ]$/",$chunk)) { $endSpace = true; $chunk = preg_replace("/[ ]$/",'',$chunk); }
30615
30616 if (preg_match("/[^".$pregRTLchars.$nonDirchars." ]/u",$chunk)) { // Chunk also contains LTR characters
30617 $all_rtl = false;
30618 if ($dir == 'rtl') {
30619 $chunk = preg_replace("/([^".$pregRTLchars.$nonDirchars."][".$nonDirchars."]*) ([".$nonDirchars."]*[^".$pregRTLchars.$nonDirchars."])/u","\\1\x07\\2",$chunk);
30620 }
30621 $chunk = preg_replace("/([".$pregRTLchars."][".$nonDirchars."]*) ([".$nonDirchars."]*[".$pregRTLchars."])/u","\\1\x07\\2",$chunk);
30622 $bits = explode(' ',$chunk);
30623 foreach($bits AS $bitkey=>$bit) {
30624 $bit = preg_replace("/\x07/"," ",$bit);
30625 if (preg_match("/^[".$pregRTLchars.$nonDirchars." ]*$/u",$bit)) {
30626 $bits[$bitkey] = $this->reverse_letters($bit);
30627 }
30628 else if (preg_match("/[".$pregRTLchars."]/u",$bit)) {
30629 if ($dir == 'rtl') {
30630 $bit = preg_replace("/([^".$pregRTLchars.$nonDirchars." ])([".$nonDirchars."]*[".$pregRTLchars."])/u","\\1\x07\\2",$bit );
30631 $bit = preg_replace("/([".$pregRTLchars."][".$nonDirchars."]*)([^".$pregRTLchars.$nonDirchars." ])/u","\\1\x07\\2",$bit );
30632 }
30633 else {
30634 $bit = preg_replace("/([^".$pregRTLchars." ][".$nonDirchars."]*)([".$pregRTLchars." ])/u","\\1\x07\\2",$bit );
30635 $bit = preg_replace("/([".$pregRTLchars." ])([".$nonDirchars."]*[^".$pregRTLchars." ])/u","\\1\x07\\2",$bit );
30636 }
30637 $sbits = explode("\x07",$bit );
30638 foreach($sbits AS $sbitkey=>$sbit) {
30639 $sbit = preg_replace("/\x07/","",$sbit);
30640 if (preg_match("/^[".$pregRTLchars.$nonDirchars." ]*$/u",$sbit)) {
30641 $sbits[$sbitkey] = $this->reverse_letters($sbit);
30642 }
30643 else if (preg_match("/[".$pregRTLchars."]/u",$sbit) && $dir=='rtl') {
30644 $sbits[$sbitkey] = $this->reverse_letters($sbit);
30645 }
30646 else {
30647 // Reverse numerals only to RTL
30648 $sbit = preg_replace_callback("/([\x{0660}-\x{066C}0-9]+[\x{0660}-\x{066C}0-9\.,:\/]*[\x{0660}-\x{066C}0-9]+)/u", array($this, 'reverse_letters_preg_callback'), $sbit ); // mPDF 5.7+
30649 $sbits[$sbitkey] = $sbit;
30650 }
30651 }
30652 if ($dir == 'rtl') { $sbits = array_reverse($sbits,false); }
30653 $bits[$bitkey] = implode('',$sbits);
30654 }
30655 else if (preg_match("/[".$pregRTLchars."]/u",$bit) && $dir=='rtl') {
30656 $bits[$bitkey] = $this->reverse_letters($bit);
30657 }
30658 else {
30659 // Reverse numerals only to RTL
30660 $bit = preg_replace_callback("/([\x{0660}-\x{066C}0-9]+[\x{0660}-\x{066C}0-9\.,:\/]*[\x{0660}-\x{066C}0-9]+)/u", array($this, 'reverse_letters_preg_callback'), $bit ); // mPDF 5.7+
30661 $bits[$bitkey] = $bit;
30662 }
30663 }
30664 if ($dir == 'rtl') { $bits = array_reverse($bits,false); }
30665 $chunk = implode(' ',$bits);
30666 }
30667 else { $chunk = $this->reverse_letters($chunk); }
30668 $contains_rtl = true;
30669
30670 // Un-Reverse numerals back to ltr
30671 $chunk = preg_replace_callback("/([\x{0660}-\x{066C}0-9]+[\x{0660}-\x{066C}0-9\.,:\/]*[\x{0660}-\x{066C}0-9]+)/u", array($this, 'reverse_letters_preg_callback'), $chunk ); // mPDF 5.7+
30672 if ($dir == 'rtl') {
30673 if ($endSpace) { $chunk = ' '.$chunk; }
30674 if ($initSpace) { $chunk .= ' '; }
30675 }
30676 else {
30677 if ($initSpace) { $chunk = ' '.$chunk; }
30678 if ($endSpace) { $chunk .= ' '; }
30679 }
30680 }
30681 else { $all_rtl = false; }
30682
30683 // mPDF 5.6.43
30684 if (count($bdo)) {
30685 for($i=0;$i<count($bdo);$i++) {
30686 $chunk = preg_replace('/[\x{'.dechex(intval(0xf800+$i)).'}\x{'.dechex(intval(0xf880+$i)).'}]/u',$bdo[$i],$chunk);
30687 }
30688 }
30689
30690 if ($all_rtl) { return 2; }
30691 else if ($contains_rtl) { return 1; }
30692 else { return 0; }
30693 }
30694 return 0;
30695 }
30696 /*-- END RTL --*/
30697
30698 //
30699 // ****************************
30700 // ****************************
30701
30702
30703 function SetSubstitutions() {
30704 $subsarray = array();
30705 @include(_MPDF_PATH.'includes/subs_win-1252.php');
30706 $this->substitute = array();
30707 foreach($subsarray AS $key => $val) {
30708 $this->substitute[code2utf($key)] = $val;
30709 }
30710 }
30711
30712
30713 function SubstituteChars($html) {
30714 // only substitute characters between tags
30715 if (count($this->substitute)) {
30716 $a=preg_split('/(<.*?>)/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
30717 $html = '';
30718 foreach($a as $i => $e) {
30719 if($i%2==0) {
30720 $e = strtr($e, $this->substitute);
30721 }
30722 $html .= $e;
30723 }
30724 }
30725 return $html;
30726 }
30727
30728
30729 function SubstituteCharsSIP(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30730 if (preg_match("/^(.*?)([\x{20000}-\x{2FFFF}]+)(.*)/u", $writehtml_e, $m)) {
30731 if (isset($this->CurrentFont['sipext']) && $this->CurrentFont['sipext']) {
30732 $font = $this->CurrentFont['sipext'];
30733 if (!in_array($font, $this->available_unifonts)) { return 0; }
30734 $writehtml_a[$writehtml_i] = $writehtml_e = $m[1];
30735 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30736 $this->subPos = $writehtml_i;
30737 return 4;
30738 }
30739 }
30740 return 0;
30741 }
30742
30743 // If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
30744 function SubstituteCharsNonCore(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30745 if (mb_convert_encoding(mb_convert_encoding($writehtml_e, $this->mb_enc, "UTF-8"), "UTF-8", $this->mb_enc) == $writehtml_e) {
30746 return 0;
30747 }
30748 $cw = &$this->CurrentFont['cw'];
30749 $unicode = $this->UTF8StringToArray($writehtml_e, false);
30750 $start = -1;
30751 $end = 0;
30752 $flag = 0;
30753 $ftype = '';
30754 $u = array();
30755 if (!$this->subArrMB) {
30756 include(_MPDF_PATH.'includes/subs_core.php');
30757 $this->subArrMB['a'] = $aarr;
30758 $this->subArrMB['s'] = $sarr;
30759 $this->subArrMB['z'] = $zarr;
30760 }
30761 foreach($unicode AS $c => $char) {
30762 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)) {
30763 if ($flag==0) { $start=$c; }
30764 $flag=1;
30765 $u[] = $char;
30766 }
30767 else if ($flag>0) { $end=$c-1; break; }
30768 }
30769 if ($flag>0 && !$end) { $end=count($unicode)-1; }
30770 if ($start==-1) { return 0; }
30771 // TRY IN BACKUP SUBS FONT
30772 if (!is_array($this->backupSubsFont)) { $this->backupSubsFont = array("$this->backupSubsFont"); }
30773 foreach($this->backupSubsFont AS $bsfctr=>$bsf) {
30774 if ($this->fonttrans[$bsf] == 'chelvetica' || $this->fonttrans[$bsf] == 'ctimes' || $this->fonttrans[$bsf] == 'ccourier') { continue; }
30775 $font = $bsf;
30776 unset($cw);
30777 $cw = '';
30778 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30779 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30780 else {
30781
30782 $prevFontFamily = $this->FontFamily;
30783 $prevFontStyle = $this->currentfontstyle;
30784 $prevFontSizePt = $this->FontSizePt;
30785 $this->SetFont($bsf, '', '', false);
30786 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30787 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30788 }
30789 if (!$cw) { continue; }
30790 $l = 0;
30791 foreach($u AS $char) {
30792 if ($char == 173 || $this->_charDefined($cw,$char) || ($char>1536 && $char<1791) || ($char>2304 && $char<3455 )) {
30793 $l++;
30794 }
30795 else {
30796 if ($l==0 && $bsfctr == (count($this->backupSubsFont)-1)) { // Not found even in last backup font
30797 $cont = mb_substr($writehtml_e, $start+1);
30798 $writehtml_e = mb_substr($writehtml_e, 0, $start+1, 'UTF-8');
30799 array_splice($writehtml_a, $writehtml_i+1, 0, array('', $cont));
30800 $this->subPos = $writehtml_i+1;
30801 return 2;
30802 }
30803 else { break; }
30804 }
30805 }
30806 if ($l > 0) {
30807 $patt = mb_substr($writehtml_e, $start, $l, 'UTF-8');
30808 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30809 $writehtml_e = $m[1];
30810 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30811 $this->subPos = $writehtml_i+3;
30812 return 4;
30813 }
30814 }
30815 }
30816
30817 unset($cw);
30818 return 0;
30819 }
30820
30821
30822 function SubstituteCharsMB(&$writehtml_a, &$writehtml_i, &$writehtml_e) {
30823 $cw = &$this->CurrentFont['cw'];
30824 $unicode = $this->UTF8StringToArray($writehtml_e, false);
30825 $start = -1;
30826 $end = 0;
30827 $flag = 0;
30828 $ftype = '';
30829 $u = array();
30830 foreach($unicode AS $c => $char) {
30831 if (($flag == 0 || $flag==2) && (!$this->_charDefined($cw,$char) || ($flag==2 && $char==32)) && $this->checkSIP && $char > 131071) { // Unicode Plane 2 (SIP)
30832 if (in_array($this->FontFamily ,$this->available_CJK_fonts)) { return 0; }
30833 if ($flag==0) { $start=$c; }
30834 $flag=2;
30835 $u[] = $char;
30836 }
30837 //else if (($flag == 0 || $flag==1) && $char != 173 && !$this->_charDefined($cw,$char) && ($char<1423 || ($char>3583 && $char < 11263))) {
30838 else if (($flag == 0 || $flag==1) && $char != 173 && (!$this->_charDefined($cw,$char) || ($flag==1 && $char==32)) && ($char<1536 || ($char>1791 && $char < 2304) || $char>3455)) {
30839 if ($flag==0) { $start=$c; }
30840 $flag=1;
30841 $u[] = $char;
30842 }
30843 else if ($flag>0) { $end=$c-1; break; }
30844 }
30845 if ($flag>0 && !$end) { $end=count($unicode)-1; }
30846 if ($start==-1) { return 0; }
30847 if ($flag == 2) { // SIP
30848 // Check if current CJK font has a ext-B related font
30849 if (isset($this->CurrentFont['sipext']) && $this->CurrentFont['sipext']) {
30850 $font = $this->CurrentFont['sipext'];
30851 unset($cw);
30852 $cw = '';
30853 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30854 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30855 else {
30856 $prevFontFamily = $this->FontFamily;
30857 $prevFontStyle = $this->currentfontstyle;
30858 $prevFontSizePt = $this->FontSizePt;
30859 $this->SetFont($font, '', '', false);
30860 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30861 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30862 }
30863 if (!$cw) { return 0; }
30864 $l = 0;
30865 foreach($u AS $char) {
30866 if ($this->_charDefined($cw,$char) || $char > 131071) {
30867 $l++;
30868 }
30869 else { break; }
30870 }
30871 if ($l > 0) {
30872 $patt = mb_substr($writehtml_e, $start, $l);
30873 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30874 $writehtml_e = $m[1];
30875 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30876 $this->subPos = $writehtml_i+3;
30877 return 4;
30878 }
30879 }
30880 }
30881 // Check Backup SIP font (defined in config_fonts.php)
30882 if (isset($this->backupSIPFont) && $this->backupSIPFont) {
30883 if ($this->currentfontfamily != $this->backupSIPFont) { $font = $this->backupSIPFont; }
30884 else { unset($cw); return 0; }
30885 unset($cw);
30886 $cw = '';
30887 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30888 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30889 else {
30890 $prevFontFamily = $this->FontFamily;
30891 $prevFontStyle = $this->currentfontstyle;
30892 $prevFontSizePt = $this->FontSizePt;
30893 $this->SetFont($this->backupSIPFont, '', '', false);
30894 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30895 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30896 }
30897 if (!$cw) { return 0; }
30898 $l = 0;
30899 foreach($u AS $char) {
30900 if ($this->_charDefined($cw,$char) || $char > 131071) {
30901 $l++;
30902 }
30903 else { break; }
30904 }
30905 if ($l > 0) {
30906 $patt = mb_substr($writehtml_e, $start, $l);
30907 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30908 $writehtml_e = $m[1];
30909 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
30910 $this->subPos = $writehtml_i+3;
30911 return 4;
30912 }
30913 }
30914 }
30915 return 0;
30916 }
30917
30918
30919 // FIRST TRY CORE FONTS
30920 if (!$this->PDFA && !$this->PDFX) {
30921 $repl = array();
30922 if (!$this->subArrMB) {
30923 include(_MPDF_PATH.'includes/subs_core.php');
30924 $this->subArrMB['a'] = $aarr;
30925 $this->subArrMB['s'] = $sarr;
30926 $this->subArrMB['z'] = $zarr;
30927 }
30928 if (isset($this->subArrMB['a'][$u[0]])) {
30929 $font = 'tta'; $ftype = 'C';
30930 foreach($u AS $char) {
30931 if ($this->subArrMB['a'][$char]) { $repl[] = $this->subArrMB['a'][$char]; }
30932 else { break; }
30933 }
30934 }
30935 else if (isset($this->subArrMB['z'][$u[0]])) {
30936 $font = 'ttz'; $ftype = 'C';
30937 foreach($u AS $char) {
30938 if ($this->subArrMB['z'][$char]) { $repl[] = $this->subArrMB['z'][$char]; }
30939 else { break; }
30940 }
30941 }
30942 else if (isset($this->subArrMB['s'][$u[0]])) {
30943 $font = 'tts'; $ftype = 'C';
30944 foreach($u AS $char) {
30945 if ($this->subArrMB['s'][$char]) { $repl[] = $this->subArrMB['s'][$char]; }
30946 else { break; }
30947 }
30948 }
30949 if ($ftype=='C') {
30950 $patt = mb_substr($writehtml_e, $start, count($repl));
30951 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
30952 $writehtml_e = $m[1];
30953 array_splice($writehtml_a, $writehtml_i+1, 0, array($font, implode('|', $repl), '/'.$font, $m[3])); // e.g. <tts>
30954 $this->subPos = $writehtml_i+3;
30955 return 4;
30956 }
30957 return 0;
30958 }
30959 }
30960
30961 // FIND IN DEFAULT FONT - removed mPDF 5.0
30962
30963 // LASTLY TRY IN BACKUP SUBS FONT
30964 if (!is_array($this->backupSubsFont)) { $this->backupSubsFont = array("$this->backupSubsFont"); }
30965 foreach($this->backupSubsFont AS $bsfctr=>$bsf) {
30966 if ($this->currentfontfamily != $bsf) { $font = $bsf; }
30967 else { continue; }
30968 unset($cw);
30969 $cw = '';
30970 if (isset($this->fonts[$font])) { $cw = &$this->fonts[$font]['cw']; }
30971 else if (file_exists(_MPDF_TTFONTDATAPATH.$font.'.cw.dat')) { $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat'); }
30972 else {
30973 $prevFontFamily = $this->FontFamily;
30974 $prevFontStyle = $this->currentfontstyle;
30975 $prevFontSizePt = $this->FontSizePt;
30976 $this->SetFont($bsf, '', '', false);
30977 $cw = @file_get_contents(_MPDF_TTFONTDATAPATH.$font.'.cw.dat');
30978 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false);
30979 }
30980 if (!$cw) { continue; }
30981 $l = 0;
30982 foreach($u AS $char) {
30983 if ($char == 173 || $this->_charDefined($cw,$char) || ($char>1536 && $char<1791) || ($char>2304 && $char<3455 )) { // Arabic and Indic
30984 $l++;
30985 }
30986 else {
30987 if ($l==0 && $bsfctr == (count($this->backupSubsFont)-1)) { // Not found even in last backup font
30988 $cont = mb_substr($writehtml_e, $start+1);
30989 $writehtml_e = mb_substr($writehtml_e, 0, $start+1);
30990 array_splice($writehtml_a, $writehtml_i+1, 0, array('', $cont));
30991 $this->subPos = $writehtml_i+1;
30992 return 2;
30993 }
30994 else { break; }
30995 }
30996 }
30997 if ($l > 0) {
30998 $patt = mb_substr($writehtml_e, $start, $l);
30999 if (preg_match("/(.*?)(".preg_quote($patt,'/').")(.*)/u", $writehtml_e, $m)) {
31000 $writehtml_e = $m[1];
31001 array_splice($writehtml_a, $writehtml_i+1, 0, array('span style="font-family: '.$font.'"', $m[2], '/span', $m[3]));
31002 $this->subPos = $writehtml_i+3;
31003 return 4;
31004 }
31005 }
31006 }
31007
31008 unset($cw);
31009 return 0;
31010 }
31011
31012
31013 function setHiEntitySubstitutions() {
31014 $entarr = array (
31015 'nbsp' => '160', 'iexcl' => '161', 'cent' => '162', 'pound' => '163', 'curren' => '164', 'yen' => '165', 'brvbar' => '166', 'sect' => '167',
31016 'uml' => '168', 'copy' => '169', 'ordf' => '170', 'laquo' => '171', 'not' => '172', 'shy' => '173', 'reg' => '174', 'macr' => '175',
31017 'deg' => '176', 'plusmn' => '177', 'sup2' => '178', 'sup3' => '179', 'acute' => '180', 'micro' => '181', 'para' => '182', 'middot' => '183',
31018 'cedil' => '184', 'sup1' => '185', 'ordm' => '186', 'raquo' => '187', 'frac14' => '188', 'frac12' => '189', 'frac34' => '190',
31019 'iquest' => '191', 'Agrave' => '192', 'Aacute' => '193', 'Acirc' => '194', 'Atilde' => '195', 'Auml' => '196', 'Aring' => '197',
31020 'AElig' => '198', 'Ccedil' => '199', 'Egrave' => '200', 'Eacute' => '201', 'Ecirc' => '202', 'Euml' => '203', 'Igrave' => '204',
31021 'Iacute' => '205', 'Icirc' => '206', 'Iuml' => '207', 'ETH' => '208', 'Ntilde' => '209', 'Ograve' => '210', 'Oacute' => '211',
31022 'Ocirc' => '212', 'Otilde' => '213', 'Ouml' => '214', 'times' => '215', 'Oslash' => '216', 'Ugrave' => '217', 'Uacute' => '218',
31023 'Ucirc' => '219', 'Uuml' => '220', 'Yacute' => '221', 'THORN' => '222', 'szlig' => '223', 'agrave' => '224', 'aacute' => '225',
31024 'acirc' => '226', 'atilde' => '227', 'auml' => '228', 'aring' => '229', 'aelig' => '230', 'ccedil' => '231', 'egrave' => '232',
31025 'eacute' => '233', 'ecirc' => '234', 'euml' => '235', 'igrave' => '236', 'iacute' => '237', 'icirc' => '238', 'iuml' => '239',
31026 'eth' => '240', 'ntilde' => '241', 'ograve' => '242', 'oacute' => '243', 'ocirc' => '244', 'otilde' => '245', 'ouml' => '246',
31027 'divide' => '247', 'oslash' => '248', 'ugrave' => '249', 'uacute' => '250', 'ucirc' => '251', 'uuml' => '252', 'yacute' => '253',
31028 'thorn' => '254', 'yuml' => '255', 'OElig' => '338', 'oelig' => '339', 'Scaron' => '352', 'scaron' => '353', 'Yuml' => '376',
31029 'fnof' => '402', 'circ' => '710', 'tilde' => '732', 'Alpha' => '913', 'Beta' => '914', 'Gamma' => '915', 'Delta' => '916',
31030 'Epsilon' => '917', 'Zeta' => '918', 'Eta' => '919', 'Theta' => '920', 'Iota' => '921', 'Kappa' => '922', 'Lambda' => '923',
31031 'Mu' => '924', 'Nu' => '925', 'Xi' => '926', 'Omicron' => '927', 'Pi' => '928', 'Rho' => '929', 'Sigma' => '931', 'Tau' => '932',
31032 'Upsilon' => '933', 'Phi' => '934', 'Chi' => '935', 'Psi' => '936', 'Omega' => '937', 'alpha' => '945', 'beta' => '946', 'gamma' => '947',
31033 'delta' => '948', 'epsilon' => '949', 'zeta' => '950', 'eta' => '951', 'theta' => '952', 'iota' => '953', 'kappa' => '954',
31034 'lambda' => '955', 'mu' => '956', 'nu' => '957', 'xi' => '958', 'omicron' => '959', 'pi' => '960', 'rho' => '961', 'sigmaf' => '962',
31035 'sigma' => '963', 'tau' => '964', 'upsilon' => '965', 'phi' => '966', 'chi' => '967', 'psi' => '968', 'omega' => '969',
31036 'thetasym' => '977', 'upsih' => '978', 'piv' => '982', 'ensp' => '8194', 'emsp' => '8195', 'thinsp' => '8201', 'zwnj' => '8204',
31037 'zwj' => '8205', 'lrm' => '8206', 'rlm' => '8207', 'ndash' => '8211', 'mdash' => '8212', 'lsquo' => '8216', 'rsquo' => '8217',
31038 'sbquo' => '8218', 'ldquo' => '8220', 'rdquo' => '8221', 'bdquo' => '8222', 'dagger' => '8224', 'Dagger' => '8225', 'bull' => '8226',
31039 'hellip' => '8230', 'permil' => '8240', 'prime' => '8242', 'Prime' => '8243', 'lsaquo' => '8249', 'rsaquo' => '8250', 'oline' => '8254',
31040 'frasl' => '8260', 'euro' => '8364', 'image' => '8465', 'weierp' => '8472', 'real' => '8476', 'trade' => '8482', 'alefsym' => '8501',
31041 'larr' => '8592', 'uarr' => '8593', 'rarr' => '8594', 'darr' => '8595', 'harr' => '8596', 'crarr' => '8629', 'lArr' => '8656',
31042 'uArr' => '8657', 'rArr' => '8658', 'dArr' => '8659', 'hArr' => '8660', 'forall' => '8704', 'part' => '8706', 'exist' => '8707',
31043 'empty' => '8709', 'nabla' => '8711', 'isin' => '8712', 'notin' => '8713', 'ni' => '8715', 'prod' => '8719', 'sum' => '8721',
31044 'minus' => '8722', 'lowast' => '8727', 'radic' => '8730', 'prop' => '8733', 'infin' => '8734', 'ang' => '8736', 'and' => '8743',
31045 'or' => '8744', 'cap' => '8745', 'cup' => '8746', 'int' => '8747', 'there4' => '8756', 'sim' => '8764', 'cong' => '8773',
31046 'asymp' => '8776', 'ne' => '8800', 'equiv' => '8801', 'le' => '8804', 'ge' => '8805', 'sub' => '8834', 'sup' => '8835', 'nsub' => '8836',
31047 'sube' => '8838', 'supe' => '8839', 'oplus' => '8853', 'otimes' => '8855', 'perp' => '8869', 'sdot' => '8901', 'lceil' => '8968',
31048 'rceil' => '8969', 'lfloor' => '8970', 'rfloor' => '8971', 'lang' => '9001', 'rang' => '9002', 'loz' => '9674', 'spades' => '9824',
31049 'clubs' => '9827', 'hearts' => '9829', 'diams' => '9830',
31050 );
31051 foreach($entarr AS $key => $val) {
31052 $this->entsearch[] = '&'.$key.';';
31053 $this->entsubstitute[] = code2utf($val);
31054 }
31055 }
31056
31057 function SubstituteHiEntities($html) {
31058 // converts html_entities > ASCII 127 to unicode
31059 // Leaves in particular &lt; to distinguish from tag marker
31060 if (count($this->entsearch)) {
31061 $html = str_replace($this->entsearch,$this->entsubstitute,$html);
31062 }
31063 return $html;
31064 }
31065
31066
31067 // Edited v1.2 Pass by reference; option to continue if invalid UTF-8 chars
31068 function is_utf8(&$string) {
31069 if ($string === mb_convert_encoding(mb_convert_encoding($string, "UTF-32", "UTF-8"), "UTF-8", "UTF-32")) {
31070 return true;
31071 }
31072 else {
31073 if ($this->ignore_invalid_utf8) {
31074 $string = mb_convert_encoding(mb_convert_encoding($string, "UTF-32", "UTF-8"), "UTF-8", "UTF-32") ;
31075 return true;
31076 }
31077 else {
31078 return false;
31079 }
31080 }
31081 }
31082
31083
31084 function purify_utf8($html,$lo=true) {
31085 // For HTML
31086 // Checks string is valid UTF-8 encoded
31087 // converts html_entities > ASCII 127 to UTF-8
31088 // Only exception - leaves low ASCII entities e.g. &lt; &amp; etc.
31089 // Leaves in particular &lt; to distinguish from tag marker
31090 if (!$this->is_utf8($html)) {
31091 echo "<p><b>HTML contains invalid UTF-8 character(s)</b></p>";
31092 while (mb_convert_encoding(mb_convert_encoding($html, "UTF-32", "UTF-8"), "UTF-8", "UTF-32") != $html) {
31093 $a = iconv('UTF-8', 'UTF-8', $html);
31094 echo ($a);
31095 $pos = $start = strlen($a);
31096 $err = '';
31097 while ( ord(substr($html,$pos,1)) > 128 ) {
31098 $err .= '[[#'.ord(substr($html,$pos,1)).']]';
31099 $pos++;
31100 }
31101 echo '<span style="color:red; font-weight:bold">'.$err.'</span>';
31102 $html = substr($html, $pos);
31103 }
31104 echo $html;
31105 $this->Error("");
31106 }
31107 $html = preg_replace("/\r/", "", $html );
31108
31109 // converts html_entities > ASCII 127 to UTF-8
31110 // Leaves in particular &lt; to distinguish from tag marker
31111 $html = $this->SubstituteHiEntities($html);
31112
31113 // converts all &#nnn; or &#xHHH; to UTF-8 multibyte
31114 // If $lo==true then includes ASCII < 128
31115 $html = strcode2utf($html,$lo);
31116 return ($html);
31117 }
31118
31119 function purify_utf8_text($txt) {
31120 // For TEXT
31121 // Make sure UTF-8 string of characters
31122 if (!$this->is_utf8($txt)) { $this->Error("Text contains invalid UTF-8 character(s)"); }
31123
31124 $txt = preg_replace("/\r/", "", $txt );
31125
31126 return ($txt);
31127 }
31128 function all_entities_to_utf8($txt) {
31129 // converts txt_entities > ASCII 127 to UTF-8
31130 // Leaves in particular &lt; to distinguish from tag marker
31131 $txt = $this->SubstituteHiEntities($txt);
31132
31133 // converts all &#nnn; or &#xHHH; to UTF-8 multibyte
31134 $txt = strcode2utf($txt);
31135
31136 $txt = $this->lesser_entity_decode($txt);
31137 return ($txt);
31138 }
31139
31140
31141 // ====================================================
31142 /*-- BARCODES --*/
31143 // UPC/EAN barcode
31144 // EAN13, EAN8, UPCA, UPCE, ISBN, ISSN
31145 // Accepts 12 or 13 digits with or without - hyphens
31146 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) {
31147 if (empty($code)) {
31148 return;
31149 }
31150 $codestr = $code;
31151 $code = preg_replace('/\-/','',$code);
31152
31153 if (!class_exists('PDFBarcode', false)) {
31154 include(_MPDF_PATH.'classes/barcode.php');
31155 }
31156 $this->barcode = new PDFBarcode();
31157 if ($btype == 'ISSN' || $btype == 'ISBN') {
31158 $arrcode = $this->barcode->getBarcodeArray($code, 'EAN13');
31159 }
31160 else { $arrcode = $this->barcode->getBarcodeArray($code, $btype); }
31161
31162 if ($arrcode === false) { $this->Error('Error in barcode string: '.$codestr); }
31163 if((($btype=='EAN13' || $btype=='ISBN' || $btype=='ISSN') && strlen($code) == 12) || ($btype=='UPCA' && strlen($code) == 11)
31164 || ($btype=='UPCE' && strlen($code) == 11) || ($btype=='EAN8' && strlen($code) == 7)) {
31165 $code .= $arrcode['checkdigit'];
31166 if (stristr($codestr,'-')) { $codestr .= '-' . $arrcode['checkdigit']; }
31167 else { $codestr .= $arrcode['checkdigit']; }
31168 }
31169 if ($btype == 'ISBN') { $codestr = 'ISBN '.$codestr; }
31170 if ($btype == 'ISSN') { $codestr = 'ISSN '.$codestr; }
31171
31172 if (empty($x)) {
31173 $x = $this->x;
31174 }
31175 if (empty($y)) {
31176 $y = $this->y;
31177 }
31178 // set foreground color
31179 $prevDrawColor = $this->DrawColor;
31180 $prevTextColor = $this->TextColor;
31181 $prevFillColor = $this->FillColor;
31182 $lw = $this->LineWidth;
31183 $this->SetLineWidth(0.01);
31184
31185 $size /= $k; // in case resized in a table
31186
31187 $xres = $arrcode['nom-X'] * $size;
31188 $llm = $arrcode['lightmL'] * $arrcode['nom-X'] * $size; // Left Light margin
31189 $rlm = $arrcode['lightmR'] * $arrcode['nom-X'] * $size; // Right Light margin
31190
31191 $bcw = ($arrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size
31192
31193 $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins
31194 $ow = $fbw + $paddingL + $paddingR; // Full overall width incl. user-defined padding
31195
31196 $fbwi = $fbw - 2; // Full barcode width incl. light margins - 2mm - for isbn string
31197
31198 // cf. http://www.gs1uk.org/downloads/bar_code/Bar coding getting it right.pdf
31199 $num_height = 3 * $size; // Height of numerals
31200 $fbh = $arrcode['nom-H'] * $size * $height; // Full barcode height incl. numerals
31201 $bch = $fbh - (1.5 * $size); // Barcode height of bars (3mm for numerals)
31202
31203 if (($btype=='EAN13' && $showtext) || $btype == 'ISSN' || $btype == 'ISBN') { // Add height for ISBN string + margin from top of bars
31204 $tisbnm = 1.5 * $size; // Top margin between isbn (if shown) & bars
31205 $codestr_fontsize = 2.1 * $size;
31206 $paddingT += $codestr_fontsize + $tisbnm ;
31207 }
31208 $oh = $fbh + $paddingT + $paddingB; // Full overall height incl. user-defined padding
31209
31210 // PRINT border background color
31211 $xpos = $x;
31212 $ypos = $y;
31213 if ($col) {
31214 $this->SetDColor($col);
31215 $this->SetTColor($col);
31216 }
31217 else {
31218 $this->SetDColor($this->ConvertColor(0));
31219 $this->SetTColor($this->ConvertColor(0));
31220 }
31221 if ($bgcol) {
31222 $this->SetFColor($bgcol);
31223 }
31224 else { $this->SetFColor($this->ConvertColor(255)); }
31225 if (!$bgcol && !$col) { // fn. called directly - not via HTML
31226 if ($border) { $fillb = 'DF'; } else { $fillb = 'F'; }
31227 $this->Rect($xpos, $ypos, $ow, $oh, $fillb);
31228 }
31229
31230
31231 // PRINT BARS
31232 $xpos = $x + $paddingL + $llm ;
31233 $ypos = $y + $paddingT;
31234 if ($col) { $this->SetFColor($col); }
31235 else { $this->SetFColor($this->ConvertColor(0)); }
31236 if ($arrcode !== false) {
31237 foreach ($arrcode["bcode"] AS $v) {
31238 $bw = ($v["w"] * $xres);
31239 if ($v["t"]) {
31240 // draw a vertical bar
31241 $this->Rect($xpos, $ypos, $bw, $bch, 'F');
31242 }
31243 $xpos += $bw;
31244 }
31245 }
31246
31247
31248 // print text
31249 $prevFontFamily = $this->FontFamily;
31250 $prevFontStyle = $this->FontStyle;
31251 $prevFontSizePt = $this->FontSizePt;
31252
31253 // ISBN string
31254 if (($btype=='EAN13' && $showtext) || $btype=='ISBN' || $btype=='ISSN') {
31255 if ($this->onlyCoreFonts) {
31256 $this->SetFont('chelvetica');
31257 }
31258 else {
31259 $this->SetFont('sans');
31260 }
31261
31262 if ($bgcol) { $this->SetFColor($bgcol); }
31263 else { $this->SetFColor($this->ConvertColor(255)); }
31264 $this->x = $x + $paddingL + 1; // 1mm left margin (cf. $fbwi above)
31265 // max width is $fbwi
31266 $loop = 0;
31267 while ( $loop == 0 ) {
31268 $this->SetFontSize($codestr_fontsize*1.4*_MPDFK, false); // don't write
31269 $sz = $this->GetStringWidth( $codestr );
31270 if ($sz > $fbwi)
31271 $codestr_fontsize -= 0.1;
31272 else
31273 $loop ++;
31274 }
31275 $this->SetFont('','',$codestr_fontsize*1.4*_MPDFK, true, true); // * 1.4 because font height is only 7/10 of given mm
31276 // WORD SPACING
31277 if ($fbwi > $sz) {
31278 $xtra = $fbwi - $sz;
31279 $charspacing = $xtra / (strlen($codestr)-1);
31280 if ($charspacing) { $this->_out(sprintf('BT %.3F Tc ET',$charspacing*_MPDFK)); }
31281 }
31282 $this->y = $y + $paddingT - ($codestr_fontsize ) - $tisbnm ;
31283 $this->Cell($fbw , $codestr_fontsize, $codestr);
31284 if ($charspacing) { $this->_out('BT 0 Tc ET'); }
31285 }
31286
31287
31288 // Bottom NUMERALS
31289 // mPDF 5.7.4
31290 if ($this->onlyCoreFonts) {
31291 $this->SetFont('ccourier');
31292 $fh = 1.3;
31293 }
31294 else {
31295 $this->SetFont('ocrb');
31296 $fh = 1.06;
31297 }
31298
31299 $charRO = '';
31300 if ($btype=='EAN13' || $btype=='ISBN' || $btype=='ISSN') {
31301 $outerfontsize = 3; // Inner fontsize = 3
31302 $outerp = $xres * 4;
31303 $innerp = $xres * 2.5;
31304 $textw = ($bcw*0.5) - $outerp - $innerp;
31305 $chars = 6; // number of numerals in each half
31306 $charLO = substr($code,0,1); // Left Outer
31307 $charLI = substr($code,1,6); // Left Inner
31308 $charRI = substr($code,7,6); // Right Inner
31309 if (!$supplement) $charRO = '>'; // Right Outer
31310 }
31311 else if ($btype=='UPCA') {
31312 $outerfontsize = 2.3; // Inner fontsize = 3
31313 $outerp = $xres * 10;
31314 $innerp = $xres * 2.5;
31315 $textw = ($bcw*0.5) - $outerp - $innerp;
31316 $chars = 5;
31317 $charLO = substr($code,0,1); // Left Outer
31318 $charLI = substr($code,1,5); // Left Inner
31319 $charRI = substr($code,6,5); // Right Inner
31320 $charRO = substr($code,11,1); // Right Outer
31321 }
31322 else if ($btype=='UPCE') {
31323 $outerfontsize = 2.3; // Inner fontsize = 3
31324 $outerp = $xres * 4;
31325 $innerp = 0;
31326 $textw = ($bcw*0.5) - $outerp - $innerp;
31327 $chars = 3;
31328 $upce_code = $arrcode['code'];
31329 $charLO = substr($code,0,1); // Left Outer
31330 $charLI = substr($upce_code,0,3); // Left Inner
31331 $charRI = substr($upce_code,3,3); // Right Inner
31332 $charRO = substr($code,11,1); // Right Outer
31333 }
31334 else if ($btype=='EAN8') {
31335 $outerfontsize = 3; // Inner fontsize = 3
31336 $outerp = $xres * 4;
31337 $innerp = $xres * 2.5;
31338 $textw = ($bcw*0.5) - $outerp - $innerp;
31339 $chars = 4;
31340 $charLO = '<'; // Left Outer
31341 $charLI = substr($code,0,4); // Left Inner
31342 $charRI = substr($code,4,4); // Right Inner
31343 if (!$supplement) $charRO = '>'; // Right Outer
31344 }
31345
31346 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
31347
31348 if (!$this->usingCoreFont) { $cw = $this->_getCharWidth($this->CurrentFont['cw'],32)*3*$fh*$size/1000; } // character width at 3mm
31349 else { $cw = 600*3*$fh*$size/1000; } // mPDF 5.7.4
31350
31351 // Outer left character
31352 $y_text = $y + $paddingT + $bch - ($num_height/2);
31353 $y_text_outer = $y + $paddingT + $bch - ($num_height*($outerfontsize/3)/2);
31354
31355 $this->x = $x + $paddingL - ($cw*($outerfontsize/3)*0.1); // 0.1 is correction as char does not fill full width;
31356 $this->y = $y_text_outer;
31357 $this->Cell($cw, $num_height, $charLO );
31358
31359 // WORD SPACING for inner chars
31360 $xtra = $textw - ($cw*$chars);
31361 $charspacing = $xtra / ($chars-1);
31362 if ($charspacing) { $this->_out(sprintf('BT %.3F Tc ET',$charspacing*_MPDFK)); }
31363
31364 if ($bgcol) { $this->SetFColor($bgcol); }
31365 else { $this->SetFColor($this->ConvertColor(255)); }
31366
31367 $this->SetFontSize(3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
31368
31369 // Inner left half characters
31370 $this->x = $x + $paddingL + $llm + $outerp;
31371 $this->y = $y_text;
31372 $this->Cell($textw, $num_height, $charLI , 0, 0, '', 1);
31373
31374 // Inner right half characters
31375 $this->x = $x + $paddingL + $llm + ($bcw*0.5) + $innerp;
31376 $this->y = $y_text;
31377 $this->Cell($textw, $num_height, $charRI , 0, 0, '', 1);
31378
31379 if ($charspacing) { $this->_out('BT 0 Tc ET'); }
31380
31381 // Outer Right character
31382 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
31383
31384 $this->x = $x + $paddingL + $llm + $bcw + $rlm - ($cw*($outerfontsize/3)*0.9); // 0.9 is correction as char does not fill full width
31385 $this->y = $y_text_outer;
31386 $this->Cell($cw*($outerfontsize/3), $num_height, $charRO , 0, 0, 'R');
31387
31388 if ($supplement) { // EAN-2 or -5 Supplement
31389 // PRINT BARS
31390 $supparrcode = $this->barcode->getBarcodeArray($supplement_code, 'EAN'.$supplement);
31391 if ($supparrcode === false) { $this->Error('Error in barcode string (supplement): '.$codestr.' '.$supplement_code); }
31392 if(strlen($supplement_code) != $supplement) {
31393 $this->Error('Barcode supplement incorrect: '.$supplement_code);
31394 }
31395 $llm = $fbw - (($arrcode['lightmR'] - $supparrcode['sepM']) * $arrcode['nom-X'] * $size); // Left Light margin
31396 $rlm = $arrcode['lightmR'] * $arrcode['nom-X'] * $size; // Right Light margin
31397
31398 $bcw = ($supparrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size
31399
31400 $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins
31401 $ow = $fbw + $paddingL + $paddingR; // Full overall width incl. user-defined padding
31402 $bch = $fbh - (1.5 * $size) - ($num_height + 0.5); // Barcode height of bars (3mm for numerals)
31403
31404 $xpos = $x + $paddingL + $llm ;
31405 $ypos = $y + $paddingT + $num_height + 0.5;
31406 if ($col) { $this->SetFColor($col); }
31407 else { $this->SetFColor($this->ConvertColor(0)); }
31408 if ($supparrcode !== false) {
31409 foreach ($supparrcode["bcode"] AS $v) {
31410 $bw = ($v["w"] * $xres);
31411 if ($v["t"]) {
31412 // draw a vertical bar
31413 $this->Rect($xpos, $ypos, $bw, $bch, 'F');
31414 }
31415 $xpos += $bw;
31416 }
31417 }
31418
31419 // Characters
31420 if ($bgcol) { $this->SetFColor($bgcol); }
31421 else { $this->SetFColor($this->ConvertColor(255)); }
31422 $this->SetFontSize(3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
31423 $this->x = $x + $paddingL + $llm;
31424 $this->y = $y + $paddingT;
31425 $this->Cell($bcw, $num_height, $supplement_code, 0, 0, 'C');
31426
31427 // Outer Right character (light margin)
31428 $this->SetFontSize(($outerfontsize/3)*3*$fh*$size*_MPDFK); // 3mm numerals (FontSize is larger to account for space above/below characters)
31429 $this->x = $x + $paddingL + $llm + $bcw + $rlm - ($cw*0.9); // 0.9 is correction as char does not fill full width
31430 $this->y = $y + $paddingT;
31431 $this->Cell($cw*($outerfontsize/3), $num_height, '>', 0, 0, 'R');
31432 }
31433
31434
31435
31436 // Restore **************
31437 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt);
31438 $this->DrawColor = $prevDrawColor;
31439 $this->TextColor = $prevTextColor;
31440 $this->FillColor = $prevFillColor;
31441 $this->SetLineWidth($lw);
31442 $this->SetY($y);
31443 }
31444
31445
31446
31447 // ====================================================
31448 // POSTAL and OTHER barcodes
31449 function WriteBarcode2($code, $x='', $y='', $size=1, $height=1, $bgcol=false, $col=false, $btype='IMB', $print_ratio='', $k=1) {
31450 if (empty($code)) { return; }
31451 if (!class_exists('PDFBarcode', false)) {
31452 include(_MPDF_PATH.'classes/barcode.php');
31453 }
31454 $this->barcode = new PDFBarcode();
31455 $arrcode = $this->barcode->getBarcodeArray($code, $btype, $print_ratio);
31456
31457 if ($arrcode === false) { $this->Error('Error in barcode string: '.$code); }
31458 if (empty($x)) { $x = $this->x; }
31459 if (empty($y)) { $y = $this->y; }
31460 $prevDrawColor = $this->DrawColor;
31461 $prevTextColor = $this->TextColor;
31462 $prevFillColor = $this->FillColor;
31463 $lw = $this->LineWidth;
31464 $this->SetLineWidth(0.01);
31465 $size /= $k; // in case resized in a table
31466 $xres = $arrcode['nom-X'] * $size;
31467
31468 if ($btype == 'IMB' || $btype == 'RM4SCC' || $btype == 'KIX' || $btype == 'POSTNET' || $btype == 'PLANET') {
31469 $llm = $arrcode['quietL'] / $k; // Left Quiet margin
31470 $rlm = $arrcode['quietR'] / $k; // Right Quiet margin
31471 $tlm = $blm = $arrcode['quietTB'] / $k;
31472 $height=1; // Overrides
31473 }
31474 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'))) {
31475 $llm = $arrcode['lightmL'] * $xres; // Left Quiet margin
31476 $rlm = $arrcode['lightmR'] * $xres; // Right Quiet margin
31477 $tlm = $blm = $arrcode['lightTB'] * $xres * $height;
31478 }
31479
31480
31481 $bcw = ($arrcode["maxw"] * $xres);
31482 $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins
31483
31484 $bch = ($arrcode["nom-H"] * $size * $height);
31485 $fbh = $bch + $tlm + $blm; // Full barcode height
31486
31487 // PRINT border background color
31488 $xpos = $x;
31489 $ypos = $y;
31490 if ($col) {
31491 $this->SetDColor($col);
31492 $this->SetTColor($col);
31493 }
31494 else {
31495 $this->SetDColor($this->ConvertColor(0));
31496 $this->SetTColor($this->ConvertColor(0));
31497 }
31498 if ($bgcol) {
31499 $this->SetFColor($bgcol);
31500 }
31501 else { $this->SetFColor($this->ConvertColor(255)); }
31502
31503 // PRINT BARS
31504 if ($col) { $this->SetFColor($col); }
31505 else { $this->SetFColor($this->ConvertColor(0)); }
31506 $xpos = $x + $llm ;
31507
31508 if ($arrcode !== false) {
31509 foreach ($arrcode["bcode"] AS $v) {
31510 $bw = ($v["w"] * $xres);
31511 if ($v["t"]) {
31512 $ypos = $y + $tlm + ($bch * $v['p'] / $arrcode['maxh']);
31513 $this->Rect($xpos, $ypos, $bw, ($v['h'] * $bch / $arrcode['maxh']), 'F');
31514 }
31515 $xpos += $bw;
31516 }
31517 }
31518
31519 // PRINT BEARER BARS
31520 if ($btype == 'I25B' || $btype == 'I25B+') {
31521 $this->Rect($x, $y, $fbw, ($arrcode['lightTB'] * $xres * $height), 'F');
31522 $this->Rect($x, $y+$tlm+$bch, $fbw, ($arrcode['lightTB'] * $xres * $height), 'F');
31523 }
31524
31525 // Restore **************
31526 $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt);
31527 $this->DrawColor = $prevDrawColor;
31528 $this->TextColor = $prevTextColor;
31529 $this->FillColor = $prevFillColor;
31530 $this->SetLineWidth($lw);
31531 $this->SetY($y);
31532 }
31533
31534 /*-- END BARCODES --*/
31535
31536 // ====================================================
31537 // ====================================================
31538
31539 function StartTransform($returnstring=false) {
31540 if ($returnstring) { return('q'); }
31541 else { $this->_out('q'); }
31542 }
31543 function StopTransform($returnstring=false) {
31544 if ($returnstring) { return('Q'); }
31545 else { $this->_out('Q'); }
31546 }
31547 function transformScale($s_x, $s_y, $x='', $y='', $returnstring=false) {
31548 if ($x === '') {
31549 $x=$this->x;
31550 }
31551 if ($y === '') {
31552 $y=$this->y;
31553 }
31554 if (($s_x == 0) OR ($s_y == 0)) {
31555 $this->Error('Please do not use values equal to zero for scaling');
31556 }
31557 $y = ($this->h - $y) * _MPDFK;
31558 $x *= _MPDFK;
31559 //calculate elements of transformation matrix
31560 $s_x /= 100;
31561 $s_y /= 100;
31562 $tm[0] = $s_x;
31563 $tm[1] = 0;
31564 $tm[2] = 0;
31565 $tm[3] = $s_y;
31566 $tm[4] = $x * (1 - $s_x);
31567 $tm[5] = $y * (1 - $s_y);
31568 //scale the coordinate system
31569 if ($returnstring) { return($this->_transform($tm, true)); }
31570 else { $this->_transform($tm); }
31571 }
31572 function transformTranslate($t_x, $t_y, $returnstring=false) {
31573 //calculate elements of transformation matrix
31574 $tm[0] = 1;
31575 $tm[1] = 0;
31576 $tm[2] = 0;
31577 $tm[3] = 1;
31578 $tm[4] = $t_x * _MPDFK;
31579 $tm[5] = -$t_y * _MPDFK;
31580 //translate the coordinate system
31581 if ($returnstring) { return($this->_transform($tm, true)); }
31582 else { $this->_transform($tm); }
31583 }
31584 function transformRotate($angle, $x='', $y='', $returnstring=false) {
31585 if ($x === '') {
31586 $x=$this->x;
31587 }
31588 if ($y === '') {
31589 $y=$this->y;
31590 }
31591 $angle = -$angle;
31592 $y = ($this->h - $y) * _MPDFK;
31593 $x *= _MPDFK;
31594 //calculate elements of transformation matrix
31595 $tm[0] = cos(deg2rad($angle));
31596 $tm[1] = sin(deg2rad($angle));
31597 $tm[2] = -$tm[1];
31598 $tm[3] = $tm[0];
31599 $tm[4] = $x + $tm[1] * $y - $tm[0] * $x;
31600 $tm[5] = $y - $tm[0] * $y - $tm[1] * $x;
31601 //rotate the coordinate system around ($x,$y)
31602 if ($returnstring) { return($this->_transform($tm, true)); }
31603 else { $this->_transform($tm); }
31604 }
31605 // mPDF 5.7.3 TRANSFORMS
31606 function transformSkew($angle_x, $angle_y, $x='', $y='', $returnstring=false) {
31607 if ($x === '') {
31608 $x = $this->x;
31609 }
31610 if ($y === '') {
31611 $y = $this->y;
31612 }
31613 $angle_x = -$angle_x;
31614 $angle_y = -$angle_y;
31615 $x *= _MPDFK;
31616 $y = ($this->h - $y) * _MPDFK;
31617 //calculate elements of transformation matrix
31618 $tm = array();
31619 $tm[0] = 1;
31620 $tm[1] = tan(deg2rad($angle_y));
31621 $tm[2] = tan(deg2rad($angle_x));
31622 $tm[3] = 1;
31623 $tm[4] = -$tm[2] * $y;
31624 $tm[5] = -$tm[1] * $x;
31625 //skew the coordinate system
31626 if ($returnstring) { return($this->_transform($tm, true)); }
31627 else { $this->_transform($tm); }
31628 }
31629 function _transform($tm, $returnstring=false) {
31630 if ($returnstring) { return(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5])); }
31631 else { $this->_out(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5])); }
31632 }
31633
31634
31635
31636 /*-- INDIC --*/
31637 // INDIC ============================
31638 // This conversion can only be done when font is set
31639 function ConvertIndic(&$str) {
31640 if (preg_match('/^ind_([a-z]{2})_/',$this->currentfontfamily, $m)) {
31641 if (!class_exists('indic', false)) { include(_MPDF_PATH.'classes/indic.php'); }
31642 if (empty($this->indic)) { $this->indic = new indic($this); }
31643 $earr = $this->UTF8StringToArray($str, false);
31644 $str = $this->indic->substituteIndic($earr, $m[1], $this->currentfontfamily);
31645 }
31646 }
31647 /*-- END INDIC --*/
31648
31649 // AUTOFONT =========================
31650 function AutoFont($html) {
31651 if ($this->onlyCoreFonts) { return $html; }
31652 $this->useLang = true;
31653 if ($this->autoFontGroupSize == 1) { $extra = $this->pregASCIIchars1; }
31654 else if ($this->autoFontGroupSize == 3) { $extra = $this->pregASCIIchars3; }
31655 else { $extra = $this->pregASCIIchars2; }
31656 $n = '';
31657 $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
31658 foreach($a as $i => $e) {
31659 if($i%2==0) {
31660 $e = strcode2utf($e);
31661 $e = $this->lesser_entity_decode($e);
31662
31663 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31664 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31665
31666 /*-- CJK-FONTS --*/
31667 if ($this->autoFontGroups & AUTOFONT_CJK) {
31668 $e = preg_replace_callback("/([".$this->pregCJKchars .$extra."]*[".$this->pregCJKchars ."][".$this->pregCJKchars .$extra."]*)/u", array($this, 'replaceCJKPregCallback'), $e ); // mPDF 5.7+
31669 }
31670 /*-- END CJK-FONTS --*/
31671
31672 /*-- RTL --*/
31673 if ($this->autoFontGroups & AUTOFONT_RTL) {
31674 // HEBREW
31675 $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);
31676 // All Arabic
31677 $e = preg_replace_callback("/([".$this->pregARABICchars .$extra."]*[".$this->pregARABICchars ."][".$this->pregARABICchars .$extra."]*)/u", array($this, 'replaceArabicPregCallback'), $e ); // mPDF 5.7+
31678 }
31679 /*-- END RTL --*/
31680
31681 /*-- INDIC --*/
31682 // INDIC
31683 if ($this->autoFontGroups & AUTOFONT_INDIC) {
31684 // Bengali
31685 $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);
31686 // Devanagari (= script for Hindi, Nepali + Sindhi)
31687 $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);
31688 // Gujarati
31689 $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);
31690 // Malayalam
31691 $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);
31692 // Kannada
31693 $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);
31694 // Oriya
31695 $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);
31696 // Punjabi ?= Gurmuhki
31697 $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);
31698 // Tamil
31699 $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);
31700 // Telugu
31701 $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);
31702 }
31703 /*-- END INDIC --*/
31704
31705
31706 if ($this->autoFontGroups & AUTOFONT_THAIVIET) {
31707 // THAI
31708 $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);
31709 // Vietnamese
31710 $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);
31711 }
31712
31713 $e = preg_replace('/[&]/','&amp;',$e);
31714 $e = preg_replace('/[<]/','&lt;',$e);
31715 $e = preg_replace('/[>]/','&gt;',$e);
31716 $e = preg_replace("/(\xef\xbf\xb0span lang=\"([a-z\-A-Z]{2,5})\"\xef\xbf\xb1)\s+/",' \\1',$e);
31717 $e = preg_replace("/[ ]+(\xef\xbf\xb0\/span\xef\xbf\xb1)/",'\\1 ',$e);
31718
31719 $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);
31720
31721 $e = preg_replace("/\xef\xbf\xb0/",'<',$e);
31722 $e = preg_replace("/\xef\xbf\xb1/",'>',$e);
31723
31724 $a[$i] = $e;
31725 }
31726 else {
31727 $a[$i] = '<'.$e.'>';
31728 }
31729 }
31730 $n = implode('',$a);
31731 return $n;
31732 }
31733
31734
31735 /*-- CJK-FONTS --*/
31736 function replaceCJK($str) {
31737 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31738 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31739 if (preg_match("/[".$this->pregUHCchars."]/u", $str)) {
31740 return "\xef\xbf\xb0span lang=\"ko\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31741 }
31742 else if (preg_match("/[".$this->pregSJISchars."]/u", $str)) {
31743 return "\xef\xbf\xb0span lang=\"ja\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31744 }
31745 // if in Unicode Plane 2, probably HKCS (incl in BIG5) if not Japanese
31746 else if (preg_match("/[\x{20000}-\x{2FFFF}]/u", $str)) {
31747 return "\xef\xbf\xb0span lang=\"zh-HK\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31748 }
31749 else{
31750 return "\xef\xbf\xb0span lang=\"zh-CN\"\xef\xbf\xb1" . $str ."\xef\xbf\xb0/span\xef\xbf\xb1";
31751 }
31752 return $str;
31753 }
31754
31755 // mPDF 5.7+
31756 function replaceCJKPregCallback($matches) {
31757 return $this->replaceCJK(stripslashes($matches[1]));
31758 }
31759 /*-- END CJK-FONTS --*/
31760
31761 /*-- RTL --*/
31762 function replaceArabic($str) {
31763 // PASHTO, SINDHI, URDU, ARABIC, PERSIAN
31764 $persian = "\x{067E}\x{0686}\x{0698}\x{06AF}";
31765
31766 $urdu = "\x{0679}\x{0688}\x{0691}\x{06BA}\x{06BE}\x{06C1}\x{06D2}";
31767 $pashto = "\x{067C}\x{0681}\x{0685}\x{0689}\x{0693}\x{0696}\x{069A}\x{06BC}\x{06D0}"; // ? and U+06AB, U+06CD
31768 $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}";
31769 // Use U=FFF0 and U+FFF1 to mark start and end of span tags to prevent nesting occurring
31770 // "\xef\xbf\xb0" ##lthtmltag## "\xef\xbf\xb1" ##gthtmltag##
31771
31772 if (preg_match("/[".$this->pregNonARABICchars ."]/u", $str) ) {
31773 if (preg_match("/[".$sindhi ."]/u", $str) ) {
31774 return "\xef\xbf\xb0span lang=\"sd\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31775 }
31776 else if (preg_match("/[".$urdu ."]/u", $str) ) {
31777 return "\xef\xbf\xb0span lang=\"ur\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31778 }
31779 else if (preg_match("/[".$pashto ."]/u", $str) ) {
31780 return "\xef\xbf\xb0span lang=\"ps\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31781 }
31782 else if (preg_match("/[".$persian ."]/u", $str) ) {
31783 return "\xef\xbf\xb0span lang=\"fa\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31784 }
31785 else {
31786 return "\xef\xbf\xb0span lang=\"ar\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31787 }
31788 }
31789 if (preg_match("/[".$persian ."]/u", $str) ) {
31790 return "\xef\xbf\xb0span lang=\"fa\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31791 }
31792 else {
31793 return "\xef\xbf\xb0span lang=\"ar\"\xef\xbf\xb1".$str."\xef\xbf\xb0/span\xef\xbf\xb1";
31794 }
31795 return $str;
31796 }
31797
31798 // mPDF 5.7+
31799 function replaceArabicPregCallback($matches) {
31800 return $this->replaceArabic(stripslashes($matches[1]));
31801 }
31802
31803 // ARABIC ===========================
31804 // mPDF 5.4.08
31805 function InitArabic() {
31806
31807 // JOIN TO FOLLOWING LETTER IN LOGICAL ORDER (i.e. AS INITIAL)
31808 $this->arabPrevLink = "";
31809 // U+060c; U+061b; U+061f; U+0626; U+0628;
31810 $this->arabPrevLink .= "\xd8\x8c\xd8\x9b\xd8\x9f\xd8\xa6\xd8\xa8";
31811 // U+062a; U+062b; U+062c; U+062d; U+062e;
31812 $this->arabPrevLink .= "\xd8\xaa\xd8\xab\xd8\xac\xd8\xad\xd8\xae";
31813 // U+0633; U+0634; U+0635; U+0636; U+0637; U+0638; U+0639; U+063a;
31814 $this->arabPrevLink .= "\xd8\xb3\xd8\xb4\xd8\xb5\xd8\xb6\xd8\xb7\xd8\xb8\xd8\xb9\xd8\xba";
31815 // U+0640; U+0641; U+0642; U+0643; U+0644; U+0645; U+0646; U+0647; U+0649; U+064a;
31816 $this->arabPrevLink .= "\xd9\x80\xd9\x81\xd9\x82\xd9\x83\xd9\x84\xd9\x85\xd9\x86\xd9\x87\xd9\x89\xd9\x8a";
31817 // U+0678; U+0679; U+067a; U+067b; U+067c; U+067d; U+067e; U+067f;
31818 $this->arabPrevLink .= "\xd9\xb8\xd9\xb9\xd9\xba\xd9\xbb\xd9\xbc\xd9\xbd\xd9\xbe\xd9\xbf";
31819 // U+0680; U+0681; U+0682; U+0683; U+0684; U+0685; U+0686; U+0687;
31820 $this->arabPrevLink .= "\xda\x80\xda\x81\xda\x82\xda\x83\xda\x84\xda\x85\xda\x86\xda\x87";
31821 // U+069a; U+069b; U+069c; U+069d; U+069e; U+069f;
31822 $this->arabPrevLink .= "\xda\x9a\xda\x9b\xda\x9c\xda\x9d\xda\x9e\xda\x9f";
31823 // U+06a0; U+06a1; U+06a2; U+06a3; U+06a4; U+06a5; U+06a6; U+06A7; U+06A8;
31824 $this->arabPrevLink .= "\xda\xa0\xda\xa1\xda\xa2\xda\xa3\xda\xa4\xda\xa5\xda\xa6\xda\xa7\xda\xa8";
31825 // U+06a9; U+06aa; U+06ab; U+06ac; U+06ad; U+06ae; U+06af;
31826 $this->arabPrevLink .= "\xda\xa9\xda\xaa\xda\xab\xda\xac\xda\xad\xda\xae\xda\xaf";
31827 // U+06b0; U+06b1; U+06b2; U+06b3; U+06b4; U+06b5; U+06b6; U+06b7; U+06b8; U+06b9;
31828 $this->arabPrevLink .= "\xda\xb0\xda\xb1\xda\xb2\xda\xb3\xda\xb4\xda\xb5\xda\xb6\xda\xb7\xda\xb8\xda\xb9";
31829 // U+06ba; U+06bb; U+06bc; U+06be; U+06bf;
31830 $this->arabPrevLink .= "\xda\xba\xda\xbb\xda\xbc\xda\xbe\xda\xbf";
31831 // U+06c1; U+06cc; U+06ce; U+06d0; U+06d1;
31832 $this->arabPrevLink .= "\xdb\x81\xdb\x8c\xdb\x8e\xdb\x90\xdb\x91";
31833
31834
31835
31836
31837 // JOIN TO PREVIOUS LETTER IN LOGICAL ORDER (i.e. AS FINAL FORM)
31838 $this->arabNextLink = "";
31839 // U+0622; U+0623; U+0624; U+0625; U+0626; U+0627; U+0628; U+0629;
31840 $this->arabNextLink .= "\xd8\xa2\xd8\xa3\xd8\xa4\xd8\xa5\xd8\xa6\xd8\xa7\xd8\xa8\xd8\xa9";
31841 // U+062A; U+062B; U+062C; U+062D; U+062E; U+062F;
31842 $this->arabNextLink .= "\xd8\xaa\xd8\xab\xd8\xac\xd8\xad\xd8\xae\xd8\xaf";
31843 // U+0630; U+0631; U+0632; U+0633; U+0634; U+0635; U+0636; U+0637; U+0638; U+0639; U+063A;
31844 $this->arabNextLink .= "\xd8\xb0\xd8\xb1\xd8\xb2\xd8\xb3\xd8\xb4\xd8\xb5\xd8\xb6\xd8\xb7\xd8\xb8\xd8\xb9\xd8\xba";
31845 // U+0640; U+0641; U+0642; U+0643; U+0644; U+0645; U+0646; U+0647; U+0648; U+0649; U+064A;
31846 $this->arabNextLink .= "\xd9\x80\xd9\x81\xd9\x82\xd9\x83\xd9\x84\xd9\x85\xd9\x86\xd9\x87\xd9\x88\xd9\x89\xd9\x8a";
31847 // U+0671; U+0672; U+0675; U+0676; U+0677; U+0678; U+0679;
31848 $this->arabNextLink .= "\xd9\xb1\xd9\xb2\xd9\xb5\xd9\xb6\xd9\xb7\xd9\xb8\xd9\xb9";
31849 // U+067A; U+067B; U+067C; U+067D; U+067E; U+067F;
31850 $this->arabNextLink .= "\xd9\xba\xd9\xbb\xd9\xbc\xd9\xbd\xd9\xbe\xd9\xbf";
31851 // U+0680; U+0681; U+0682; U+0683; U+0684; U+0685; U+0686; U+0687; U+0688; U+0689;
31852 $this->arabNextLink .= "\xda\x80\xda\x81\xda\x82\xda\x83\xda\x84\xda\x85\xda\x86\xda\x87\xda\x88\xda\x89";
31853 // U+068A; U+068B; U+068C; U+068D; U+068F;U+068F;
31854 $this->arabNextLink .= "\xda\x8a\xda\x8b\xda\x8c\xda\x8d\xda\x8e\xda\x8f";
31855 // U+0690; U+0691; U+0692; U+0693; U+0694; U+0695; U+0696; U+0697; U+0698; U+0699;
31856 $this->arabNextLink .= "\xda\x90\xda\x91\xda\x92\xda\x93\xda\x94\xda\x95\xda\x96\xda\x97\xda\x98\xda\x99";
31857 // U+069A; U+069B; U+069C; U+069D; U+069E; U+069F;
31858 $this->arabNextLink .= "\xda\x9a\xda\x9b\xda\x9c\xda\x9d\xda\x9e\xda\x9f";
31859 // U+06A0; U+06A1; U+06A2; U+06A3; U+06A4; U+06A5; U+06A6; U+06A7; U+06A8; U+06A9;
31860 $this->arabNextLink .= "\xda\xa0\xda\xa1\xda\xa2\xda\xa3\xda\xa4\xda\xa5\xda\xa6\xda\xa7\xda\xa8\xda\xa9";
31861 // U+06AA; U+06AB; U+06AC; U+06AD; U+06AE; U+06AF;
31862 $this->arabNextLink .= "\xda\xaa\xda\xab\xda\xac\xda\xad\xda\xae\xda\xaf";
31863 // U+06B0; U+06B1; U+06B2; U+06B3; U+06B4; U+06B5; U+06B6; U+06B7; U+06B8; U+06B9;
31864 $this->arabNextLink .= "\xda\xb0\xda\xb1\xda\xb2\xda\xb3\xda\xb4\xda\xb5\xda\xb6\xda\xb7\xda\xb8\xda\xb9";
31865 // U+06BA; U+06BB; U+06BC; U+06BE; U+06BF;
31866 $this->arabNextLink .= "\xda\xba\xda\xbb\xda\xbc\xda\xbe\xda\xbf";
31867 // U+06C0; U+06C1; U+06C2; U+06C3; U+06C4; U+06C5; U+06C6; U+06C7; U+06C8; U+06C9;
31868 $this->arabNextLink .= "\xdb\x80\xdb\x81\xdb\x82\xdb\x83\xdb\x84\xdb\x85\xdb\x86\xdb\x87\xdb\x88\xdb\x89";
31869 // U+06CA; U+06CB; U+06CC; U+06CD; U+06CE; U+06CF;
31870 $this->arabNextLink .= "\xdb\x8a\xdb\x8b\xdb\x8c\xdb\x8d\xdb\x8e\xdb\x8f";
31871 // U+06D0; U+06d1; U+06D2; U+06D3;
31872 $this->arabNextLink .= "\xdb\x90\xdb\x91\xdb\x92\xdb\x93";
31873
31874
31875 // VOWELS ++
31876
31877 // U+064b U+064c; U+064d; U+064e; U+064f; U+0650; U+0651; U+0652;
31878 $this->arabVowels = "\xd9\x8b\xd9\x8c\xd9\x8d\xd9\x8e\xd9\x8f\xd9\x90\xd9\x91\xd9\x92";
31879
31880 // Added chars that may not be vowels but should not interrupt joining
31881 // U+0670; U+0653;
31882 $this->arabVowels .= "\xd9\xb0\xd9\x93";
31883 // ? should also add - U+615, 616, 617-61A, 653-65E, 6D6-6DC, 6DF-6E4, 6E7, 6E8, 6EA-6ED
31884
31885
31886
31887 // ISOLATED FORM :: FINAL :: INITIAL :: MEDIAL
31888 // FB** - FE** = Arabic presentation Forms
31889 // F5** F6** F7** = Private use area used by unAGlyphs in mPDF
31890 $this->arabGlyphs = array(
31891 "\xd8\x8c"=>array("\xd8\x8c", "\xd8\x8c", "\xd8\x8c", "\xd8\x8c"), /* 060C, 060C, 060C, 060C */
31892 "\xd8\x9b"=>array("\xd8\x9b", "\xd8\x9b", "\xd8\x9b", "\xd8\x9b"), /* 061B, 061B, 061B, 061B */
31893 "\xd8\x9f"=>array("\xd8\x9f", "\xd8\x9f", "\xd8\x9f", "\xd8\x9f"), /* 061F, 061F, 061F, 061F */
31894 "\xd8\xa1"=>array("\xd8\xa1", "\xd8\xa1", "\xd8\xa1", "\xd8\xa1"), /* 0621, 0621, 0621, 0621 */
31895 "\xd8\xa2"=>array("\xd8\xa2", "\xef\xba\x82", "\xd8\xa2", "\xef\xba\x82"), /* 0622, FE82, 0622, FE82 */
31896 "\xd8\xa3"=>array("\xd8\xa3", "\xef\xba\x84", "\xd8\xa3", "\xef\xba\x84"), /* 0623, FE84, 0623, FE84 */
31897 "\xd8\xa4"=>array("\xd8\xa4", "\xef\xba\x86", "\xd8\xa4", "\xef\xba\x86"), /* 0624, FE86, 0624, FE86 */
31898 "\xd8\xa5"=>array("\xd8\xa5", "\xef\xba\x88", "\xd8\xa5", "\xef\xba\x88"), /* 0625, FE88, 0625, FE88 */
31899 "\xd8\xa6"=>array("\xd8\xa6", "\xef\xba\x8a", "\xef\xba\x8b", "\xef\xba\x8c"), /* 0626, FE8A, FE8B, FE8C */
31900 "\xd8\xa7"=>array("\xd8\xa7", "\xef\xba\x8e", "\xd8\xa7", "\xef\xba\x8e"), /* 0627, FE8E, 0627, FE8E */
31901 "\xd8\xa8"=>array("\xd8\xa8", "\xef\xba\x90", "\xef\xba\x91", "\xef\xba\x92"), /* 0628, FE90, FE91, FE92 */
31902 "\xd8\xa9"=>array("\xd8\xa9", "\xef\xba\x94", "\xd8\xa9", "\xef\xba\x94"), /* 0629, FE94, 0629, FE94 */
31903 "\xd8\xaa"=>array("\xd8\xaa", "\xef\xba\x96", "\xef\xba\x97", "\xef\xba\x98"), /* 062A, FE96, FE97, FE98 */
31904 "\xd8\xab"=>array("\xd8\xab", "\xef\xba\x9a", "\xef\xba\x9b", "\xef\xba\x9c"), /* 062B, FE9A, FE9B, FE9C */
31905 "\xd8\xac"=>array("\xd8\xac", "\xef\xba\x9e", "\xef\xba\x9f", "\xef\xba\xa0"), /* 062C, FE9E, FE9F, FEA0 */
31906 "\xd8\xad"=>array("\xd8\xad", "\xef\xba\xa2", "\xef\xba\xa3", "\xef\xba\xa4"), /* 062D, FEA2, FEA3, FEA4 */
31907 "\xd8\xae"=>array("\xd8\xae", "\xef\xba\xa6", "\xef\xba\xa7", "\xef\xba\xa8"), /* 062E, FEA6, FEA7, FEA8 */
31908 "\xd8\xaf"=>array("\xd8\xaf", "\xef\xba\xaa", "\xd8\xaf", "\xef\xba\xaa"), /* 062F, FEAA, 062F, FEAA */
31909 "\xd8\xb0"=>array("\xd8\xb0", "\xef\xba\xac", "\xd8\xb0", "\xef\xba\xac"), /* 0630, FEAC, 0630, FEAC */
31910 "\xd8\xb1"=>array("\xd8\xb1", "\xef\xba\xae", "\xd8\xb1", "\xef\xba\xae"), /* 0631, FEAE, 0631, FEAE */
31911 "\xd8\xb2"=>array("\xd8\xb2", "\xef\xba\xb0", "\xd8\xb2", "\xef\xba\xb0"), /* 0632, FEB0, 0632, FEB0 */
31912 "\xd8\xb3"=>array("\xd8\xb3", "\xef\xba\xb2", "\xef\xba\xb3", "\xef\xba\xb4"), /* 0633, FEB2, FEB3, FEB4 */
31913 "\xd8\xb4"=>array("\xd8\xb4", "\xef\xba\xb6", "\xef\xba\xb7", "\xef\xba\xb8"), /* 0634, FEB6, FEB7, FEB8 */
31914 "\xd8\xb5"=>array("\xd8\xb5", "\xef\xba\xba", "\xef\xba\xbb", "\xef\xba\xbc"), /* 0635, FEBA, FEBB, FEBC */
31915 "\xd8\xb6"=>array("\xd8\xb6", "\xef\xba\xbe", "\xef\xba\xbf", "\xef\xbb\x80"), /* 0636, FEBE, FEBF, FEC0 */
31916 "\xd8\xb7"=>array("\xd8\xb7", "\xef\xbb\x82", "\xef\xbb\x83", "\xef\xbb\x84"), /* 0637, FEC2, FEC3, FEC4 */
31917 "\xd8\xb8"=>array("\xd8\xb8", "\xef\xbb\x86", "\xef\xbb\x87", "\xef\xbb\x88"), /* 0638, FEC6, FEC7, FEC8 */
31918 "\xd8\xb9"=>array("\xd8\xb9", "\xef\xbb\x8a", "\xef\xbb\x8b", "\xef\xbb\x8c"), /* 0639, FECA, FECB, FECC */
31919 "\xd8\xba"=>array("\xd8\xba", "\xef\xbb\x8e", "\xef\xbb\x8f", "\xef\xbb\x90"), /* 063A, FECE, FECF, FED0 */
31920 "\xd9\x80"=>array("\xd9\x80", "\xd9\x80", "\xd9\x80", "\xd9\x80"), /* 0640, 0640, 0640, 0640 */
31921 "\xd9\x81"=>array("\xd9\x81", "\xef\xbb\x92", "\xef\xbb\x93", "\xef\xbb\x94"), /* 0641, FED2, FED3, FED4 */
31922 "\xd9\x82"=>array("\xd9\x82", "\xef\xbb\x96", "\xef\xbb\x97", "\xef\xbb\x98"), /* 0642, FED6, FED7, FED8 */
31923 "\xd9\x83"=>array("\xd9\x83", "\xef\xbb\x9a", "\xef\xbb\x9b", "\xef\xbb\x9c"), /* 0643, FEDA, FEDB, FEDC */
31924 "\xd9\x84"=>array("\xd9\x84", "\xef\xbb\x9e", "\xef\xbb\x9f", "\xef\xbb\xa0"), /* 0644, FEDE, FEDF, FEE0 */
31925 "\xd9\x85"=>array("\xd9\x85", "\xef\xbb\xa2", "\xef\xbb\xa3", "\xef\xbb\xa4"), /* 0645, FEE2, FEE3, FEE4 */
31926 "\xd9\x86"=>array("\xd9\x86", "\xef\xbb\xa6", "\xef\xbb\xa7", "\xef\xbb\xa8"), /* 0646, FEE6, FEE7, FEE8 */
31927 "\xd9\x87"=>array("\xd9\x87", "\xef\xbb\xaa", "\xef\xbb\xab", "\xef\xbb\xac"), /* 0647, FEEA, FEEB, FEEC */
31928 "\xd9\x88"=>array("\xd9\x88", "\xef\xbb\xae", "\xd9\x88", "\xef\xbb\xae"), /* 0648, FEEE, 0648, FEEE */
31929
31930 /* 0649 Alef Maksura should only appear at end of word (in Arabic) So Initial and medial are shown as isolated/final */
31931 "\xd9\x89"=>array("\xd9\x89", "\xef\xbb\xb0", "\xd9\x89", "\xef\xbb\xb0"), /* 0649, FEF0, 0649, FEF0 */
31932
31933 /* 0649 Alef Maksura Initial and Medial forms as given in Unicode FBE8 and FBE9 for Uighur Kazakh (not in some fonts) */
31934 "\xd9\x89"=>array("\xd9\x89", "\xef\xbb\xb0", "\xef\xaf\xa8", "\xef\xaf\xa9"), /* 0649, FEF0, FBE8, FBE9 not in most fonts */
31935
31936 "\xd9\x8a"=>array("\xd9\x8a", "\xef\xbb\xb2", "\xef\xbb\xb3", "\xef\xbb\xb4"), /* 064A, FEF2, FEF3, FEF4 */
31937 "\xd9\x8b"=>array("\xd9\x8b", "\xd9\x8b", "\xd9\x8b", "\xd9\x8b"), /* 064B, 064B, 064B, 064B */
31938 "\xd9\x8c"=>array("\xd9\x8c", "\xd9\x8c", "\xd9\x8c", "\xd9\x8c"), /* 064C, 064C, 064C, 064C */
31939 "\xd9\x8d"=>array("\xd9\x8d", "\xd9\x8d", "\xd9\x8d", "\xd9\x8d"), /* 064D, 064D, 064D, 064D */
31940 "\xd9\x8e"=>array("\xd9\x8e", "\xd9\x8e", "\xd9\x8e", "\xd9\x8e"), /* 064E, 064E, 064E, 064E */
31941 "\xd9\x8f"=>array("\xd9\x8f", "\xd9\x8f", "\xd9\x8f", "\xd9\x8f"), /* 064F, 064F, 064F, 064F */
31942 "\xd9\x90"=>array("\xd9\x90", "\xd9\x90", "\xd9\x90", "\xd9\x90"), /* 0650, 0650, 0650, 0650 */
31943 "\xd9\x91"=>array("\xd9\x91", "\xd9\x91", "\xd9\x91", "\xd9\x91"), /* 0651, 0651, 0651, 0651 */
31944 "\xd9\x92"=>array("\xd9\x92", "\xd9\x92", "\xd9\x92", "\xd9\x92"), /* 0652, 0652, 0652, 0652 */
31945 "\xd9\xb1"=>array("\xd9\xb1", "\xef\xad\x91", "\xd9\xb1", "\xef\xad\x91"), /* 0671, FB51, 0671, FB51 */
31946 "\xd9\xb2"=>array("\xd9\xb2", "\xef\x95\xb2", "\xd9\xb2", "\xef\x95\xb2"), /* 0672, F572, 0672, F572 */
31947 "\xd9\xb5"=>array("\xd9\xb5", "\xef\x95\xb5", "\xd9\xb5", "\xef\x95\xb5"), /* 0675, F575, 0675, F575 */
31948 "\xd9\xb8"=>array("\xd9\xb8", "\xef\x95\xb8", "\xef\xba\x8b", "\xef\xba\x8c"), /* 0678, F578, FE8B, FE8C ( as 0626 ) */
31949 "\xd9\xb9"=>array("\xd9\xb9", "\xef\xad\xa7", "\xef\xad\xa8", "\xef\xad\xa9"), /* 0679, FB67, FB68, FB69 */
31950 "\xd9\xba"=>array("\xd9\xba", "\xef\xad\x9f", "\xef\xad\xa0", "\xef\xad\xa1"), /* 067A, FB5F, FB60, FB61 */
31951 "\xd9\xbb"=>array("\xd9\xbb", "\xef\xad\x93", "\xef\xad\x94", "\xef\xad\x95"), /* 067B, FB53, FB54, FB55 */
31952 "\xd9\xbc"=>array("\xd9\xbc", "\xef\x95\xbc", "\xef\x99\xbc", "\xef\x9d\xbc"), /* 067C, F57C, F67C, F77C */
31953 "\xd9\xbd"=>array("\xd9\xbd", "\xef\x95\xbd", "\xef\x99\xbd", "\xef\x9d\xbd"), /* 067D, F57D, F67D, F77D */
31954 "\xd9\xbe"=>array("\xd9\xbe", "\xef\xad\x97", "\xef\xad\x98", "\xef\xad\x99"), /* 067E, FB57, FB58, FB59 */
31955 "\xd9\xbf"=>array("\xd9\xbf", "\xef\xad\xa3", "\xef\xad\xa4", "\xef\xad\xa5"), /* 067F, FB63, FB64, FB65 */
31956 "\xda\x80"=>array("\xda\x80", "\xef\xad\x9b", "\xef\xad\x9c", "\xef\xad\x9d"), /* 0680, FB5B, FB5C, FB5D */
31957 "\xda\x81"=>array("\xda\x81", "\xef\x96\x81", "\xef\x9a\x81", "\xef\x9e\x81"), /* 0681, F581, F681, F781 */
31958 "\xda\x82"=>array("\xda\x82", "\xef\x96\x82", "\xef\x9a\x82", "\xef\x9e\x82"), /* 0682, F582, F682, F782 */
31959 "\xda\x83"=>array("\xda\x83", "\xef\xad\xb7", "\xef\xad\xb8", "\xef\xad\xb9"), /* 0683, FB77, FB78, FB79 */
31960 "\xda\x84"=>array("\xda\x84", "\xef\xad\xb3", "\xef\xad\xb4", "\xef\xad\xb5"), /* 0684, FB73, FB74, FB75 */
31961 "\xda\x85"=>array("\xda\x85", "\xef\x96\x85", "\xef\x9a\x85", "\xef\x9e\x85"), /* 0685, F585, F685, F785 */
31962 "\xda\x86"=>array("\xda\x86", "\xef\xad\xbb", "\xef\xad\xbc", "\xef\xad\xbd"), /* 0686, FB7B, FB7C, FB7D */
31963 "\xda\x87"=>array("\xda\x87", "\xef\xad\xbf", "\xef\xae\x80", "\xef\xae\x81"), /* 0687, FB7F, FB80, FB81 */
31964 "\xda\x88"=>array("\xda\x88", "\xef\xae\x89", "\xda\x88", "\xda\x88"), /* 0688, FB89, 0688, 0688 */
31965 "\xda\x89"=>array("\xda\x89", "\xef\x96\x89", "\xda\x89", "\xda\x89"), /* 0689, F589, 0689, 0689 */
31966 "\xda\x91"=>array("\xda\x91", "\xef\xae\x8d", "\xda\x91", "\xef\xae\x8d"), /* 0691, FB8D, 0691, FB8D */
31967 "\xda\x93"=>array("\xda\x93", "\xef\x96\x93", "\xda\x93", "\xda\x93"), /* 0693, F593, 0693, 0693 */
31968 "\xda\x96"=>array("\xda\x96", "\xef\x96\x96", "\xda\x96", "\xda\x96"), /* 0696, F596, 0696, 0696 */
31969 "\xda\x98"=>array("\xda\x98", "\xef\xae\x8b", "\xda\x98", "\xef\xae\x8b"), /* 0698, FB8B, 0698, FB8B */
31970 "\xda\x9a"=>array("\xda\x9a", "\xef\x96\x9a", "\xef\x9a\x9a", "\xef\x9e\x9a"), /* 069A, F59A, F69A, F79A */
31971 "\xda\x9b"=>array("\xda\x9b", "\xef\x96\x9b", "\xef\x9a\x9b", "\xef\x9e\x9b"), /* 069B, F59B, F69B, F79B */
31972 "\xda\x9c"=>array("\xda\x9c", "\xef\x96\x9c", "\xef\x9a\x9c", "\xef\x9e\x9c"), /* 069C, F59C, F69C, F79C */
31973 "\xda\x9d"=>array("\xda\x9d", "\xef\x96\x9d", "\xef\x9a\x9d", "\xef\x9e\x9d"), /* 069D, F59D, F69D, F79D */
31974 "\xda\x9e"=>array("\xda\x9e", "\xef\x96\x9e", "\xef\x9a\x9e", "\xef\x9e\x9e"), /* 069E, F59E, F69E, F79E */
31975 "\xda\xa0"=>array("\xda\xa0", "\xef\x96\xa0", "\xef\x9a\xa0", "\xef\x9e\xa0"), /* 06A0, F5A0, F6A0, F7A0 */
31976 "\xda\xa1"=>array("\xda\xa1", "\xef\x96\xa1", "\xef\x9a\xa1", "\xef\x9e\xa1"), /* 06A1, F5A1, F6A1, F7A1 */
31977 "\xda\xa2"=>array("\xda\xa2", "\xef\x96\xa2", "\xef\x9a\xa2", "\xef\x9e\xa2"), /* 06A2, F5A2, F6A2, F7A2 */
31978 "\xda\xa3"=>array("\xda\xa3", "\xef\x96\xa3", "\xef\x9a\xa3", "\xef\x9e\xa3"), /* 06A3, F5A3, F6A3, F7A3 */
31979 "\xda\xa4"=>array("\xda\xa4", "\xef\xad\xab", "\xef\xad\xac", "\xef\xad\xad"), /* 06A4, FB6B, FB6C, FB6D */
31980 "\xda\xa5"=>array("\xda\xa5", "\xef\x96\xa5", "\xef\x9a\xa5", "\xef\x9e\xa5"), /* 06A5, F5A5, F6A5, F7A5 */
31981 "\xda\xa6"=>array("\xda\xa6", "\xef\xad\xaf", "\xef\xad\xb0", "\xef\xad\xb1"), /* 06A6, FB6F, FB70, FB71 */
31982 "\xda\xa9"=>array("\xda\xa9", "\xef\xae\x8f", "\xef\xae\x90", "\xef\xae\x91"), /* 06A9, FB8F, FB90, FB91 */
31983 "\xda\xaa"=>array("\xda\xaa", "\xef\x96\xaa", "\xef\x9a\xaa", "\xef\x9e\xaa"), /* 06AA, F5AA, F6AA, F7AA */
31984 "\xda\xab"=>array("\xda\xab", "\xef\x96\xab", "\xef\x9a\xab", "\xef\x9e\xab"), /* 06AB, F5AB, F6AB, F7AB */
31985 "\xda\xac"=>array("\xda\xac", "\xef\x96\xac", "\xef\x9a\xac", "\xef\x9e\xac"), /* 06AC, F5AC, F6AC, F7AC */
31986 "\xda\xad"=>array("\xda\xad", "\xef\xaf\x94", "\xef\xaf\x95", "\xef\xaf\x96"), /* 06AD, FBD4, FBD5, FBD6 */
31987 "\xda\xae"=>array("\xda\xae", "\xef\x96\xae", "\xef\x9a\xae", "\xef\x9e\xae"), /* 06AE, F5AE, F6AE, F7AE */
31988 "\xda\xaf"=>array("\xda\xaf", "\xef\xae\x93", "\xef\xae\x94", "\xef\xae\x95"), /* 06Af, FB93, FB94, FB95 */
31989 "\xda\xb0"=>array("\xda\xb0", "\xef\x96\xb0", "\xef\x9a\xb0", "\xef\x9e\xb0"), /* 06B0, F5B0, F6B0, F7B0 */
31990 "\xda\xb1"=>array("\xda\xb1", "\xef\xae\x9b", "\xef\xae\x9c", "\xef\xae\x9d"), /* 06B1, FB9B, FB9C, FB9D */
31991 "\xda\xb2"=>array("\xda\xb2", "\xef\x96\xb2", "\xef\x9a\xb2", "\xef\x9e\xb2"), /* 06B2, F5B2, F6B2, F7B2 */
31992 "\xda\xb3"=>array("\xda\xb3", "\xef\xae\x97", "\xef\xae\x98", "\xef\xae\x99"), /* 06B3, FB97, FB98, FB99 */
31993 "\xda\xb4"=>array("\xda\xb4", "\xef\x96\xb4", "\xef\x9a\xb4", "\xef\x9e\xb4"), /* 06B4, F5B4, F6B4, F7B4 */
31994 "\xda\xb5"=>array("\xda\xb5", "\xef\x96\xb5", "\xef\x9a\xb5", "\xef\x9e\xb5"), /* 06B5, F5B5, F6B5, F7B5 */
31995 "\xda\xb6"=>array("\xda\xb6", "\xef\x96\xb6", "\xef\x9a\xb6", "\xef\x9e\xb6"), /* 06B6, F5B6, F6B6, F7B6 */
31996 "\xda\xb7"=>array("\xda\xb7", "\xef\x96\xb7", "\xef\x9a\xb7", "\xef\x9e\xb7"), /* 06B7, F5B7, F6B7, F7B7 */
31997 "\xda\xb8"=>array("\xda\xb8", "\xef\x96\xb8", "\xef\x9a\xb8", "\xef\x9e\xb8"), /* 06B8, F5B8, F6B8, F7B8 */
31998 "\xda\xb9"=>array("\xda\xb9", "\xef\x96\xb9", "\xef\x9a\xb9", "\xef\x9e\xb9"), /* 06B9, F5B9, F6B9, F7B9 */
31999 "\xda\xba"=>array("\xda\xba", "\xef\xae\x9f", "\xda\xba", "\xda\xba"), /* 06BA, FB9F, 06BA, 06BA */
32000 "\xda\xbb"=>array("\xda\xbb", "\xef\xae\xa1", "\xef\xae\xa2", "\xef\xae\xa3"), /* 06BB, FBA1, FBA2, FBA3 */
32001 "\xda\xbc"=>array("\xda\xbc", "\xef\x96\xbc", "\xef\x9a\xbc", "\xef\x9e\xbc"), /* 06BC, F5BC, F6BC, F7BC */
32002 "\xda\xbe"=>array("\xda\xbe", "\xef\xae\xab", "\xef\xae\xac", "\xef\xae\xad"), /* 06BE, FBAB, FBAC, FBAD */
32003 "\xda\xbf"=>array("\xda\xbf", "\xef\x96\xbf", "\xef\x9a\xbf", "\xef\x9e\xbf"), /* 06BF, F5BF, F6BF, F7BF */
32004 "\xdb\x80"=>array("\xdb\x80", "\xef\xae\xa5", "\xdb\x80", "\xef\xae\xa5"), /* 06C0, FBA5, 06C0, FBA5 */
32005 "\xdb\x81"=>array("\xdb\x81", "\xef\xae\xa7", "\xef\xae\xa8", "\xef\xae\xa9"), /* 06C1, FBA7, FBA8, FBA9 */
32006 "\xdb\x8c"=>array("\xdb\x8c", "\xef\xaf\xbd", "\xef\xaf\xbe", "\xef\xaf\xbf"), /* 06CC, FBFD, FBFE, FBFF */
32007 "\xdb\x8d"=>array("\xdb\x8d", "\xef\x97\x8d", "\xdb\x8d", "\xef\x97\x8d"), /* 06CD, F5CD, 06CD, F5CD */
32008 "\xdb\x8e"=>array("\xdb\x8e", "\xef\x97\x8e", "\xef\x9b\x8e", "\xef\x9f\x8e"), /* 06CE, F5CE, F6CE, F7CE */
32009 "\xdb\x90"=>array("\xdb\x90", "\xef\xaf\xa5", "\xef\xaf\xa6", "\xef\xaf\xa7"), /* 06D0, FBE5, FBE6, FBE7 */
32010 "\xdb\x91"=>array("\xdb\x91", "\xef\x97\x91", "\xef\xad\x98", "\xef\xad\x99"), /* 06D1, F5D1, FB58, FB59 Fudge borrows from 067E */
32011 "\xdb\x92"=>array("\xdb\x92", "\xef\xae\xaf", "\xdb\x92", "\xef\xae\xaf"), /* 06D2, FBAF, 06D2, FBAF */
32012 "\xdb\x93"=>array("\xdb\x93", "\xef\xae\xb1", "\xdb\x93", "\xef\xae\xb1"), /* 06D3, FBB1, 06D3, FBB1 */
32013 );
32014
32015
32016 // LAM with ALEF ligatures (Mandatory ligatures)
32017
32018 // U+0644; U+0622; U+0644; U+0623; U+0644; U+0625; U+0644; U+0627;
32019 $this->arabLigGlyphs = "\xd9\x84\xd8\xa2\xd9\x84\xd8\xa3\xd9\x84\xd8\xa5\xd9\x84\xd8\xa7";
32020 $this->arabLigHex = 'FEF5FEF6FEF5FEF6FEF7FEF8FEF7FEF8FEF9FEFAFEF9FEFAFEFBFEFCFEFBFEFC';
32021
32022 }
32023
32024 // mPDF 5.4.08
32025 function ArabJoin($str) {
32026 if (!$this->arabGlyphs) { $this->InitArabic(); }
32027 $crntChar = null;
32028 $prevChar = null;
32029 $nextChar = null;
32030 $output = array();
32031 $chars = preg_split('//u', $str);
32032 $max = count($chars);
32033 for ($i = $max - 1; $i >= 0; $i--) {
32034 $crntChar = $chars[$i];
32035 if ($i > 0){ $prevChar = $chars[$i - 1]; }
32036 else{ $prevChar = NULL; }
32037 if ($prevChar && mb_strpos($this->arabVowels, $prevChar, 0, 'utf-8') !== false) {
32038 $prevChar = $chars[$i - 2];
32039 if ($prevChar && mb_strpos($this->arabVowels, $prevChar, 0, 'utf-8') !== false) {
32040 $prevChar = $chars[$i - 3];
32041 }
32042 }
32043 if ($crntChar && mb_strpos($this->arabVowels, $crntChar, 0, 'utf-8') !== false) {
32044 // If next_char = nextLink && prev_char = prevLink:
32045 // Added && $prevchar (defined) else error on mb_strpos()
32046 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)) {
32047 $output[] = $this->get_arab_glyphs($crntChar, 1); // <final> form
32048 }
32049 else {
32050 $output[] = $this->get_arab_glyphs($crntChar, 0); // <isolated> form
32051 }
32052 continue;
32053 }
32054 // NB = &#x622 &#x623; &#x625; &#x627; &#x644;
32055 if (isset($chars[$i + 1]) && in_array($chars[$i + 1], array("\xd8\xa2","\xd8\xa3","\xd8\xa5","\xd8\xa7")) && $crntChar == "\xd9\x84"){
32056 continue;
32057 }
32058 if (ord($crntChar) < 128) {
32059 $output[] = $crntChar;
32060 $nextChar = $crntChar;
32061 continue;
32062 }
32063 $form = 0;
32064 if ($prevChar == "\xd9\x84" && ($crntChar == "\xd8\xa2" || $crntChar == "\xd8\xa3" || $crntChar == "\xd8\xa5" || $crntChar == "\xd8\xa7")) {
32065 if ($chars[$i - 2] && mb_strpos($this->arabPrevLink, $chars[$i - 2], 0, 'utf-8') !== false) {
32066 $form++; // <final> form
32067 }
32068 $pos = mb_strpos($this->arabLigGlyphs, ($prevChar . $crntChar), 0, 'utf-8');
32069 $pos = $pos*8 + $form*4;
32070 $pres = (mb_substr($this->arabLigHex, $pos, 4, 'utf-8'));
32071 // If presentation forms for mandatory ligatures with diacritics not present (even if remapped from e.g. uni0644uni0625)
32072 // try replacing with mandatory ligature Alef/lam isolated/final FEFB/FEFC + diacritic glyph
32073 if (!$this->_charDefined($this->CurrentFont['cw'], hexdec($pres)) && $this->_charDefined($this->CurrentFont['cw'], hexdec('FEFB'))) {
32074 if ($pres=='FEF5') { $output[] = strcode2utf('&#xFEFB;&#x0653;'); }
32075 else if ($pres=='FEF6') { $output[] = strcode2utf('&#xFEFC;&#x0653;'); }
32076 else if ($pres=='FEF7') { $output[] = strcode2utf('&#xFEFB;&#x0654;'); }
32077 else if ($pres=='FEF8') { $output[] = strcode2utf('&#xFEFC;&#x0654;'); }
32078 else if ($pres=='FEF9') { $output[] = strcode2utf('&#xFEFB;&#x0655;'); }
32079 else if ($pres=='FEFA') { $output[] = strcode2utf('&#xFEFC;&#x0655;'); }
32080 }
32081 else {
32082 $output[] = strcode2utf('&#x' . $pres . ';');
32083 }
32084 $nextChar = $prevChar;
32085 continue;
32086 }
32087 if ($prevChar && mb_strpos($this->arabPrevLink, $prevChar, 0, 'utf-8') !== false) {
32088 $form++;
32089 }
32090 if ($nextChar && mb_strpos($this->arabNextLink, $nextChar, 0, 'utf-8') !== false) {
32091 $form += 2;
32092 }
32093 $output[] = $this->get_arab_glyphs($crntChar, $form) ;
32094 $nextChar = $crntChar;
32095 }
32096 $ra = array_reverse($output);
32097 $s = implode($ra);
32098 return $s;
32099 }
32100
32101 // mPDF 5.7+
32102 function arabJoinPregCallback($matches) {
32103 return $this->ArabJoin(stripslashes($matches[1]));
32104 }
32105
32106 // mPDF 5.4.08
32107 function get_arab_glyphs($char, $type) {
32108 if ($type>0 && isset($this->arabGlyphs[$char])) {
32109 // If presentation form specified FB** - FE** = Arabic presentation Forms
32110 if (preg_match("/[\x{FB50}-\x{FEFF}]/u",$this->arabGlyphs[$char][$type])) {
32111 $unicode = $this->UTF8StringToArray($this->arabGlyphs[$char][$type], false);
32112 if ($this->_charDefined($this->CurrentFont['cw'],$unicode[0])) { return $this->arabGlyphs[$char][$type]; }
32113 else if (isset($this->CurrentFont['unAGlyphs'])) {
32114 $uni = $this->UTF8StringToArray($char, false);
32115 $pua = $uni[0] - 1536 + 62464 + 256*$type ;
32116 if ($this->_charDefined($this->CurrentFont['cw'], $pua)) { return strcode2utf('&#x' . dechex($pua) . ';'); }
32117 else return $char;
32118 }
32119 else return $char;
32120 }
32121 // If PUA form specified and unAGlphs font set F5** F6** F7** = Private use area used by unAGlyphs in mPDF
32122 if (preg_match("/[\x{F500}-\x{F7FF}]/u",$this->arabGlyphs[$char][$type]) && isset($this->CurrentFont['unAGlyphs'])) {
32123 $unicode = $this->UTF8StringToArray($this->arabGlyphs[$char][$type], false);
32124 if ($this->_charDefined($this->CurrentFont['cw'],$unicode[0])) { return $this->arabGlyphs[$char][$type]; }
32125 else return $char;
32126 }
32127 return $this->arabGlyphs[$char][$type];
32128 }
32129 else return $char;
32130 }
32131 /*-- END RTL --*/
32132
32133
32134
32135 //===========================
32136 // Functions originally in htmltoolkit - moved mPDF 4.0
32137
32138 // Call-back function Used for usort in fn _tableWrite
32139
32140 function _cmpdom($a, $b) {
32141 return ($a["dom"] < $b["dom"]) ? -1 : 1;
32142 }
32143
32144 function mb_strrev($str, $enc = 'utf-8'){
32145 $ch = array();
32146 $ch = preg_split('//u',$str);
32147 $revch = array_reverse($ch);
32148 return implode('',$revch);
32149 }
32150
32151 /*-- COLUMNS --*/
32152 // Callback function from function printcolumnbuffer in mpdf
32153 function columnAdjustAdd($type,$k,$xadj,$yadj,$a,$b,$c=0,$d=0,$e=0,$f=0) {
32154 if ($type == 'Td') { // xpos,ypos
32155 $a += ($xadj * $k);
32156 $b -= ($yadj * $k);
32157 return 'BT '.sprintf('%.3F %.3F',$a,$b).' Td';
32158 }
32159 else if ($type == 're') { // xpos,ypos,width,height
32160 $a += ($xadj * $k);
32161 $b -= ($yadj * $k);
32162 return sprintf('%.3F %.3F %.3F %.3F',$a,$b,$c,$d).' re';
32163 }
32164 else if ($type == 'l') { // xpos,ypos,x2pos,y2pos
32165 $a += ($xadj * $k);
32166 $b -= ($yadj * $k);
32167 return sprintf('%.3F %.3F l',$a,$b);
32168 }
32169 else if ($type == 'img') { // width,height,xpos,ypos
32170 $c += ($xadj * $k);
32171 $d -= ($yadj * $k);
32172 return sprintf('q %.3F 0 0 %.3F %.3F %.3F',$a,$b,$c,$d).' cm /'.$e;
32173 }
32174 else if ($type == 'draw') { // xpos,ypos
32175 $a += ($xadj * $k);
32176 $b -= ($yadj * $k);
32177 return sprintf('%.3F %.3F m',$a,$b);
32178 }
32179 else if ($type == 'bezier') { // xpos,ypos,x2pos,y2pos,x3pos,y3pos
32180 $a += ($xadj * $k);
32181 $b -= ($yadj * $k);
32182 $c += ($xadj * $k);
32183 $d -= ($yadj * $k);
32184 $e += ($xadj * $k);
32185 $f -= ($yadj * $k);
32186 return sprintf('%.3F %.3F %.3F %.3F %.3F %.3F',$a,$b,$c,$d,$e,$f).' c';
32187 }
32188 }
32189 /*-- END COLUMNS --*/
32190
32191
32192
32193 function ConvertColor($color="#000000"){
32194 $color = trim(strtolower($color));
32195 $c = false;
32196 if ($color=='transparent') { return false; }
32197 else if ($color=='inherit') { return false; }
32198 else if (isset($this->SVGcolors[$color])) $color = $this->SVGcolors[$color];
32199
32200 if (preg_match('/^[\d]+$/',$color)) { $c = (array(1,$color)); } // i.e. integer only
32201 else if ($color[0] == '#') { //case of #nnnnnn or #nnn
32202 $cor = preg_replace('/\s+.*/','',$color); // in case of Background: #CCC url() x-repeat etc.
32203 if (strlen($cor) == 4) { // Turn #RGB into #RRGGBB
32204 $cor = "#" . $cor[1] . $cor[1] . $cor[2] . $cor[2] . $cor[3] . $cor[3];
32205 }
32206 $r = hexdec(substr($cor, 1, 2));
32207 $g = hexdec(substr($cor, 3, 2));
32208 $b = hexdec(substr($cor, 5, 2));
32209 $c = array(3,$r,$g,$b);
32210 }
32211 else if (preg_match('/(rgba|rgb|device-cmyka|cmyka|device-cmyk|cmyk|hsla|hsl|spot)\((.*?)\)/',$color,$m)) { // mPDF 5.6.05
32212 $type= $m[1];
32213 $cores = explode(",", $m[2]);
32214 $ncores = count($cores);
32215 if (stristr($cores[0],'%') ) {
32216 $cores[0] += 0;
32217 if ($type=='rgb' || $type=='rgba') { $cores[0] = intval($cores[0]*255/100); }
32218 }
32219 if ($ncores>1 && stristr($cores[1],'%') ) {
32220 $cores[1] += 0;
32221 if ($type=='rgb' || $type=='rgba') { $cores[1] = intval($cores[1]*255/100); }
32222 if ($type=='hsl' || $type=='hsla') { $cores[1] = $cores[1]/100; }
32223 }
32224 if ($ncores>2 && stristr($cores[2],'%') ) {
32225 $cores[2] += 0;
32226 if ($type=='rgb' || $type=='rgba') { $cores[2] = intval($cores[2]*255/100); }
32227 if ($type=='hsl' || $type=='hsla') { $cores[2] = $cores[2]/100; }
32228 }
32229 if ($ncores>3 && stristr($cores[3],'%') ) {
32230 $cores[3] += 0;
32231 }
32232
32233 if ($type=='rgb') { $c = array(3,$cores[0],$cores[1],$cores[2]); }
32234 else if ($type=='rgba') { $c = array(5,$cores[0],$cores[1],$cores[2],$cores[3]*100); }
32235 else if ($type=='cmyk' || $type=='device-cmyk') { $c = array(4,$cores[0],$cores[1],$cores[2],$cores[3]); } // mPDF 5.6.05
32236 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
32237 else if ($type=='hsl' || $type=='hsla') {
32238 $conv = $this->hsl2rgb($cores[0]/360,$cores[1],$cores[2]);
32239 if ($type=='hsl') { $c = array(3,$conv[0],$conv[1],$conv[2]); }
32240 else if ($type=='hsla') { $c = array(5,$conv[0],$conv[1],$conv[2],$cores[3]*100); }
32241 }
32242 else if ($type=='spot') {
32243 $name = strtoupper(trim($cores[0]));
32244 // mPDF 5.6.59
32245 if(!isset($this->spotColors[$name])) {
32246 if (isset($cores[5])) { $this->AddSpotColor($cores[0],$cores[2],$cores[3],$cores[4],$cores[5]); }
32247 else { $this->Error('Undefined spot color: '.$name); }
32248 }
32249 $c = array(2,$this->spotColors[$name]['i'],$cores[1]);
32250 }
32251 }
32252
32253
32254 // $this->restrictColorSpace
32255 // 1 - allow GRAYSCALE only [convert CMYK/RGB->gray]
32256 // 2 - allow RGB / SPOT COLOR / Grayscale [convert CMYK->RGB]
32257 // 3 - allow CMYK / SPOT COLOR / Grayscale [convert RGB->CMYK]
32258 if ($this->PDFA || $this->PDFX || $this->restrictColorSpace) {
32259 if ($c[0]==1) { // GRAYSCALE
32260 }
32261 else if ($c[0]==2) { // SPOT COLOR
32262 if (!isset($this->spotColorIDs[$c[1]])) { die('Error: Spot colour has not been defined - '.$this->spotColorIDs[$c[1]]); }
32263 if ($this->PDFA) {
32264 if ($this->PDFA && !$this->PDFAauto) { $this->PDFAXwarnings[] = "Spot color specified '".$this->spotColorIDs[$c[1]]."' (converted to process color)"; }
32265 if ($this->restrictColorSpace!=3) {
32266 $sp = $this->spotColors[$this->spotColorIDs[$c[1]]];
32267 $c = $this->cmyk2rgb(array(4,$sp['c'],$sp['m'],$sp['y'],$sp['k']));
32268 }
32269 }
32270 else if ($this->restrictColorSpace==1) {
32271 $sp = $this->spotColors[$this->spotColorIDs[$c[1]]];
32272 $c = $this->cmyk2gray(array(4,$sp['c'],$sp['m'],$sp['y'],$sp['k']));
32273 }
32274 }
32275 else if ($c[0]==3) { // RGB
32276 if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3)) {
32277 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "RGB color specified '".$color."' (converted to CMYK)"; }
32278 $c = $this->rgb2cmyk($c);
32279 }
32280 else if ($this->restrictColorSpace==1) { $c = $this->rgb2gray($c); }
32281 else if ($this->restrictColorSpace==3) { $c = $this->rgb2cmyk($c); }
32282 }
32283 else if ($c[0]==4) { // CMYK
32284 if ($this->PDFA && $this->restrictColorSpace!=3) {
32285 if ($this->PDFA && !$this->PDFAauto) { $this->PDFAXwarnings[] = "CMYK color specified '".$color."' (converted to RGB)"; }
32286 $c = $this->cmyk2rgb($c);
32287 }
32288 else if ($this->restrictColorSpace==1) { $c = $this->cmyk2gray($c); }
32289 else if ($this->restrictColorSpace==2) { $c = $this->cmyk2rgb($c); }
32290 }
32291 else if ($c[0]==5) { // RGBa
32292 if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3)) {
32293 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "RGB color with transparency specified '".$color."' (converted to CMYK without transparency)"; }
32294 $c = $this->rgb2cmyk($c);
32295 $c = array(4, $c[1], $c[2], $c[3], $c[4]);
32296 }
32297 else if ($this->PDFA && $this->restrictColorSpace!=3) {
32298 if (!$this->PDFAauto) { $this->PDFAXwarnings[] = "RGB color with transparency specified '".$color."' (converted to RGB without transparency)"; }
32299 $c = $this->rgb2cmyk($c);
32300 $c = array(4, $c[1], $c[2], $c[3], $c[4]);
32301 }
32302 else if ($this->restrictColorSpace==1) { $c = $this->rgb2gray($c); }
32303 else if ($this->restrictColorSpace==3) { $c = $this->rgb2cmyk($c); }
32304 }
32305 else if ($c[0]==6) { // CMYKa
32306 if ($this->PDFA && $this->restrictColorSpace!=3) {
32307 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "CMYK color with transparency specified '".$color."' (converted to RGB without transparency)"; }
32308 $c = $this->cmyk2rgb($c);
32309 $c = array(3, $c[1], $c[2], $c[3]);
32310 }
32311 else if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3)) {
32312 if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "CMYK color with transparency specified '".$color."' (converted to CMYK without transparency)"; }
32313 $c = $this->cmyk2rgb($c);
32314 $c = array(3, $c[1], $c[2], $c[3]);
32315 }
32316 else if ($this->restrictColorSpace==1) { $c = $this->cmyk2gray($c); }
32317 else if ($this->restrictColorSpace==2) { $c = $this->cmyk2rgb($c); }
32318 }
32319 }
32320 if (is_array($c)) {
32321 $c = array_pad($c, 6, 0);
32322 $cstr = pack("a1ccccc", $c[0], ($c[1] & 0xFF), ($c[2] & 0xFF), ($c[3] & 0xFF), ($c[4] & 0xFF), ($c[5] & 0xFF) );
32323 }
32324 return $cstr;
32325 }
32326
32327 function rgb2gray($c) {
32328 if (isset($c[4])) { return array(1,(($c[1] * .21) + ($c[2] * .71) + ($c[3] * .07)), ord(1), $c[4]); }
32329 else { return array(1,(($c[1] * .21) + ($c[2] * .71) + ($c[3] * .07))); }
32330 }
32331
32332 function cmyk2gray($c) {
32333 $rgb = $this->cmyk2rgb($c);
32334 return $this->rgb2gray($rgb);
32335 }
32336
32337 function rgb2cmyk($c) {
32338 $cyan = 1 - ($c[1] / 255);
32339 $magenta = 1 - ($c[2] / 255);
32340 $yellow = 1 - ($c[3] / 255);
32341 $min = min($cyan, $magenta, $yellow);
32342
32343 if ($min == 1) {
32344 if ($c[0]==5) { return array (6,100,100,100,100, $c[4]); }
32345 else { return array (4,100,100,100,100); }
32346 // For K-Black
32347 //if ($c[0]==5) { return array (6,0,0,0,100, $c[4]); }
32348 //else { return array (4,0,0,0,100); }
32349 }
32350 $K = $min;
32351 $black = 1 - $K;
32352 if ($c[0]==5) { return array (6,($cyan-$K)*100/$black, ($magenta-$K)*100/$black, ($yellow-$K)*100/$black, $K*100, $c[4]); }
32353 else { return array (4,($cyan-$K)*100/$black, ($magenta-$K)*100/$black, ($yellow-$K)*100/$black, $K*100); }
32354 }
32355
32356
32357 function cmyk2rgb($c) {
32358 $rgb = array();
32359 $colors = 255 - ($c[4]*2.55);
32360 $rgb[0] = intval($colors * (255 - ($c[1]*2.55))/255);
32361 $rgb[1] = intval($colors * (255 - ($c[2]*2.55))/255);
32362 $rgb[2] = intval($colors * (255 - ($c[3]*2.55))/255);
32363 if ($c[0]==6) { return array (5,$rgb[0],$rgb[1],$rgb[2], $c[5]); }
32364 else { return array (3,$rgb[0],$rgb[1],$rgb[2]); }
32365 }
32366
32367 function rgb2hsl($var_r, $var_g, $var_b) {
32368 $var_min = min($var_r,$var_g,$var_b);
32369 $var_max = max($var_r,$var_g,$var_b);
32370 $del_max = $var_max - $var_min;
32371 $l = ($var_max + $var_min) / 2;
32372 if ($del_max == 0) {
32373 $h = 0;
32374 $s = 0;
32375 }
32376 else {
32377 if ($l < 0.5) { $s = $del_max / ($var_max + $var_min); }
32378 else { $s = $del_max / (2 - $var_max - $var_min); }
32379 $del_r = ((($var_max - $var_r) / 6) + ($del_max / 2)) / $del_max;
32380 $del_g = ((($var_max - $var_g) / 6) + ($del_max / 2)) / $del_max;
32381 $del_b = ((($var_max - $var_b) / 6) + ($del_max / 2)) / $del_max;
32382 if ($var_r == $var_max) { $h = $del_b - $del_g; }
32383 elseif ($var_g == $var_max) { $h = (1 / 3) + $del_r - $del_b; }
32384 elseif ($var_b == $var_max) { $h = (2 / 3) + $del_g - $del_r; };
32385 if ($h < 0) { $h += 1; }
32386 if ($h > 1) { $h -= 1; }
32387 }
32388 return array($h,$s,$l);
32389 }
32390
32391
32392 function hsl2rgb($h2,$s2,$l2) {
32393 // Input is HSL value of complementary colour, held in $h2, $s, $l as fractions of 1
32394 // Output is RGB in normal 255 255 255 format, held in $r, $g, $b
32395 // Hue is converted using function hue_2_rgb, shown at the end of this code
32396 if ($s2 == 0) {
32397 $r = $l2 * 255;
32398 $g = $l2 * 255;
32399 $b = $l2 * 255;
32400 }
32401 else {
32402 if ($l2 < 0.5) { $var_2 = $l2 * (1 + $s2); }
32403 else { $var_2 = ($l2 + $s2) - ($s2 * $l2); }
32404 $var_1 = 2 * $l2 - $var_2;
32405 $r = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2 + (1 / 3)));
32406 $g = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2));
32407 $b = round(255 * $this->hue_2_rgb($var_1,$var_2,$h2 - (1 / 3)));
32408 }
32409 return array($r,$g,$b);
32410 }
32411
32412 function hue_2_rgb($v1,$v2,$vh) {
32413 // Function to convert hue to RGB, called from above
32414 if ($vh < 0) { $vh += 1; };
32415 if ($vh > 1) { $vh -= 1; };
32416 if ((6 * $vh) < 1) { return ($v1 + ($v2 - $v1) * 6 * $vh); };
32417 if ((2 * $vh) < 1) { return ($v2); };
32418 if ((3 * $vh) < 2) { return ($v1 + ($v2 - $v1) * ((2 / 3 - $vh) * 6)); };
32419 return ($v1);
32420 }
32421
32422 function _invertColor($cor) {
32423 if ($cor[0]==3 || $cor[0]==5) { // RGB
32424 return array(3, (255-$cor[1]), (255-$cor[2]), (255-$cor[3]));
32425 }
32426 else if ($cor[0]==4 || $cor[0]==6) { // CMYK
32427 return array(4, (100-$cor[1]), (100-$cor[2]), (100-$cor[3]), (100-$cor[4]));
32428 }
32429 else if ($cor[0]==1) { // Grayscale
32430 return array(1, (255-$cor[1]));
32431 }
32432 // Cannot cope with non-RGB colors at present
32433 die('Error in _invertColor - trying to invert non-RGB color');
32434 }
32435
32436 function _colAtoString($cor) {
32437 $s = '';
32438 if ($cor{0}==1) $s = 'rgb('.ord($cor{1}).','.ord($cor{1}).','.ord($cor{1}).')';
32439 else if ($cor{0}==2) $s = 'spot('.ord($cor{1}).','.ord($cor{2}).')'; // SPOT COLOR
32440 else if ($cor{0}==3) $s = 'rgb('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).')';
32441 else if ($cor{0}==4) $s = 'cmyk('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).','.ord($cor{4}).')';
32442 else if ($cor{0}==5) $s = 'rgba('.ord($cor{1}).','.ord($cor{2}).','.ord($cor{3}).','.sprintf('%0.2F',ord($cor{4})/100).')';
32443 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).')';
32444 return $s;
32445 }
32446
32447 function ConvertSize($size=5,$maxsize=0,$fontsize=false,$usefontsize=true){
32448 // usefontsize - setfalse for e.g. margins - will ignore fontsize for % values
32449 // Depends of maxsize value to make % work properly. Usually maxsize == pagewidth
32450 // For text $maxsize = Fontsize
32451 // Setting e.g. margin % will use maxsize (pagewidth) and em will use fontsize
32452 //Identify size (remember: we are using 'mm' units here)
32453 $size = trim(strtolower($size));
32454
32455 if ( $size == 'thin' ) $size = 1*(25.4/$this->dpi); //1 pixel width for table borders
32456 elseif ( stristr($size,'px') ) $size *= (25.4/$this->dpi); //pixels
32457 elseif ( stristr($size,'cm') ) $size *= 10; //centimeters
32458 elseif ( stristr($size,'mm') ) $size += 0; //millimeters
32459 elseif ( stristr($size,'pt') ) $size *= 25.4/72; //72 pts/inch
32460 elseif ( stristr($size,'rem') ) { // mPDF 5.6.12
32461 $size += 0; //make "0.83rem" become simply "0.83"
32462 $size *= ($this->default_font_size / _MPDFK);
32463 }
32464 elseif ( stristr($size,'em') ) {
32465 $size += 0; //make "0.83em" become simply "0.83"
32466 if ($fontsize) { $size *= $fontsize; }
32467 else { $size *= $maxsize; }
32468 }
32469 elseif ( stristr($size,'%') ) {
32470 $size += 0; //make "90%" become simply "90"
32471 if ($fontsize && $usefontsize) { $size *= $fontsize/100; }
32472 else { $size *= $maxsize/100; }
32473 }
32474 elseif ( stristr($size,'in') ) $size *= 25.4; //inches
32475 elseif ( stristr($size,'pc') ) $size *= 38.1/9; //PostScript picas
32476 elseif ( stristr($size,'ex') ) { // Approximates "ex" as half of font height
32477 $size += 0; //make "3.5ex" become simply "3.5"
32478 if ($fontsize) { $size *= $fontsize/2; }
32479 else { $size *= $maxsize/2; }
32480 }
32481 elseif ( $size == 'medium' ) $size = 3*(25.4/$this->dpi); //3 pixel width for table borders
32482 elseif ( $size == 'thick' ) $size = 5*(25.4/$this->dpi); //5 pixel width for table borders
32483 elseif ($size == 'xx-small') {
32484 if ($fontsize) { $size *= $fontsize*0.7; }
32485 else { $size *= $maxsize*0.7; }
32486 }
32487 elseif ($size == 'x-small') {
32488 if ($fontsize) { $size *= $fontsize*0.77; }
32489 else { $size *= $maxsize*0.77; }
32490 }
32491 elseif ($size == 'small') {
32492 if ($fontsize) { $size *= $fontsize*0.86; }
32493 else { $size *= $maxsize*0.86; }
32494 }
32495 elseif ($size == 'medium') {
32496 if ($fontsize) { $size *= $fontsize; }
32497 else { $size *= $maxsize; }
32498 }
32499 elseif ($size == 'large') {
32500 if ($fontsize) { $size *= $fontsize*1.2; }
32501 else { $size *= $maxsize*1.2; }
32502 }
32503 elseif ($size == 'x-large') {
32504 if ($fontsize) { $size *= $fontsize*1.5; }
32505 else { $size *= $maxsize*1.5; }
32506 }
32507 elseif ($size == 'xx-large') {
32508 if ($fontsize) { $size *= $fontsize*2; }
32509 else { $size *= $maxsize*2; }
32510 }
32511 else $size *= (25.4/$this->dpi); //nothing == px
32512
32513 return $size;
32514 }
32515
32516 // mPDF 5.7.3 TRANSFORMS
32517 function ConvertAngle($s, $makepositive=true) {
32518 if (preg_match('/([\-]*[0-9\.]+)(deg|grad|rad)/i',$s,$m)) {
32519 $angle = $m[1] + 0;
32520 if (strtolower($m[2])=='deg') { $angle = $angle; }
32521 else if (strtolower($m[2])=='grad') { $angle *= (360/400); }
32522 else if (strtolower($m[2])=='rad') { $angle = rad2deg($angle); }
32523 while($angle >= 360) { $angle -= 360; }
32524 while($angle <= -360) { $angle += 360; }
32525 if ($makepositive) { // always returns an angle between 0 and 360deg
32526 if ($angle < 0) { $angle += 360; }
32527 }
32528 }
32529 else { $angle = $s + 0; }
32530 return $angle;
32531 }
32532
32533 function lesser_entity_decode($html) {
32534 //supports the most used entity codes (only does ascii safe characters)
32535 //$html = str_replace("&nbsp;"," ",$html); // mPDF 5.3.59
32536 $html = str_replace("&lt;","<",$html);
32537 $html = str_replace("&gt;",">",$html);
32538
32539 $html = str_replace("&apos;","'",$html);
32540 $html = str_replace("&quot;",'"',$html);
32541 $html = str_replace("&amp;","&",$html);
32542 return $html;
32543 }
32544
32545 function AdjustHTML($html, $tabSpaces=8) {
32546 //Try to make the html text more manageable (turning it into XHTML)
32547 if (PHP_VERSION_ID < 50307) {
32548 if (strlen($html) > 100000) {
32549 if (PHP_VERSION_ID < 50200) $this->Error("The HTML code is more than 100,000 characters. You should use WriteHTML() with smaller string lengths.");
32550 else ini_set("pcre.backtrack_limit","1000000");
32551 }
32552 }
32553
32554 /*-- ANNOTATIONS --*/
32555 preg_match_all("/(<annotation.*?>)/si", $html, $m);
32556 if (count($m[1])) {
32557 for($i=0;$i<count($m[1]);$i++) {
32558 $sub = preg_replace("/\n/si", "\xbb\xa4\xac", $m[1][$i]);
32559 $html = preg_replace('/'.preg_quote($m[1][$i], '/').'/si', $sub, $html);
32560 }
32561 }
32562 /*-- END ANNOTATIONS --*/
32563
32564 preg_match_all("/(<svg.*?<\/svg>)/si", $html, $svgi);
32565 if (count($svgi[0])) {
32566 for($i=0;$i<count($svgi[0]);$i++) {
32567 $file = _MPDF_TEMP_PATH.'_tempSVG'.uniqid(rand(1,100000),true).'_'.$i.'.svg';
32568 //Save to local file
32569 file_put_contents($file, $svgi[0][$i]);
32570 $html = str_replace($svgi[0][$i], '<img src="'.$file.'" />', $html); // mPDF 5.5.18
32571 }
32572 }
32573
32574 //Remove javascript code from HTML (should not appear in the PDF file)
32575 $html = preg_replace('/<script.*?<\/script>/is','',$html);
32576
32577 //Remove special comments
32578 $html = preg_replace('/<!--mpdf/i','',$html);
32579 $html = preg_replace('/mpdf-->/i','',$html);
32580
32581 //Remove comments from HTML (should not appear in the PDF file)
32582 $html = preg_replace('/<!--.*?-->/s','',$html);
32583
32584 $html = preg_replace('/\f/','',$html); //replace formfeed by nothing
32585 $html = preg_replace('/\r/','',$html); //replace carriage return by nothing
32586
32587 // Well formed XHTML end tags
32588 $html = preg_replace('/<(br|hr)\/>/i',"<\\1 />",$html);
32589 // Get rid of empty <thead></thead>
32590 $html = preg_replace('/<thead>\s*<\/thead>/i','',$html);
32591 $html = preg_replace('/<tfoot>\s*<\/tfoot>/i','',$html);
32592 $html = preg_replace('/<table[^>]*>\s*<\/table>/i','',$html);
32593 $html = preg_replace('/<tr>\s*<\/tr>/i','',$html);
32594
32595 // Remove spaces at end of table cells
32596 $html = preg_replace("/[ \n\r]+<\/t(d|h)/",'</t\\1',$html); // mPDF 5.5.09
32597
32598 $html = preg_replace("/[ ]*<dottab\s*[\/]*>[ ]*/",'<dottab />',$html);
32599
32600 // Concatenates any Substitute characters from symbols/dingbats
32601 $html = str_replace('</tts><tts>','|',$html);
32602 $html = str_replace('</ttz><ttz>','|',$html);
32603 $html = str_replace('</tta><tta>','|',$html);
32604
32605 $html = preg_replace('/<br \/>\s*/is',"<br />",$html);
32606
32607 $html = preg_replace('/<wbr[ \/]*>\s*/is',"&#173;",$html); // mPDF 5.6.04
32608
32609 // Preserve '\n's in content between the tags <pre> and </pre>
32610 if (preg_match('/<pre/',$html)) {
32611 $html_a = preg_split('/(\<\/?pre[^\>]*\>)/', $html, -1, 2);
32612 $h = array();
32613 $c=0;
32614 foreach($html_a AS $s) {
32615 if ($c>1 && preg_match('/^<\/pre/i',$s)) { $c--; $s=preg_replace('/<\/pre/i','</innerpre',$s); }
32616 else if ($c>0 && preg_match('/^<pre/i',$s)) { $c++; $s=preg_replace('/<pre/i','<innerpre',$s); }
32617 else if (preg_match('/^<pre/i',$s)) { $c++; }
32618 else if (preg_match('/^<\/pre/i',$s)) { $c--; }
32619 array_push($h, $s);
32620 }
32621 $html = implode("", $h);
32622 }
32623 $thereispre = preg_match_all('#<pre(.*?)>(.*?)</pre>#si',$html,$temp);
32624 // Preserve '\n's in content between the tags <textarea> and </textarea>
32625 $thereistextarea = preg_match_all('#<textarea(.*?)>(.*?)</textarea>#si',$html,$temp2);
32626 $html = preg_replace('/[\n]/',' ',$html); //replace linefeed by spaces
32627 $html = preg_replace('/[\t]/',' ',$html); //replace tabs by spaces
32628
32629 // Converts < to &lt; when not a tag
32630 $html = preg_replace('/<([^!\/a-zA-Z_:])/i','&lt;\\1',$html); // mPDF 5.7.3
32631 $html = preg_replace("/[ ]+/",' ',$html);
32632
32633 $html = preg_replace('/\/li>\s+<\/(u|o)l/i','/li></\\1l',$html);
32634 $html = preg_replace('/\/(u|o)l>\s+<\/li/i','/\\1l></li',$html);
32635 $html = preg_replace('/\/li>\s+<\/(u|o)l/i','/li></\\1l',$html);
32636 $html = preg_replace('/\/li>\s+<li/i','/li><li',$html);
32637 $html = preg_replace('/<(u|o)l([^>]*)>[ ]+/i','<\\1l\\2>',$html);
32638 $html = preg_replace('/[ ]+<(u|o)l/i','<\\1l',$html);
32639
32640 $iterator = 0;
32641 while($thereispre) //Recover <pre attributes>content</pre>
32642 {
32643 $temp[2][$iterator] = preg_replace('/<([^!\/a-zA-Z_:])/','&lt;\\1',$temp[2][$iterator]); // mPDF 5.7.2 // mPDF 5.7.3
32644 $temp[2][$iterator] = preg_replace_callback("/^([^\n\t]*?)\t/m", array($this, 'tabs2spaces_callback'), $temp[2][$iterator]); // mPDF 5.7+
32645 $temp[2][$iterator] = preg_replace('/\t/',str_repeat(" ",$tabSpaces),$temp[2][$iterator]);
32646
32647 $temp[2][$iterator] = preg_replace('/\n/',"<br />",$temp[2][$iterator]);
32648 $temp[2][$iterator] = str_replace('\\',"\\\\",$temp[2][$iterator]);
32649 //$html = preg_replace('#<pre(.*?)>(.*?)</pre>#si','<erp'.$temp[1][$iterator].'>'.$temp[2][$iterator].'</erp>',$html,1);
32650 $html = preg_replace('#<pre(.*?)>(.*?)</pre>#si','<erp'.$temp[1][$iterator].'>'.str_replace('$','\$',$temp[2][$iterator]).'</erp>',$html,1); // mPDF 5.7+
32651 $thereispre--;
32652 $iterator++;
32653 }
32654 $iterator = 0;
32655 while($thereistextarea) //Recover <textarea attributes>content</textarea>
32656 {
32657 $temp2[2][$iterator] = preg_replace('/\t/',str_repeat(" ",$tabSpaces),$temp2[2][$iterator]);
32658 $temp2[2][$iterator] = str_replace('\\',"\\\\",$temp2[2][$iterator]); // mPDF 5.3.88
32659 $html = preg_replace('#<textarea(.*?)>(.*?)</textarea>#si','<aeratxet'.$temp2[1][$iterator].'>'.trim($temp2[2][$iterator]) .'</aeratxet>',$html,1);
32660 $thereistextarea--;
32661 $iterator++;
32662 }
32663 //Restore original tag names
32664 $html = str_replace("<erp","<pre",$html);
32665 $html = str_replace("</erp>","</pre>",$html);
32666 $html = str_replace("<aeratxet","<textarea",$html);
32667 $html = str_replace("</aeratxet>","</textarea>",$html);
32668 $html = str_replace("</innerpre","</pre",$html);
32669 $html = str_replace("<innerpre","<pre",$html);
32670
32671 $html = preg_replace('/<textarea([^>]*)><\/textarea>/si','<textarea\\1> </textarea>',$html);
32672 $html = preg_replace('/(<table[^>]*>)\s*(<caption)(.*?<\/caption>)(.*?<\/table>)/si','\\2 position="top"\\3\\1\\4\\2 position="bottom"\\3',$html); // *TABLES*
32673 $html = preg_replace('/<(h[1-6])([^>]*)(>(?:(?!h[1-6]).)*?<\/\\1>\s*<table)/si','<\\1\\2 keep-with-table="1"\\3',$html); // *TABLES*
32674 $html = preg_replace("/\xbb\xa4\xac/", "\n", $html);
32675
32676 return $html;
32677 }
32678 // mPDF 5.7+
32679 function tabs2spaces_callback($matches) {
32680 return (stripslashes($matches[1]) . str_repeat(' ', $this->tabSpaces - (mb_strlen(stripslashes($matches[1])) % $this->tabSpaces)));
32681 }
32682 // mPDF 5.7+
32683 function date_callback($matches) {
32684 return date($matches[1]);
32685 }
32686
32687 /*-- LISTS --*/
32688 function dec2other($num, $cp) {
32689 $nstr = (string) $num;
32690 $rnum = '';
32691 for ($i=0;$i<strlen($nstr);$i++) {
32692 if ($this->_charDefined($this->CurrentFont['cw'],$cp+intval($nstr[$i]))) { // contains arabic-indic numbers
32693 $rnum .= code2utf($cp+intval($nstr[$i]));
32694 }
32695 else { $rnum .= $nstr[$i]; }
32696 }
32697 return $rnum;
32698 }
32699
32700 function dec2alpha($valor,$toupper="true"){
32701 // returns a string from A-Z to AA-ZZ to AAA-ZZZ
32702 // OBS: A = 65 ASCII TABLE VALUE
32703 if (($valor < 1) || ($valor > 18278)) return "?"; //supports 'only' up to 18278
32704 $c1 = $c2 = $c3 = '';
32705 if ($valor > 702) // 3 letters (up to 18278)
32706 {
32707 $c1 = 65 + floor(($valor-703)/676);
32708 $c2 = 65 + floor((($valor-703)%676)/26);
32709 $c3 = 65 + floor((($valor-703)%676)%26);
32710 }
32711 elseif ($valor > 26) // 2 letters (up to 702)
32712 {
32713 $c1 = (64 + (int)(($valor-1) / 26));
32714 $c2 = (64 + (int)($valor % 26));
32715 if ($c2 == 64) $c2 += 26;
32716 }
32717 else // 1 letter (up to 26)
32718 {
32719 $c1 = (64 + $valor);
32720 }
32721 $alpha = chr($c1);
32722 if ($c2 != '') $alpha .= chr($c2);
32723 if ($c3 != '') $alpha .= chr($c3);
32724 if (!$toupper) $alpha = strtolower($alpha);
32725 return $alpha;
32726 }
32727
32728
32729 function dec2roman($valor,$toupper=true){
32730 //returns a string as a roman numeral
32731 $r1=$r2=$r3=$r4='';
32732 if (($valor >= 5000) || ($valor < 1)) return "?"; //supports 'only' up to 4999
32733 $aux = (int)($valor/1000);
32734 if ($aux!==0)
32735 {
32736 $valor %= 1000;
32737 while($aux!==0)
32738 {
32739 $r1 .= "M";
32740 $aux--;
32741 }
32742 }
32743 $aux = (int)($valor/100);
32744 if ($aux!==0)
32745 {
32746 $valor %= 100;
32747 switch($aux){
32748 case 3: $r2="C";
32749 case 2: $r2.="C";
32750 case 1: $r2.="C"; break;
32751 case 9: $r2="CM"; break;
32752 case 8: $r2="C";
32753 case 7: $r2.="C";
32754 case 6: $r2.="C";
32755 case 5: $r2="D".$r2; break;
32756 case 4: $r2="CD"; break;
32757 default: break;
32758 }
32759 }
32760 $aux = (int)($valor/10);
32761 if ($aux!==0)
32762 {
32763 $valor %= 10;
32764 switch($aux){
32765 case 3: $r3="X";
32766 case 2: $r3.="X";
32767 case 1: $r3.="X"; break;
32768 case 9: $r3="XC"; break;
32769 case 8: $r3="X";
32770 case 7: $r3.="X";
32771 case 6: $r3.="X";
32772 case 5: $r3="L".$r3; break;
32773 case 4: $r3="XL"; break;
32774 default: break;
32775 }
32776 }
32777 switch($valor){
32778 case 3: $r4="I";
32779 case 2: $r4.="I";
32780 case 1: $r4.="I"; break;
32781 case 9: $r4="IX"; break;
32782 case 8: $r4="I";
32783 case 7: $r4.="I";
32784 case 6: $r4.="I";
32785 case 5: $r4="V".$r4; break;
32786 case 4: $r4="IV"; break;
32787 default: break;
32788 }
32789 $roman = $r1.$r2.$r3.$r4;
32790 if (!$toupper) $roman = strtolower($roman);
32791 return $roman;
32792 }
32793 /*-- END LISTS --*/
32794
32795
32796 //===========================
32797 /*-- IMPORTS --*/
32798 function SetImportUse() {
32799 $this->enableImports = true;
32800 ini_set('auto_detect_line_endings',1);
32801 require_once(_MPDF_PATH."mpdfi/pdf_context.php");
32802 require_once(_MPDF_PATH."mpdfi/pdf_parser.php");
32803 require_once(_MPDF_PATH."mpdfi/fpdi_pdf_parser.php");
32804 }
32805
32806 // from mPDFI
32807 function hex2str($hex) {
32808 return pack("H*", str_replace(array("\r","\n"," "),"", $hex));
32809 }
32810
32811 function str2hex($str) {
32812 return current(unpack("H*",$str));
32813 }
32814
32815
32816 function pdf_write_value(&$value) {
32817 switch ($value[0]) {
32818 case PDF_TYPE_NUMERIC :
32819 case PDF_TYPE_TOKEN :
32820 // A numeric value or a token.
32821 // Simply output them
32822 $this->_out($value[1]." ", false);
32823 break;
32824
32825 case PDF_TYPE_ARRAY :
32826 // An array. Output the proper
32827 // structure and move on.
32828 $this->_out("[",false);
32829 for ($i = 0; $i < count($value[1]); $i++) {
32830 $this->pdf_write_value($value[1][$i]);
32831 }
32832 $this->_out("]");
32833 break;
32834
32835 case PDF_TYPE_DICTIONARY :
32836 // A dictionary.
32837 $this->_out("<<",false);
32838 reset ($value[1]);
32839 while (list($k, $v) = each($value[1])) {
32840 $this->_out($k . " ",false);
32841 $this->pdf_write_value($v);
32842 }
32843 $this->_out(">>");
32844 break;
32845
32846 case PDF_TYPE_OBJREF :
32847 // An indirect object reference
32848 // Fill the object stack if needed
32849 $cpfn =& $this->current_parser->filename;
32850 if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) {
32851 $this->_newobj(false,true);
32852 $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
32853 $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
32854 }
32855 $objid = $this->_don_obj_stack[$cpfn][$value[1]][0];
32856 $this->_out("{$objid} 0 R"); //{$value[2]}
32857 break;
32858
32859 case PDF_TYPE_STRING :
32860 if ($this->encrypted) {
32861 $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
32862 $value[1] = $this->_escape($value[1]);
32863 }
32864 // A string.
32865 $this->_out('('.$value[1].')');
32866 break;
32867
32868 case PDF_TYPE_STREAM :
32869 // A stream. First, output the
32870 // stream dictionary, then the
32871 // stream data itself.
32872 $this->pdf_write_value($value[1]);
32873 if ($this->encrypted) {
32874 $value[2][1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[2][1]);
32875 }
32876 $this->_out("stream");
32877 $this->_out($value[2][1]);
32878 $this->_out("endstream");
32879 break;
32880
32881 case PDF_TYPE_HEX :
32882 if ($this->encrypted) {
32883 $value[1] = $this->hex2str($value[1]);
32884 $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
32885 // remake hexstring of encrypted string
32886 $value[1] = $this->str2hex($value[1]);
32887 }
32888 $this->_out("<".$value[1].">");
32889 break;
32890
32891 case PDF_TYPE_NULL :
32892 // The null object.
32893 $this->_out("null");
32894 break;
32895 }
32896 }
32897
32898 // ========== OVERWRITE SEARCH STRING IN A PDF FILE ================
32899 function OverWrite($file_in, $search, $replacement, $dest="D", $file_out="mpdf" ) {
32900 $pdf = file_get_contents($file_in);
32901
32902 if (!is_array($search)) {
32903 $x = $search;
32904 $search = array($x);
32905 }
32906 if (!is_array($replacement)) {
32907 $x = $replacement;
32908 $replacement = array($x); // mPDF 5.7.4
32909 }
32910
32911 if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
32912 foreach($search AS $k=>$val) {
32913 $search[$k] = $this->UTF8ToUTF16BE($search[$k] , false);
32914 $search[$k] = $this->_escape($search[$k]);
32915 $replacement[$k] = $this->UTF8ToUTF16BE($replacement[$k], false);
32916 $replacement[$k] = $this->_escape($replacement[$k]);
32917 }
32918 }
32919 else {
32920 foreach($replacement AS $k=>$val) {
32921 $replacement[$k] = mb_convert_encoding($replacement[$k],$this->mb_enc,'utf-8');
32922 $replacement[$k] = $this->_escape($replacement[$k]);
32923 }
32924 }
32925
32926 // Get xref into array
32927 $xref = array();
32928 preg_match("/xref\n0 (\d+)\n(.*?)\ntrailer/s",$pdf,$m);
32929 $xref_objid = $m[1];
32930 preg_match_all('/(\d{10}) (\d{5}) (f|n)/',$m[2],$x);
32931 for($i=0; $i<count($x[0]); $i++) {
32932 $xref[] = array(intval($x[1][$i]), $x[2][$i], $x[3][$i]);
32933 }
32934
32935 $changes = array();
32936 preg_match("/<<\s*\/Type\s*\/Pages\s*\/Kids\s*\[(.*?)\]\s*\/Count/s",$pdf,$m);
32937 preg_match_all("/(\d+) 0 R /s",$m[1],$o);
32938 $objlist = $o[1];
32939 foreach($objlist AS $obj) {
32940 if ($this->compress) {
32941 preg_match("/".($obj+1)." 0 obj\n<<\s*\/Filter\s*\/FlateDecode\s*\/Length (\d+)>>\nstream\n(.*?)\nendstream\n/s",$pdf,$m);
32942 }
32943 else {
32944 preg_match("/".($obj+1)." 0 obj\n<<\s*\/Length (\d+)>>\nstream\n(.*?)\nendstream\n/s",$pdf,$m);
32945 }
32946 $s = $m[2];
32947 if (!$s) { continue; }
32948 $oldlen = $m[1];
32949 if ($this->encrypted) {
32950 $s = $this->_RC4($this->_objectkey($obj+1), $s);
32951 }
32952 if ($this->compress) {
32953 $s = gzuncompress($s);
32954 }
32955 foreach($search AS $k=>$val) {
32956 $s = str_replace($search[$k],$replacement[$k],$s);
32957 }
32958 if ($this->compress) {
32959 $s = gzcompress($s);
32960 }
32961 if ($this->encrypted) {
32962 $s = $this->_RC4($this->_objectkey($obj+1), $s);
32963 }
32964 $newlen = strlen($s);
32965 $changes[($xref[$obj+1][0])] = ($newlen - $oldlen) + (strlen($newlen) - strlen($oldlen ));
32966 if ($this->compress) {
32967 $newstr = ($obj+1) . " 0 obj\n<</Filter /FlateDecode /Length ".$newlen.">>\nstream\n".$s."\nendstream\n";
32968 }
32969 else {
32970 $newstr = ($obj+1) . " 0 obj\n<</Length ".$newlen.">>\nstream\n".$s."\nendstream\n";
32971 }
32972 $pdf = str_replace($m[0],$newstr,$pdf);
32973 }
32974
32975 // Update xref in PDF
32976 krsort($changes);
32977 $newxref = "xref\n0 ".$xref_objid."\n";
32978 foreach($xref AS $v) {
32979 foreach($changes AS $ck => $cv) {
32980 if ($v[0] > $ck) { $v[0] += $cv; }
32981 }
32982 $newxref .= sprintf('%010d',$v[0]) . ' ' . $v[1] . ' ' .$v[2] . " \n";
32983 }
32984 $newxref .= "trailer";
32985 $pdf = preg_replace("/xref\n0 \d+\n.*?\ntrailer/s",$newxref,$pdf);
32986
32987 // Update startxref in PDF
32988 preg_match("/startxref\n(\d+)\n%%EOF/s", $pdf, $m);
32989 $startxref = $m[1];
32990 $startxref += array_sum($changes);
32991 $pdf = preg_replace("/startxref\n(\d+)\n%%EOF/s","startxref\n".$startxref."\n%%EOF",$pdf);
32992
32993 // OUTPUT
32994 switch($dest) {
32995 case 'I':
32996 //Send to standard output
32997 if(isset($_SERVER['SERVER_NAME']))
32998 {
32999 //We send to a browser
33000 Header('Content-Type: application/pdf');
33001 Header('Content-Length: '.strlen($pdf));
33002 Header('Content-disposition: inline; filename='.$file_out);
33003 }
33004 echo $pdf;
33005 break;
33006 case 'F':
33007 //Save to local file
33008 if (!$file_out) { $file_out = 'mpdf.pdf'; }
33009 $f=fopen($file_out,'wb');
33010 if(!$f) die('Unable to create output file: '.$file_out);
33011 fwrite($f,$pdf,strlen($pdf));
33012 fclose($f);
33013 break;
33014 case 'S':
33015 //Return as a string
33016 return $pdf;
33017 case 'D':
33018 default:
33019 //Download file
33020 if(isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'],'MSIE'))
33021 Header('Content-Type: application/force-download');
33022 else
33023 Header('Content-Type: application/octet-stream');
33024 Header('Content-Length: '.strlen($pdf));
33025 Header('Content-disposition: attachment; filename='.$file_out);
33026 echo $pdf;
33027 break;
33028 }
33029 }
33030
33031
33032 function GetTemplateSize($tplidx, $_w=0, $_h=0) {
33033 if (!$this->tpls[$tplidx])
33034 return false;
33035 $w = $this->tpls[$tplidx]['box']['w'];
33036 $h = $this->tpls[$tplidx]['box']['h'];
33037 if ($_w == 0 and $_h == 0) {
33038 $_w = $w;
33039 $_h = $h;
33040 }
33041 if($_w==0)
33042 $_w=$_h*$w/$h;
33043 if($_h==0)
33044 $_h=$_w*$h/$w;
33045 return array("w" => $_w, "h" => $_h);
33046 }
33047
33048 // Thumbnails
33049 function Thumbnail($file, $npr=3, $spacing=10) { //$npr = number per row
33050 $w = (($this->pgwidth + $spacing)/$npr) - $spacing;
33051 $oldlinewidth = $this->LineWidth;
33052 $this->SetLineWidth(0.02);
33053 $this->SetDColor($this->ConvertColor(0));
33054 $h = 0;
33055 $maxh = 0;
33056 $x = $_x = $this->lMargin;
33057 $_y = $this->tMargin;
33058 if ($this->y==0) { $y = $_y; } else { $y = $this->y; }
33059 $pagecount = $this->SetSourceFile($file);
33060 for ($n = 1; $n <= $pagecount; $n++) {
33061 $tplidx = $this->ImportPage($n);
33062 $size = $this->useTemplate($tplidx, $x, $y, $w);
33063 $this->Rect($x, $y, $size['w'], $size['h']);
33064 $h = max($h, $size['h']);
33065 $maxh = max($h, $maxh);
33066 if ($n % $npr == 0) {
33067 if (($y + $h + $spacing + $maxh)>$this->PageBreakTrigger && $n != $pagecount) {
33068 $this->AddPage();
33069 $x = $_x;
33070 $y = $_y;
33071 }
33072 else {
33073 $y += $h+$spacing ;
33074 $x = $_x;
33075 $h = 0;
33076 }
33077 }
33078 else {
33079 $x += $w+$spacing ;
33080 }
33081 }
33082 $this->SetLineWidth($oldlinewidth);
33083 }
33084
33085 function SetSourceFile($filename) {
33086 $this->current_filename = $filename;
33087 $fn =& $this->current_filename;
33088 if (!isset($this->parsers[$fn]))
33089 // $this->parsers[$fn] =& new fpdi_pdf_parser($fn,$this);
33090 $this->parsers[$fn] = new fpdi_pdf_parser($fn,$this);
33091 if (!$this->parsers[$fn]->success) {
33092 $this->Error($this->parsers[$fn]->errormsg); // Delete this line to return false on fail
33093 return false;
33094 }
33095 $this->current_parser =& $this->parsers[$fn];
33096 return $this->parsers[$fn]->getPageCount();
33097 }
33098 function ImportPage($pageno=1, $crop_x=null, $crop_y=null, $crop_w=0, $crop_h=0, $boxName='/CropBox') {
33099 $fn =& $this->current_filename;
33100 $parser =& $this->parsers[$fn];
33101 $parser->setPageno($pageno);
33102
33103 $this->tpl++;
33104 $this->tpls[$this->tpl] = array();
33105 $tpl =& $this->tpls[$this->tpl];
33106 $tpl['parser'] =& $parser;
33107 $tpl['resources'] = $parser->getPageResources();
33108 $tpl['buffer'] = $parser->getContent();
33109 if (!in_array($boxName, $parser->availableBoxes))
33110 return $this->Error(sprintf("Unknown box: %s", $boxName));
33111 $pageboxes = $parser->getPageBoxes($pageno);
33112 /**
33113 * MediaBox
33114 * CropBox: Default -> MediaBox
33115 * BleedBox: Default -> CropBox
33116 * TrimBox: Default -> CropBox
33117 * ArtBox: Default -> CropBox
33118 */
33119 if (!isset($pageboxes[$boxName]) && ($boxName == "/BleedBox" || $boxName == "/TrimBox" || $boxName == "/ArtBox"))
33120 $boxName = "/CropBox";
33121 if (!isset($pageboxes[$boxName]) && $boxName == "/CropBox")
33122 $boxName = "/MediaBox";
33123 if (!isset($pageboxes[$boxName]))
33124 return false;
33125 $box = $pageboxes[$boxName];
33126
33127 $tpl['box'] = $box;
33128 // To build an array that can be used by useTemplate()
33129 $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl],$box);
33130 // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects()
33131 $tpl['x'] = 0;
33132 $tpl['y'] = 0;
33133 $tpl['w'] = $tpl['box']['w'] ;
33134 $tpl['h'] = $tpl['box']['h'] ;
33135 if ($crop_w) { $tpl['box']['w'] = $crop_w; }
33136 if ($crop_h) { $tpl['box']['h'] = $crop_h; }
33137 if (isset($crop_x)) { $tpl['box']['x'] = $crop_x; }
33138 if (isset($crop_y)) {$tpl['box']['y'] = $tpl['h'] - $crop_y - $crop_h ; }
33139
33140 $page =& $parser->pages[$parser->pageno];
33141 // fix for rotated pages
33142 $rotation = $parser->getPageRotation($pageno);
33143
33144 if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0 && $tpl['box']['w'] == $tpl['w']) {
33145 $steps = $angle / 90;
33146
33147 $_w = $tpl['w'];
33148 $_h = $tpl['h'];
33149 $tpl['w'] = $steps % 2 == 0 ? $_w : $_h;
33150 $tpl['h'] = $steps % 2 == 0 ? $_h : $_w;
33151 if ($steps % 2 != 0) {
33152 $x = $y = ($steps == 1 || $steps == -3) ? $tpl['h'] : $tpl['w'];
33153 } else {
33154 $x = $tpl['w'];
33155 $y = $tpl['h'];
33156 }
33157 $cx=($x/2+$tpl['box']['x'])*_MPDFK;
33158 $cy=($y/2+$tpl['box']['y'])*_MPDFK;
33159 $angle*=-1;
33160 $angle*=M_PI/180;
33161 $c=cos($angle);
33162 $s=sin($angle);
33163 $tpl['box']['w'] = $tpl['w'] ;
33164 $tpl['box']['h'] = $tpl['h'] ;
33165 $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']);
33166 }
33167 return $this->tpl;
33168 }
33169 function UseTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) {
33170 if (!isset($this->tpls[$tplidx]))
33171 $this->Error("Template does not exist!");
33172 if($this->state==0) { $this->AddPage(); }
33173 $out = 'q 0 J 1 w 0 j 0 G'."\n"; // reset standard values
33174 $x = $this->tpls[$tplidx]['x'];
33175 $y = $this->tpls[$tplidx]['y'];
33176 $w = $this->tpls[$tplidx]['w'];
33177 $h = $this->tpls[$tplidx]['h'];
33178 if ($_x == null) { $_x = $x; }
33179 if ($_y == null) { $_y = $y; }
33180 if ($_x === -1) { $_x = $this->x; }
33181 if ($_y === -1) { $_y = $this->y; }
33182
33183 $wh = $this->getTemplateSize($tplidx,$_w,$_h);
33184 $_w = $wh['w'];
33185 $_h = $wh['h'];
33186 $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";
33187 $out .= $this->tplprefix.$tplidx." Do Q\n";
33188
33189 $s = array("w" => $_w, "h" => $_h);
33190 $out .= "Q\n";
33191 $this->pages[$this->page] = $out . $this->pages[$this->page];
33192 return $s;
33193 }
33194 function SetPageTemplate($tplidx='') {
33195 if (!isset($this->tpls[$tplidx])) {
33196 $this->pageTemplate = '';
33197 return false;
33198 }
33199 $this->pageTemplate = $tplidx;
33200 }
33201 function SetDocTemplate($file='', $continue=0) {
33202 $this->docTemplate = $file;
33203 $this->docTemplateContinue = $continue;
33204 }
33205 /*-- END IMPORTS --*/
33206
33207
33208 /* ---------------------------------------------- */
33209 /* ---------------------------------------------- */
33210 /* ---------------------------------------------- */
33211 /* ---------------------------------------------- */
33212 /* ---------------------------------------------- */
33213
33214 // JAVASCRIPT
33215 function _set_object_javascript ($string) {
33216 $this->_newobj();
33217 $this->_out('<<');
33218 $this->_out('/S /JavaScript ');
33219 $this->_out('/JS '.$this->_textstring($string));
33220 $this->_out('>>');
33221 $this->_out('endobj');
33222 }
33223
33224 function SetJS($script) {
33225 $this->js = $script;
33226 }
33227
33228
33229
33230
33231 }//end of Class
33232
33233
33234
33235
33236 ?>